MYNEWT-653 Use runtimeco gatt fork.

Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/a1553084
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/a1553084
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/a1553084

Branch: refs/heads/mynewt_1_0_0
Commit: a1553084c899135c7764b5307f9252b4ec42ca01
Parents: 351d90a
Author: Christopher Collins <[email protected]>
Authored: Thu Mar 2 19:12:27 2017 -0800
Committer: Marko Kiiskila <[email protected]>
Committed: Mon Mar 6 13:38:07 2017 -0800

----------------------------------------------------------------------
 newtmgr/Godeps/Godeps.json                      |  32 +-
 .../vendor/github.com/runtimeco/gatt/.gitignore |   3 +
 .../vendor/github.com/runtimeco/gatt/LICENSE.md |  27 +
 newtmgr/vendor/github.com/runtimeco/gatt/adv.go | 234 +++++
 .../vendor/github.com/runtimeco/gatt/attr.go    | 160 +++
 .../vendor/github.com/runtimeco/gatt/central.go | 152 +++
 .../github.com/runtimeco/gatt/central_darwin.go |  70 ++
 .../github.com/runtimeco/gatt/central_linux.go  | 446 +++++++++
 .../vendor/github.com/runtimeco/gatt/common.go  | 399 ++++++++
 .../vendor/github.com/runtimeco/gatt/const.go   | 153 +++
 .../vendor/github.com/runtimeco/gatt/device.go  | 161 +++
 .../github.com/runtimeco/gatt/device_darwin.go  | 513 ++++++++++
 .../github.com/runtimeco/gatt/device_linux.go   | 240 +++++
 newtmgr/vendor/github.com/runtimeco/gatt/doc.go |  88 ++
 .../github.com/runtimeco/gatt/known_uuid.go     | 122 +++
 .../runtimeco/gatt/l2cap_writer_linux.go        | 156 +++
 .../github.com/runtimeco/gatt/linux/cmd/cmd.go  | 995 +++++++++++++++++++
 .../github.com/runtimeco/gatt/linux/const.go    |  21 +
 .../github.com/runtimeco/gatt/linux/device.go   | 109 ++
 .../github.com/runtimeco/gatt/linux/devices.go  |  58 ++
 .../github.com/runtimeco/gatt/linux/doc.go      |   5 +
 .../github.com/runtimeco/gatt/linux/evt/evt.go  | 382 +++++++
 .../runtimeco/gatt/linux/gioctl/LICENSE.md      |  22 +
 .../runtimeco/gatt/linux/gioctl/README.md       |  12 +
 .../runtimeco/gatt/linux/gioctl/ioctl.go        |  57 ++
 .../github.com/runtimeco/gatt/linux/hci.go      | 400 ++++++++
 .../github.com/runtimeco/gatt/linux/l2cap.go    | 174 ++++
 .../runtimeco/gatt/linux/socket/asm.s           |   8 +
 .../runtimeco/gatt/linux/socket/asm_linux_386.s |  33 +
 .../runtimeco/gatt/linux/socket/socket.go       | 121 +++
 .../gatt/linux/socket/socket_common.go          |  24 +
 .../gatt/linux/socket/socket_darwin.go          |   6 +
 .../runtimeco/gatt/linux/socket/socket_linux.go |   7 +
 .../gatt/linux/socket/socket_linux_386.go       |  31 +
 .../runtimeco/gatt/linux/util/util.go           |  16 +
 .../github.com/runtimeco/gatt/option_darwin.go  |  15 +
 .../github.com/runtimeco/gatt/option_linux.go   |  87 ++
 .../github.com/runtimeco/gatt/peripheral.go     | 102 ++
 .../runtimeco/gatt/peripheral_darwin.go         | 277 ++++++
 .../runtimeco/gatt/peripheral_linux.go          | 448 +++++++++
 .../vendor/github.com/runtimeco/gatt/readme.md  | 115 +++
 .../vendor/github.com/runtimeco/gatt/uuid.go    |  86 ++
 .../github.com/runtimeco/gatt/xpc/LICENSE       |  21 +
 .../vendor/github.com/runtimeco/gatt/xpc/doc.go |   8 +
 .../github.com/runtimeco/gatt/xpc/xpc_darwin.go | 350 +++++++
 .../runtimeco/gatt/xpc/xpc_wrapper_darwin.c     |  85 ++
 .../runtimeco/gatt/xpc/xpc_wrapper_darwin.h     |  32 +
 .../github.com/runtimeinc/gatt/.gitignore       |   3 -
 .../github.com/runtimeinc/gatt/LICENSE.md       |  27 -
 .../vendor/github.com/runtimeinc/gatt/adv.go    | 234 -----
 .../vendor/github.com/runtimeinc/gatt/attr.go   | 160 ---
 .../github.com/runtimeinc/gatt/central.go       | 152 ---
 .../runtimeinc/gatt/central_darwin.go           |  70 --
 .../github.com/runtimeinc/gatt/central_linux.go | 446 ---------
 .../vendor/github.com/runtimeinc/gatt/common.go | 399 --------
 .../vendor/github.com/runtimeinc/gatt/const.go  | 153 ---
 .../vendor/github.com/runtimeinc/gatt/device.go | 161 ---
 .../github.com/runtimeinc/gatt/device_darwin.go | 513 ----------
 .../github.com/runtimeinc/gatt/device_linux.go  | 240 -----
 .../vendor/github.com/runtimeinc/gatt/doc.go    |  88 --
 .../github.com/runtimeinc/gatt/known_uuid.go    | 122 ---
 .../runtimeinc/gatt/l2cap_writer_linux.go       | 156 ---
 .../github.com/runtimeinc/gatt/linux/cmd/cmd.go | 995 -------------------
 .../github.com/runtimeinc/gatt/linux/const.go   |  21 -
 .../github.com/runtimeinc/gatt/linux/device.go  | 109 --
 .../github.com/runtimeinc/gatt/linux/devices.go |  58 --
 .../github.com/runtimeinc/gatt/linux/doc.go     |   5 -
 .../github.com/runtimeinc/gatt/linux/evt/evt.go | 382 -------
 .../runtimeinc/gatt/linux/gioctl/LICENSE.md     |  22 -
 .../runtimeinc/gatt/linux/gioctl/README.md      |  12 -
 .../runtimeinc/gatt/linux/gioctl/ioctl.go       |  57 --
 .../github.com/runtimeinc/gatt/linux/hci.go     | 400 --------
 .../github.com/runtimeinc/gatt/linux/l2cap.go   | 174 ----
 .../runtimeinc/gatt/linux/socket/asm.s          |   8 -
 .../gatt/linux/socket/asm_linux_386.s           |  33 -
 .../runtimeinc/gatt/linux/socket/socket.go      | 121 ---
 .../gatt/linux/socket/socket_common.go          |  24 -
 .../gatt/linux/socket/socket_darwin.go          |   6 -
 .../gatt/linux/socket/socket_linux.go           |   7 -
 .../gatt/linux/socket/socket_linux_386.go       |  31 -
 .../runtimeinc/gatt/linux/util/util.go          |  16 -
 .../github.com/runtimeinc/gatt/option_darwin.go |  15 -
 .../github.com/runtimeinc/gatt/option_linux.go  |  87 --
 .../github.com/runtimeinc/gatt/peripheral.go    | 102 --
 .../runtimeinc/gatt/peripheral_darwin.go        | 277 ------
 .../runtimeinc/gatt/peripheral_linux.go         | 448 ---------
 .../vendor/github.com/runtimeinc/gatt/readme.md | 115 ---
 .../vendor/github.com/runtimeinc/gatt/uuid.go   |  86 --
 .../github.com/runtimeinc/gatt/xpc/LICENSE      |  21 -
 .../github.com/runtimeinc/gatt/xpc/doc.go       |   8 -
 .../runtimeinc/gatt/xpc/xpc_darwin.go           | 350 -------
 .../runtimeinc/gatt/xpc/xpc_wrapper_darwin.c    |  85 --
 .../runtimeinc/gatt/xpc/xpc_wrapper_darwin.h    |  32 -
 93 files changed, 7061 insertions(+), 7033 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/Godeps/Godeps.json
----------------------------------------------------------------------
diff --git a/newtmgr/Godeps/Godeps.json b/newtmgr/Godeps/Godeps.json
index b2571e8..b486ebe 100644
--- a/newtmgr/Godeps/Godeps.json
+++ b/newtmgr/Godeps/Godeps.json
@@ -38,8 +38,8 @@
                        "Rev": "f3009df150dadf309fdee4a54ed65c124afad715"
                },
                {
-                       "ImportPath": "github.com/runtimeinc/gatt",
-                       "Rev": "a8b4c64987af1491ef629e5ec45d3fc47df29eb9"
+                       "ImportPath": "github.com/runtimeco/gatt",
+                       "Rev": "ceaca1e3d4b698ce4f610b8c71ebc5cde9ad40dd"
                },
                {
                        "ImportPath": "github.com/runtimeinc/gatt/linux",
@@ -116,6 +116,34 @@
                        "ImportPath": "mynewt.apache.org/newt/yaml",
                        "Comment": "pre_sterly_refactor-137-gfcecea4",
                        "Rev": "fcecea4b13ab467168e936a51ef01695833644d8"
+               },
+               {
+                       "ImportPath": "github.com/runtimeco/gatt/linux",
+                       "Rev": "ceaca1e3d4b698ce4f610b8c71ebc5cde9ad40dd"
+               },
+               {
+                       "ImportPath": "github.com/runtimeco/gatt/linux/cmd",
+                       "Rev": "ceaca1e3d4b698ce4f610b8c71ebc5cde9ad40dd"
+               },
+               {
+                       "ImportPath": "github.com/runtimeco/gatt/xpc",
+                       "Rev": "ceaca1e3d4b698ce4f610b8c71ebc5cde9ad40dd"
+               },
+               {
+                       "ImportPath": "github.com/runtimeco/gatt/linux/evt",
+                       "Rev": "ceaca1e3d4b698ce4f610b8c71ebc5cde9ad40dd"
+               },
+               {
+                       "ImportPath": "github.com/runtimeco/gatt/linux/gioctl",
+                       "Rev": "ceaca1e3d4b698ce4f610b8c71ebc5cde9ad40dd"
+               },
+               {
+                       "ImportPath": "github.com/runtimeco/gatt/linux/socket",
+                       "Rev": "ceaca1e3d4b698ce4f610b8c71ebc5cde9ad40dd"
+               },
+               {
+                       "ImportPath": "github.com/runtimeco/gatt/linux/util",
+                       "Rev": "ceaca1e3d4b698ce4f610b8c71ebc5cde9ad40dd"
                }
        ]
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/.gitignore
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/.gitignore 
b/newtmgr/vendor/github.com/runtimeco/gatt/.gitignore
new file mode 100644
index 0000000..7ab0687
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/.gitignore
@@ -0,0 +1,3 @@
+c.out
+c/*-ble
+sample

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/LICENSE.md
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/LICENSE.md 
b/newtmgr/vendor/github.com/runtimeco/gatt/LICENSE.md
new file mode 100644
index 0000000..51c07a6
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/LICENSE.md
@@ -0,0 +1,27 @@
+Copyright (c) 2014 PayPal Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of PayPal Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/adv.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/adv.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/adv.go
new file mode 100644
index 0000000..3b8a747
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/adv.go
@@ -0,0 +1,234 @@
+package gatt
+
+import (
+       "errors"
+       "log"
+)
+
+// MaxEIRPacketLength is the maximum allowed AdvertisingPacket
+// and ScanResponsePacket length.
+const MaxEIRPacketLength = 31
+
+// ErrEIRPacketTooLong is the error returned when an AdvertisingPacket
+// or ScanResponsePacket is too long.
+var ErrEIRPacketTooLong = errors.New("max packet length is 31")
+
+// Advertising data field types
+const (
+       typeFlags             = 0x01 // Flags
+       typeSomeUUID16        = 0x02 // Incomplete List of 16-bit Service Class 
UUIDs
+       typeAllUUID16         = 0x03 // Complete List of 16-bit Service Class 
UUIDs
+       typeSomeUUID32        = 0x04 // Incomplete List of 32-bit Service Class 
UUIDs
+       typeAllUUID32         = 0x05 // Complete List of 32-bit Service Class 
UUIDs
+       typeSomeUUID128       = 0x06 // Incomplete List of 128-bit Service 
Class UUIDs
+       typeAllUUID128        = 0x07 // Complete List of 128-bit Service Class 
UUIDs
+       typeShortName         = 0x08 // Shortened Local Name
+       typeCompleteName      = 0x09 // Complete Local Name
+       typeTxPower           = 0x0A // Tx Power Level
+       typeClassOfDevice     = 0x0D // Class of Device
+       typeSimplePairingC192 = 0x0E // Simple Pairing Hash C-192
+       typeSimplePairingR192 = 0x0F // Simple Pairing Randomizer R-192
+       typeSecManagerTK      = 0x10 // Security Manager TK Value
+       typeSecManagerOOB     = 0x11 // Security Manager Out of Band Flags
+       typeSlaveConnInt      = 0x12 // Slave Connection Interval Range
+       typeServiceSol16      = 0x14 // List of 16-bit Service Solicitation 
UUIDs
+       typeServiceSol128     = 0x15 // List of 128-bit Service Solicitation 
UUIDs
+       typeServiceData16     = 0x16 // Service Data - 16-bit UUID
+       typePubTargetAddr     = 0x17 // Public Target Address
+       typeRandTargetAddr    = 0x18 // Random Target Address
+       typeAppearance        = 0x19 // Appearance
+       typeAdvInterval       = 0x1A // Advertising Interval
+       typeLEDeviceAddr      = 0x1B // LE Bluetooth Device Address
+       typeLERole            = 0x1C // LE Role
+       typeServiceSol32      = 0x1F // List of 32-bit Service Solicitation 
UUIDs
+       typeServiceData32     = 0x20 // Service Data - 32-bit UUID
+       typeServiceData128    = 0x21 // Service Data - 128-bit UUID
+       typeLESecConfirm      = 0x22 // LE Secure Connections Confirmation Value
+       typeLESecRandom       = 0x23 // LE Secure Connections Random Value
+       typeManufacturerData  = 0xFF // Manufacturer Specific Data
+)
+
+// Advertising type flags
+const (
+       flagLimitedDiscoverable = 0x01 // LE Limited Discoverable Mode
+       flagGeneralDiscoverable = 0x02 // LE General Discoverable Mode
+       flagLEOnly              = 0x04 // BR/EDR Not Supported. Bit 37 of LMP 
Feature Mask Definitions (Page 0)
+       flagBothController      = 0x08 // Simultaneous LE and BR/EDR to Same 
Device Capable (Controller).
+       flagBothHost            = 0x10 // Simultaneous LE and BR/EDR to Same 
Device Capable (Host).
+)
+
+// FIXME: check the unmarshalling of this data structure.
+type ServiceData struct {
+       UUID UUID
+       Data []byte
+}
+
+// This is borrowed from core bluetooth.
+// Embedded/Linux folks might be interested in more details.
+type Advertisement struct {
+       LocalName        string
+       ManufacturerData []byte
+       ServiceData      []ServiceData
+       Services         []UUID
+       OverflowService  []UUID
+       TxPowerLevel     int
+       Connectable      bool
+       SolicitedService []UUID
+       AddressType uint8
+       Address     [6]byte
+}
+
+// This is only used in Linux port.
+func (a *Advertisement) unmarshall(b []byte) error {
+
+       // Utility function for creating a list of uuids.
+       uuidList := func(u []UUID, d []byte, w int) []UUID {
+               for len(d) > 0 {
+                       u = append(u, UUID{d[:w]})
+                       d = d[w:]
+               }
+               return u
+       }
+
+       for len(b) > 0 {
+               if len(b) < 2 {
+                       return errors.New("invalid advertise data")
+               }
+               l, t := b[0], b[1]
+               if len(b) < int(1+l) {
+                       return errors.New("invalid advertise data")
+               }
+               d := b[2 : 1+l]
+               switch t {
+               case typeFlags:
+                       // TODO: should we do anything about the 
discoverability here?
+               case typeSomeUUID16:
+                       a.Services = uuidList(a.Services, d, 2)
+               case typeAllUUID16:
+                       a.Services = uuidList(a.Services, d, 2)
+               case typeSomeUUID32:
+                       a.Services = uuidList(a.Services, d, 4)
+               case typeAllUUID32:
+                       a.Services = uuidList(a.Services, d, 4)
+               case typeSomeUUID128:
+                       a.Services = uuidList(a.Services, d, 16)
+               case typeAllUUID128:
+                       a.Services = uuidList(a.Services, d, 16)
+               case typeShortName:
+                       a.LocalName = string(d)
+               case typeCompleteName:
+                       a.LocalName = string(d)
+               case typeTxPower:
+                       a.TxPowerLevel = int(d[0])
+               case typeServiceSol16:
+                       a.SolicitedService = uuidList(a.SolicitedService, d, 2)
+               case typeServiceSol128:
+                       a.SolicitedService = uuidList(a.SolicitedService, d, 16)
+               case typeServiceSol32:
+                       a.SolicitedService = uuidList(a.SolicitedService, d, 4)
+               case typeManufacturerData:
+                       a.ManufacturerData = make([]byte, len(d))
+                       copy(a.ManufacturerData, d)
+               // case typeServiceData16,
+               // case typeServiceData32,
+               // case typeServiceData128:
+               default:
+                       log.Printf("DATA: [ % X ]", d)
+               }
+               b = b[1+l:]
+       }
+       return nil
+}
+
+// AdvPacket is an utility to help crafting advertisment or scan response data.
+type AdvPacket struct {
+       b []byte
+}
+
+// Bytes returns an 31-byte array, which contains up to 31 bytes of the packet.
+func (a *AdvPacket) Bytes() [31]byte {
+       b := [31]byte{}
+       copy(b[:], a.b)
+       return b
+}
+
+// Len returns the length of the packets with a maximum of 31.
+func (a *AdvPacket) Len() int {
+       if len(a.b) > 31 {
+               return 31
+       }
+       return len(a.b)
+}
+
+// AppendField appends a BLE advertising packet field.
+// TODO: refuse to append field if it'd make the packet too long.
+func (a *AdvPacket) AppendField(typ byte, b []byte) *AdvPacket {
+       // A field consists of len, typ, b.
+       // Len is 1 byte for typ plus len(b).
+       if len(a.b)+2+len(b) > MaxEIRPacketLength {
+               b = b[:MaxEIRPacketLength-len(a.b)-2]
+       }
+       a.b = append(a.b, byte(len(b)+1))
+       a.b = append(a.b, typ)
+       a.b = append(a.b, b...)
+       return a
+}
+
+// AppendFlags appends a flag field to the packet.
+func (a *AdvPacket) AppendFlags(f byte) *AdvPacket {
+       return a.AppendField(typeFlags, []byte{f})
+}
+
+// AppendFlags appends a name field to the packet.
+// If the name fits in the space, it will be append as a complete name field, 
otherwise a short name field.
+func (a *AdvPacket) AppendName(n string) *AdvPacket {
+       typ := byte(typeCompleteName)
+       if len(a.b)+2+len(n) > MaxEIRPacketLength {
+               typ = byte(typeShortName)
+       }
+       return a.AppendField(typ, []byte(n))
+}
+
+// AppendManufacturerData appends a manufacturer data field to the packet.
+func (a *AdvPacket) AppendManufacturerData(id uint16, b []byte) *AdvPacket {
+       d := append([]byte{uint8(id), uint8(id >> 8)}, b...)
+       return a.AppendField(typeManufacturerData, d)
+}
+
+// AppendUUIDFit appends a BLE advertised service UUID
+// packet field if it fits in the packet, and reports whether the UUID fit.
+func (a *AdvPacket) AppendUUIDFit(uu []UUID) bool {
+       // Iterate all UUIDs to see if they fit in the packet or not.
+       fit, l := true, len(a.b)
+       for _, u := range uu {
+               if u.Equal(attrGAPUUID) || u.Equal(attrGATTUUID) {
+                       continue
+               }
+               l += 2 + u.Len()
+               if l > MaxEIRPacketLength {
+                       fit = false
+                       break
+               }
+       }
+
+       // Append the UUIDs until they no longer fit.
+       for _, u := range uu {
+               if u.Equal(attrGAPUUID) || u.Equal(attrGATTUUID) {
+                       continue
+               }
+               if len(a.b)+2+u.Len() > MaxEIRPacketLength {
+                       break
+               }
+               switch l = u.Len(); {
+               case l == 2 && fit:
+                       a.AppendField(typeAllUUID16, u.b)
+               case l == 16 && fit:
+                       a.AppendField(typeAllUUID128, u.b)
+               case l == 2 && !fit:
+                       a.AppendField(typeSomeUUID16, u.b)
+               case l == 16 && !fit:
+                       a.AppendField(typeSomeUUID128, u.b)
+               }
+       }
+       return fit
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/attr.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/attr.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/attr.go
new file mode 100644
index 0000000..d1ae09d
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/attr.go
@@ -0,0 +1,160 @@
+package gatt
+
+import "log"
+
+// attr is a BLE attribute. It is not exported;
+// managing attributes is an implementation detail.
+type attr struct {
+       h      uint16   // attribute handle
+       typ    UUID     // attribute type in UUID
+       props  Property // attripute property
+       secure Property // attribute secure (implementation specific usage)
+       value  []byte   // attribute value
+
+       pvt interface{} // point to the corresponsing 
Serveice/Characteristic/Descriptor
+}
+
+// A attrRange is a contiguous range of attributes.
+type attrRange struct {
+       aa   []attr
+       base uint16 // handle for first attr in aa
+}
+
+const (
+       tooSmall = -1
+       tooLarge = -2
+)
+
+// idx returns the index into aa corresponding to attr a.
+// If h is too small, idx returns tooSmall (-1).
+// If h is too large, idx returns tooLarge (-2).
+func (r *attrRange) idx(h int) int {
+       if h < int(r.base) {
+               return tooSmall
+       }
+       if int(h) >= int(r.base)+len(r.aa) {
+               return tooLarge
+       }
+       return h - int(r.base)
+}
+
+// At returns attr a.
+func (r *attrRange) At(h uint16) (a attr, ok bool) {
+       i := r.idx(int(h))
+       if i < 0 {
+               return attr{}, false
+       }
+       return r.aa[i], true
+}
+
+// Subrange returns attributes in range [start, end]; it may
+// return an empty slice. Subrange does not panic for
+// out-of-range start or end.
+func (r *attrRange) Subrange(start, end uint16) []attr {
+       startidx := r.idx(int(start))
+       switch startidx {
+       case tooSmall:
+               startidx = 0
+       case tooLarge:
+               return []attr{}
+       }
+
+       endidx := r.idx(int(end) + 1) // [start, end] includes its upper bound!
+       switch endidx {
+       case tooSmall:
+               return []attr{}
+       case tooLarge:
+               endidx = len(r.aa)
+       }
+       return r.aa[startidx:endidx]
+}
+
+func dumpAttributes(aa []attr) {
+       log.Printf("Generating attribute table:")
+       log.Printf("handle\ttype\tprops\tsecure\tpvt\tvalue")
+       for _, a := range aa {
+               log.Printf("0x%04X\t0x%s\t0x%02X\t0x%02x\t%T\t[ % X ]",
+                       a.h, a.typ, int(a.props), int(a.secure), a.pvt, a.value)
+       }
+}
+
+func generateAttributes(ss []*Service, base uint16) *attrRange {
+       var aa []attr
+       h := base
+       last := len(ss) - 1
+       for i, s := range ss {
+               var a []attr
+               h, a = generateServiceAttributes(s, h, i == last)
+               aa = append(aa, a...)
+       }
+       dumpAttributes(aa)
+       return &attrRange{aa: aa, base: base}
+}
+
+func generateServiceAttributes(s *Service, h uint16, last bool) (uint16, 
[]attr) {
+       s.h = h
+       // endh set later
+       a := attr{
+               h:     h,
+               typ:   attrPrimaryServiceUUID,
+               value: s.uuid.b,
+               props: CharRead,
+               pvt:   s,
+       }
+       aa := []attr{a}
+       h++
+
+       for _, c := range s.Characteristics() {
+               var a []attr
+               h, a = generateCharAttributes(c, h)
+               aa = append(aa, a...)
+       }
+
+       s.endh = h - 1
+       if last {
+               h = 0xFFFF
+               s.endh = h
+       }
+
+       return h, aa
+}
+
+func generateCharAttributes(c *Characteristic, h uint16) (uint16, []attr) {
+       c.h = h
+       c.vh = h + 1
+       ca := attr{
+               h:     c.h,
+               typ:   attrCharacteristicUUID,
+               value: append([]byte{byte(c.props), byte(c.vh), byte((c.vh) >> 
8)}, c.uuid.b...),
+               props: c.props,
+               pvt:   c,
+       }
+       va := attr{
+               h:     c.vh,
+               typ:   c.uuid,
+               value: c.value,
+               props: c.props,
+               pvt:   c,
+       }
+       h += 2
+
+       aa := []attr{ca, va}
+       for _, d := range c.descs {
+               aa = append(aa, generateDescAttributes(d, h))
+               h++
+       }
+
+       return h, aa
+}
+
+func generateDescAttributes(d *Descriptor, h uint16) attr {
+       d.h = h
+       a := attr{
+               h:     h,
+               typ:   d.uuid,
+               value: d.value,
+               props: d.props,
+               pvt:   d,
+       }
+       return a
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/central.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/central.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/central.go
new file mode 100644
index 0000000..55bd2c1
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/central.go
@@ -0,0 +1,152 @@
+package gatt
+
+import (
+       "bytes"
+       "errors"
+       "fmt"
+       "sync"
+)
+
+// Central is the interface that represent a remote central device.
+type Central interface {
+       ID() string   // ID returns platform specific ID of the remote central 
device.
+       Close() error // Close disconnects the connection.
+       MTU() int     // MTU returns the current connection mtu.
+}
+
+type ResponseWriter interface {
+       // Write writes data to return as the characteristic value.
+       Write([]byte) (int, error)
+
+       // SetStatus reports the result of the read operation. See the Status* 
constants.
+       SetStatus(byte)
+}
+
+// responseWriter is the default implementation of ResponseWriter.
+type responseWriter struct {
+       capacity int
+       buf      *bytes.Buffer
+       status   byte
+}
+
+func newResponseWriter(c int) *responseWriter {
+       return &responseWriter{
+               capacity: c,
+               buf:      new(bytes.Buffer),
+               status:   StatusSuccess,
+       }
+}
+
+func (w *responseWriter) Write(b []byte) (int, error) {
+       if avail := w.capacity - w.buf.Len(); avail < len(b) {
+               return 0, fmt.Errorf("requested write %d bytes, %d available", 
len(b), avail)
+       }
+       return w.buf.Write(b)
+}
+
+func (w *responseWriter) SetStatus(status byte) { w.status = status }
+func (w *responseWriter) bytes() []byte         { return w.buf.Bytes() }
+
+// A ReadHandler handles GATT read requests.
+type ReadHandler interface {
+       ServeRead(resp ResponseWriter, req *ReadRequest)
+}
+
+// ReadHandlerFunc is an adapter to allow the use of
+// ordinary functions as ReadHandlers. If f is a function
+// with the appropriate signature, ReadHandlerFunc(f) is a
+// ReadHandler that calls f.
+type ReadHandlerFunc func(resp ResponseWriter, req *ReadRequest)
+
+// ServeRead returns f(r, maxlen, offset).
+func (f ReadHandlerFunc) ServeRead(resp ResponseWriter, req *ReadRequest) {
+       f(resp, req)
+}
+
+// A WriteHandler handles GATT write requests.
+// Write and WriteNR requests are presented identically;
+// the server will ensure that a response is sent if appropriate.
+type WriteHandler interface {
+       ServeWrite(r Request, data []byte) (status byte)
+}
+
+// WriteHandlerFunc is an adapter to allow the use of
+// ordinary functions as WriteHandlers. If f is a function
+// with the appropriate signature, WriteHandlerFunc(f) is a
+// WriteHandler that calls f.
+type WriteHandlerFunc func(r Request, data []byte) byte
+
+// ServeWrite returns f(r, data).
+func (f WriteHandlerFunc) ServeWrite(r Request, data []byte) byte {
+       return f(r, data)
+}
+
+// A NotifyHandler handles GATT notification requests.
+// Notifications can be sent using the provided notifier.
+type NotifyHandler interface {
+       ServeNotify(r Request, n Notifier)
+}
+
+// NotifyHandlerFunc is an adapter to allow the use of
+// ordinary functions as NotifyHandlers. If f is a function
+// with the appropriate signature, NotifyHandlerFunc(f) is a
+// NotifyHandler that calls f.
+type NotifyHandlerFunc func(r Request, n Notifier)
+
+// ServeNotify calls f(r, n).
+func (f NotifyHandlerFunc) ServeNotify(r Request, n Notifier) {
+       f(r, n)
+}
+
+// A Notifier provides a means for a GATT server to send
+// notifications about value changes to a connected device.
+// Notifiers are provided by NotifyHandlers.
+type Notifier interface {
+       // Write sends data to the central.
+       Write(data []byte) (int, error)
+
+       // Done reports whether the central has requested not to
+       // receive any more notifications with this notifier.
+       Done() bool
+
+       // Cap returns the maximum number of bytes that may be sent
+       // in a single notification.
+       Cap() int
+}
+
+type notifier struct {
+       central *central
+       a       *attr
+       maxlen  int
+       donemu  sync.RWMutex
+       done    bool
+}
+
+func newNotifier(c *central, a *attr, maxlen int) *notifier {
+       return &notifier{central: c, a: a, maxlen: maxlen}
+}
+
+func (n *notifier) Write(b []byte) (int, error) {
+       n.donemu.RLock()
+       defer n.donemu.RUnlock()
+       if n.done {
+               return 0, errors.New("central stopped notifications")
+       }
+       return n.central.sendNotification(n.a, b)
+}
+
+func (n *notifier) Cap() int {
+       return n.maxlen
+}
+
+func (n *notifier) Done() bool {
+       n.donemu.RLock()
+       defer n.donemu.RUnlock()
+       return n.done
+}
+
+func (n *notifier) stop() {
+       n.donemu.Lock()
+       n.done = true
+       n.donemu.Unlock()
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/central_darwin.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/central_darwin.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/central_darwin.go
new file mode 100644
index 0000000..47faa2e
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/central_darwin.go
@@ -0,0 +1,70 @@
+package gatt
+
+import (
+       "sync"
+
+       "github.com/runtimeco/gatt/xpc"
+)
+
+type central struct {
+       dev         *device
+       uuid        UUID
+       mtu         int
+       notifiers   map[uint16]*notifier
+       notifiersmu *sync.Mutex
+}
+
+func newCentral(d *device, u UUID) *central {
+       return &central{
+               dev:         d,
+               mtu:         23,
+               uuid:        u,
+               notifiers:   make(map[uint16]*notifier),
+               notifiersmu: &sync.Mutex{},
+       }
+}
+
+func (c *central) ID() string   { return c.uuid.String() }
+func (c *central) Close() error { return nil }
+func (c *central) MTU() int     { return c.mtu }
+
+func (c *central) sendNotification(a *attr, b []byte) (int, error) {
+       data := make([]byte, len(b))
+       copy(data, b) // have to make a copy, why?
+       c.dev.sendCmd(15, xpc.Dict{
+               // "kCBMsgArgUUIDs": [][]byte{reverse(c.uuid.b)}, // connection 
interrupted
+               // "kCBMsgArgUUIDs": [][]byte{c.uuid.b}, // connection 
interrupted
+               // "kCBMsgArgUUIDs": []xpc.UUID{xpc.UUID(reverse(c.uuid.b))},
+               // "kCBMsgArgUUIDs": []xpc.UUID{xpc.UUID(c.uuid.b)},
+               // "kCBMsgArgUUIDs": reverse(c.uuid.b),
+               //
+               // FIXME: Sigh... tried to targeting the central, but couldn't 
get work.
+               // So, broadcast to all subscribed centrals. Either of the 
following works.
+               // "kCBMsgArgUUIDs": []xpc.UUID{},
+               "kCBMsgArgUUIDs":       [][]byte{},
+               "kCBMsgArgAttributeID": a.h,
+               "kCBMsgArgData":        data,
+       })
+       return len(b), nil
+}
+
+func (c *central) startNotify(a *attr, maxlen int) {
+       c.notifiersmu.Lock()
+       defer c.notifiersmu.Unlock()
+       if _, found := c.notifiers[a.h]; found {
+               return
+       }
+       n := newNotifier(c, a, maxlen)
+       c.notifiers[a.h] = n
+       char := a.pvt.(*Characteristic)
+       go char.nhandler.ServeNotify(Request{Central: c}, n)
+}
+
+func (c *central) stopNotify(a *attr) {
+       c.notifiersmu.Lock()
+       defer c.notifiersmu.Unlock()
+       if n, found := c.notifiers[a.h]; found {
+               n.stop()
+               delete(c.notifiers, a.h)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/central_linux.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/central_linux.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/central_linux.go
new file mode 100644
index 0000000..3ae6994
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/central_linux.go
@@ -0,0 +1,446 @@
+package gatt
+
+import (
+       "encoding/binary"
+       "io"
+       "net"
+       "sync"
+)
+
+type security int
+
+const (
+       securityLow = iota
+       securityMed
+       securityHigh
+)
+
+type central struct {
+       attrs       *attrRange
+       mtu         uint16
+       addr        net.HardwareAddr
+       security    security
+       l2conn      io.ReadWriteCloser
+       notifiers   map[uint16]*notifier
+       notifiersmu *sync.Mutex
+}
+
+func newCentral(a *attrRange, addr net.HardwareAddr, l2conn 
io.ReadWriteCloser) *central {
+       return &central{
+               attrs:       a,
+               mtu:         23,
+               addr:        addr,
+               security:    securityLow,
+               l2conn:      l2conn,
+               notifiers:   make(map[uint16]*notifier),
+               notifiersmu: &sync.Mutex{},
+       }
+}
+
+func (c *central) ID() string {
+       return c.addr.String()
+}
+
+func (c *central) Close() error {
+       c.notifiersmu.Lock()
+       defer c.notifiersmu.Unlock()
+       for _, n := range c.notifiers {
+               n.stop()
+       }
+       return c.l2conn.Close()
+}
+
+func (c *central) MTU() int {
+       return int(c.mtu)
+}
+
+func (c *central) loop() {
+       for {
+               // L2CAP implementations shall support a minimum MTU size of 48 
bytes.
+               // The default value is 672 bytes
+               b := make([]byte, 672)
+               n, err := c.l2conn.Read(b)
+               if n == 0 || err != nil {
+                       c.Close()
+                       break
+               }
+               if rsp := c.handleReq(b[:n]); rsp != nil {
+                       c.l2conn.Write(rsp)
+               }
+       }
+}
+
+// handleReq dispatches a raw request from the central shim
+// to an appropriate handler, based on its type.
+// It panics if len(b) == 0.
+func (c *central) handleReq(b []byte) []byte {
+       var resp []byte
+       switch reqType, req := b[0], b[1:]; reqType {
+       case attOpMtuReq:
+               resp = c.handleMTU(req)
+       case attOpFindInfoReq:
+               resp = c.handleFindInfo(req)
+       case attOpFindByTypeValueReq:
+               resp = c.handleFindByTypeValue(req)
+       case attOpReadByTypeReq:
+               resp = c.handleReadByType(req)
+       case attOpReadReq:
+               resp = c.handleRead(req)
+       case attOpReadBlobReq:
+               resp = c.handleReadBlob(req)
+       case attOpReadByGroupReq:
+               resp = c.handleReadByGroup(req)
+       case attOpWriteReq, attOpWriteCmd:
+               resp = c.handleWrite(reqType, req)
+       case attOpReadMultiReq, attOpPrepWriteReq, attOpExecWriteReq, 
attOpSignedWriteCmd:
+               fallthrough
+       default:
+               resp = attErrorRsp(reqType, 0x0000, attEcodeReqNotSupp)
+       }
+       return resp
+}
+
+func (c *central) handleMTU(b []byte) []byte {
+       c.mtu = binary.LittleEndian.Uint16(b[:2])
+       if c.mtu < 23 {
+               c.mtu = 23
+       }
+       if c.mtu >= 256 {
+               c.mtu = 256
+       }
+       return []byte{attOpMtuRsp, uint8(c.mtu), uint8(c.mtu >> 8)}
+}
+
+// REQ: FindInfoReq(0x04), StartHandle, EndHandle
+// RSP: FindInfoRsp(0x05), UUIDFormat, Handle, UUID, Handle, UUID, ...
+func (c *central) handleFindInfo(b []byte) []byte {
+       start, end := readHandleRange(b[:4])
+
+       w := newL2capWriter(c.mtu)
+       w.WriteByteFit(attOpFindInfoRsp)
+
+       uuidLen := -1
+       for _, a := range c.attrs.Subrange(start, end) {
+               if uuidLen == -1 {
+                       uuidLen = a.typ.Len()
+                       if uuidLen == 2 {
+                               w.WriteByteFit(0x01) // TODO: constants for 
16bit vs 128bit uuid magic numbers here
+                       } else {
+                               w.WriteByteFit(0x02)
+                       }
+               }
+               if a.typ.Len() != uuidLen {
+                       break
+               }
+               w.Chunk()
+               w.WriteUint16Fit(a.h)
+               w.WriteUUIDFit(a.typ)
+               if ok := w.Commit(); !ok {
+                       break
+               }
+       }
+
+       if uuidLen == -1 {
+               return attErrorRsp(attOpFindInfoReq, start, 
attEcodeAttrNotFound)
+       }
+       return w.Bytes()
+}
+
+// REQ: FindByTypeValueReq(0x06), StartHandle, EndHandle, Type(UUID), Value
+// RSP: FindByTypeValueRsp(0x07), AttrHandle, GroupEndHandle, AttrHandle, 
GroupEndHandle, ...
+func (c *central) handleFindByTypeValue(b []byte) []byte {
+       start, end := readHandleRange(b[:4])
+       t := UUID{b[4:6]}
+       u := UUID{b[6:]}
+
+       // Only support the ATT ReadByGroupReq for GATT Primary Service 
Discovery.
+       // More sepcifically, the "Discover Primary Services By Service UUID" 
sub-procedure
+       if !t.Equal(attrPrimaryServiceUUID) {
+               return attErrorRsp(attOpFindByTypeValueReq, start, 
attEcodeAttrNotFound)
+       }
+
+       w := newL2capWriter(c.mtu)
+       w.WriteByteFit(attOpFindByTypeValueRsp)
+
+       var wrote bool
+       for _, a := range c.attrs.Subrange(start, end) {
+               if !a.typ.Equal(attrPrimaryServiceUUID) {
+                       continue
+               }
+               if !(UUID{a.value}.Equal(u)) {
+                       continue
+               }
+               s := a.pvt.(*Service)
+               w.Chunk()
+               w.WriteUint16Fit(s.h)
+               w.WriteUint16Fit(s.endh)
+               if ok := w.Commit(); !ok {
+                       break
+               }
+               wrote = true
+       }
+       if !wrote {
+               return attErrorRsp(attOpFindByTypeValueReq, start, 
attEcodeAttrNotFound)
+       }
+
+       return w.Bytes()
+}
+
+// REQ: ReadByType(0x08), StartHandle, EndHandle, Type(UUID)
+// RSP: ReadByType(0x09), LenOfEachDataField, DataField, DataField, ...
+func (c *central) handleReadByType(b []byte) []byte {
+       start, end := readHandleRange(b[:4])
+       t := UUID{b[4:]}
+
+       w := newL2capWriter(c.mtu)
+       w.WriteByteFit(attOpReadByTypeRsp)
+       uuidLen := -1
+       for _, a := range c.attrs.Subrange(start, end) {
+               if !a.typ.Equal(t) {
+                       continue
+               }
+               if (a.secure&CharRead) != 0 && c.security > securityLow {
+                       return attErrorRsp(attOpReadByTypeReq, start, 
attEcodeAuthentication)
+               }
+               v := a.value
+               if v == nil {
+                       rsp := newResponseWriter(int(c.mtu - 1))
+                       req := &ReadRequest{
+                               Request: Request{Central: c},
+                               Cap:     int(c.mtu - 1),
+                               Offset:  0,
+                       }
+                       if c, ok := a.pvt.(*Characteristic); ok {
+                               c.rhandler.ServeRead(rsp, req)
+                       } else if d, ok := a.pvt.(*Descriptor); ok {
+                               d.rhandler.ServeRead(rsp, req)
+                       }
+                       v = rsp.bytes()
+               }
+               if uuidLen == -1 {
+                       uuidLen = len(v)
+                       w.WriteByteFit(byte(uuidLen) + 2)
+               }
+               if len(v) != uuidLen {
+                       break
+               }
+               w.Chunk()
+               w.WriteUint16Fit(a.h)
+               w.WriteFit(v)
+               if ok := w.Commit(); !ok {
+                       break
+               }
+       }
+       if uuidLen == -1 {
+               return attErrorRsp(attOpReadByTypeReq, start, 
attEcodeAttrNotFound)
+       }
+       return w.Bytes()
+}
+
+// REQ: ReadReq(0x0A), Handle
+// RSP: ReadRsp(0x0B), Value
+func (c *central) handleRead(b []byte) []byte {
+       h := binary.LittleEndian.Uint16(b)
+       a, ok := c.attrs.At(h)
+       if !ok {
+               return attErrorRsp(attOpReadReq, h, attEcodeInvalidHandle)
+       }
+       if a.props&CharRead == 0 {
+               return attErrorRsp(attOpReadReq, h, attEcodeReadNotPerm)
+       }
+       if a.secure&CharRead != 0 && c.security > securityLow {
+               return attErrorRsp(attOpReadReq, h, attEcodeAuthentication)
+       }
+       v := a.value
+       if v == nil {
+               req := &ReadRequest{
+                       Request: Request{Central: c},
+                       Cap:     int(c.mtu - 1),
+                       Offset:  0,
+               }
+               rsp := newResponseWriter(int(c.mtu - 1))
+               if c, ok := a.pvt.(*Characteristic); ok {
+                       c.rhandler.ServeRead(rsp, req)
+               } else if d, ok := a.pvt.(*Descriptor); ok {
+                       d.rhandler.ServeRead(rsp, req)
+               }
+               v = rsp.bytes()
+       }
+
+       w := newL2capWriter(c.mtu)
+       w.WriteByteFit(attOpReadRsp)
+       w.Chunk()
+       w.WriteFit(v)
+       w.CommitFit()
+       return w.Bytes()
+}
+
+// FIXME: check this, untested, might be broken
+func (c *central) handleReadBlob(b []byte) []byte {
+       h := binary.LittleEndian.Uint16(b)
+       offset := binary.LittleEndian.Uint16(b[2:])
+       a, ok := c.attrs.At(h)
+       if !ok {
+               return attErrorRsp(attOpReadBlobReq, h, attEcodeInvalidHandle)
+       }
+       if a.props&CharRead == 0 {
+               return attErrorRsp(attOpReadBlobReq, h, attEcodeReadNotPerm)
+       }
+       if a.secure&CharRead != 0 && c.security > securityLow {
+               return attErrorRsp(attOpReadBlobReq, h, attEcodeAuthentication)
+       }
+       v := a.value
+       if v == nil {
+               req := &ReadRequest{
+                       Request: Request{Central: c},
+                       Cap:     int(c.mtu - 1),
+                       Offset:  int(offset),
+               }
+               rsp := newResponseWriter(int(c.mtu - 1))
+               if c, ok := a.pvt.(*Characteristic); ok {
+                       c.rhandler.ServeRead(rsp, req)
+               } else if d, ok := a.pvt.(*Descriptor); ok {
+                       d.rhandler.ServeRead(rsp, req)
+               }
+               v = rsp.bytes()
+               offset = 0 // the server has already adjusted for the offset
+       }
+       w := newL2capWriter(c.mtu)
+       w.WriteByteFit(attOpReadBlobRsp)
+       w.Chunk()
+       w.WriteFit(v)
+       if ok := w.ChunkSeek(offset); !ok {
+               return attErrorRsp(attOpReadBlobReq, h, attEcodeInvalidOffset)
+       }
+       w.CommitFit()
+       return w.Bytes()
+}
+
+func (c *central) handleReadByGroup(b []byte) []byte {
+       start, end := readHandleRange(b)
+       t := UUID{b[4:]}
+
+       // Only support the ATT ReadByGroupReq for GATT Primary Service 
Discovery.
+       // More specifically, the "Discover All Primary Services" sub-procedure.
+       if !t.Equal(attrPrimaryServiceUUID) {
+               return attErrorRsp(attOpReadByGroupReq, start, 
attEcodeUnsuppGrpType)
+       }
+
+       w := newL2capWriter(c.mtu)
+       w.WriteByteFit(attOpReadByGroupRsp)
+       uuidLen := -1
+       for _, a := range c.attrs.Subrange(start, end) {
+               if !a.typ.Equal(attrPrimaryServiceUUID) {
+                       continue
+               }
+               if uuidLen == -1 {
+                       uuidLen = len(a.value)
+                       w.WriteByteFit(byte(uuidLen + 4))
+               }
+               if uuidLen != len(a.value) {
+                       break
+               }
+               s := a.pvt.(*Service)
+               w.Chunk()
+               w.WriteUint16Fit(s.h)
+               w.WriteUint16Fit(s.endh)
+               w.WriteFit(a.value)
+               if ok := w.Commit(); !ok {
+                       break
+               }
+       }
+       if uuidLen == -1 {
+               return attErrorRsp(attOpReadByGroupReq, start, 
attEcodeAttrNotFound)
+       }
+       return w.Bytes()
+}
+
+func (c *central) handleWrite(reqType byte, b []byte) []byte {
+       h := binary.LittleEndian.Uint16(b[:2])
+       value := b[2:]
+
+       a, ok := c.attrs.At(h)
+       if !ok {
+               return attErrorRsp(reqType, h, attEcodeInvalidHandle)
+       }
+
+       noRsp := reqType == attOpWriteCmd
+       charFlag := CharWrite
+       if noRsp {
+               charFlag = CharWriteNR
+       }
+       if a.props&charFlag == 0 {
+               return attErrorRsp(reqType, h, attEcodeWriteNotPerm)
+       }
+       if a.secure&charFlag == 0 && c.security > securityLow {
+               return attErrorRsp(reqType, h, attEcodeAuthentication)
+       }
+
+       // Props of Service and Characteristic declration are read only.
+       // So we only need deal with writable descriptors here.
+       // (Characteristic's value is implemented with descriptor)
+       if !a.typ.Equal(attrClientCharacteristicConfigUUID) {
+               // Regular write, not CCC
+               r := Request{Central: c}
+               if c, ok := a.pvt.(*Characteristic); ok {
+                       c.whandler.ServeWrite(r, value)
+               } else if d, ok := a.pvt.(*Characteristic); ok {
+                       d.whandler.ServeWrite(r, value)
+               }
+               if noRsp {
+                       return nil
+               } else {
+                       return []byte{attOpWriteRsp}
+               }
+       }
+
+       // CCC/descriptor write
+       if len(value) != 2 {
+               return attErrorRsp(reqType, h, attEcodeInvalAttrValueLen)
+       }
+       ccc := binary.LittleEndian.Uint16(value)
+       // char := a.pvt.(*Descriptor).char
+       if ccc&(gattCCCNotifyFlag|gattCCCIndicateFlag) != 0 {
+               c.startNotify(&a, int(c.mtu-3))
+       } else {
+               c.stopNotify(&a)
+       }
+       if noRsp {
+               return nil
+       }
+       return []byte{attOpWriteRsp}
+}
+
+func (c *central) sendNotification(a *attr, data []byte) (int, error) {
+       w := newL2capWriter(c.mtu)
+       w.WriteByteFit(attOpHandleNotify)
+       w.WriteUint16Fit(a.pvt.(*Descriptor).char.vh)
+       w.WriteFit(data)
+       return c.l2conn.Write(w.Bytes())
+}
+
+func readHandleRange(b []byte) (start, end uint16) {
+       return binary.LittleEndian.Uint16(b), binary.LittleEndian.Uint16(b[2:])
+}
+
+func (c *central) startNotify(a *attr, maxlen int) {
+       c.notifiersmu.Lock()
+       defer c.notifiersmu.Unlock()
+       if _, found := c.notifiers[a.h]; found {
+               return
+       }
+       char := a.pvt.(*Descriptor).char
+       n := newNotifier(c, a, maxlen)
+       c.notifiers[a.h] = n
+       go char.nhandler.ServeNotify(Request{Central: c}, n)
+}
+
+func (c *central) stopNotify(a *attr) {
+       c.notifiersmu.Lock()
+       defer c.notifiersmu.Unlock()
+       // char := a.pvt.(*Characteristic)
+       if n, found := c.notifiers[a.h]; found {
+               n.stop()
+               delete(c.notifiers, a.h)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/common.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/common.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/common.go
new file mode 100644
index 0000000..4fa2389
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/common.go
@@ -0,0 +1,399 @@
+package gatt
+
+// Supported statuses for GATT characteristic read/write operations.
+// These correspond to att constants in the BLE spec
+const (
+       StatusSuccess         = 0
+       StatusInvalidOffset   = 1
+       StatusUnexpectedError = 2
+)
+
+// A Request is the context for a request from a connected central device.
+// TODO: Replace this with more general context, such as:
+// http://godoc.org/golang.org/x/net/context
+type Request struct {
+       Central Central
+}
+
+// A ReadRequest is a characteristic read request from a connected device.
+type ReadRequest struct {
+       Request
+       Cap    int // maximum allowed reply length
+       Offset int // request value offset
+}
+
+type Property int
+
+// Characteristic property flags (spec 3.3.3.1)
+const (
+       CharBroadcast   Property = 0x01 // may be brocasted
+       CharRead        Property = 0x02 // may be read
+       CharWriteNR     Property = 0x04 // may be written to, with no reply
+       CharWrite       Property = 0x08 // may be written to, with a reply
+       CharNotify      Property = 0x10 // supports notifications
+       CharIndicate    Property = 0x20 // supports Indications
+       CharSignedWrite Property = 0x40 // supports signed write
+       CharExtended    Property = 0x80 // supports extended properties
+)
+
+func (p Property) String() (result string) {
+       if (p & CharBroadcast) != 0 {
+               result += "broadcast "
+       }
+       if (p & CharRead) != 0 {
+               result += "read "
+       }
+       if (p & CharWriteNR) != 0 {
+               result += "writeWithoutResponse "
+       }
+       if (p & CharWrite) != 0 {
+               result += "write "
+       }
+       if (p & CharNotify) != 0 {
+               result += "notify "
+       }
+       if (p & CharIndicate) != 0 {
+               result += "indicate "
+       }
+       if (p & CharSignedWrite) != 0 {
+               result += "authenticateSignedWrites "
+       }
+       if (p & CharExtended) != 0 {
+               result += "extendedProperties "
+       }
+       return
+}
+
+// A Service is a BLE service.
+type Service struct {
+       uuid  UUID
+       chars []*Characteristic
+
+       h    uint16
+       endh uint16
+}
+
+// NewService creates and initialize a new Service using u as it's UUID.
+func NewService(u UUID) *Service {
+       return &Service{uuid: u}
+}
+
+// AddCharacteristic adds a characteristic to a service.
+// AddCharacteristic panics if the service already contains another
+// characteristic with the same UUID.
+func (s *Service) AddCharacteristic(u UUID) *Characteristic {
+       for _, c := range s.chars {
+               if c.uuid.Equal(u) {
+                       panic("service already contains a characteristic with 
uuid " + u.String())
+               }
+       }
+       c := &Characteristic{uuid: u, svc: s}
+       s.chars = append(s.chars, c)
+       return c
+}
+
+// UUID returns the UUID of the service.
+func (s *Service) UUID() UUID { return s.uuid }
+
+// Name returns the specificatin name of the service according to its UUID.
+// If the UUID is not assigne, Name returns an empty string.
+func (s *Service) Name() string {
+       return knownServices[s.uuid.String()].Name
+}
+
+// Handle returns the Handle of the service.
+func (s *Service) Handle() uint16 { return s.h }
+
+// EndHandle returns the End Handle of the service.
+func (s *Service) EndHandle() uint16 { return s.endh }
+
+// SetHandle sets the Handle of the service.
+func (s *Service) SetHandle(h uint16) { s.h = h }
+
+// SetEndHandle sets the End Handle of the service.
+func (s *Service) SetEndHandle(endh uint16) { s.endh = endh }
+
+// SetCharacteristics sets the Characteristics of the service.
+func (s *Service) SetCharacteristics(chars []*Characteristic) { s.chars = 
chars }
+
+// Characteristic returns the contained characteristic of this service.
+func (s *Service) Characteristics() []*Characteristic { return s.chars }
+
+// A Characteristic is a BLE characteristic.
+type Characteristic struct {
+       uuid   UUID
+       props  Property // enabled properties
+       secure Property // security enabled properties
+       svc    *Service
+       cccd   *Descriptor
+       descs  []*Descriptor
+
+       value []byte
+
+       // All the following fields are only used in peripheral/server 
implementation.
+       rhandler ReadHandler
+       whandler WriteHandler
+       nhandler NotifyHandler
+
+       h    uint16
+       vh   uint16
+       endh uint16
+}
+
+// NewCharacteristic creates and returns a Characteristic.
+func NewCharacteristic(u UUID, s *Service, props Property, h uint16, vh 
uint16) *Characteristic {
+       c := &Characteristic{
+               uuid:  u,
+               svc:   s,
+               props: props,
+               h:     h,
+               vh:    vh,
+       }
+
+       return c
+}
+
+// Handle returns the Handle of the characteristic.
+func (c *Characteristic) Handle() uint16 { return c.h }
+
+// VHandle returns the Value Handle of the characteristic.
+func (c *Characteristic) VHandle() uint16 { return c.vh }
+
+// EndHandle returns the End Handle of the characteristic.
+func (c *Characteristic) EndHandle() uint16 { return c.endh }
+
+// Descriptor returns the Descriptor of the characteristic.
+func (c *Characteristic) Descriptor() *Descriptor { return c.cccd }
+
+// SetHandle sets the Handle of the characteristic.
+func (c *Characteristic) SetHandle(h uint16) { c.h = h }
+
+// SetVHandle sets the Value Handle of the characteristic.
+func (c *Characteristic) SetVHandle(vh uint16) { c.vh = vh }
+
+// SetEndHandle sets the End Handle of the characteristic.
+func (c *Characteristic) SetEndHandle(endh uint16) { c.endh = endh }
+
+// SetDescriptor sets the Descriptor of the characteristic.
+func (c *Characteristic) SetDescriptor(cccd *Descriptor) { c.cccd = cccd }
+
+// SetDescriptors sets the list of Descriptor of the characteristic.
+func (c *Characteristic) SetDescriptors(descs []*Descriptor) { c.descs = descs 
}
+
+// UUID returns the UUID of the characteristic.
+func (c *Characteristic) UUID() UUID {
+       return c.uuid
+}
+
+// Name returns the specificatin name of the characteristic.
+// If the UUID is not assigned, Name returns empty string.
+func (c *Characteristic) Name() string {
+       return knownCharacteristics[c.uuid.String()].Name
+}
+
+// Service returns the containing service of this characteristic.
+func (c *Characteristic) Service() *Service {
+       return c.svc
+}
+
+// Properties returns the properties of this characteristic.
+func (c *Characteristic) Properties() Property {
+       return c.props
+}
+
+// Descriptors returns the contained descriptors of this characteristic.
+func (c *Characteristic) Descriptors() []*Descriptor {
+       return c.descs
+}
+
+// AddDescriptor adds a descriptor to a characteristic.
+// AddDescriptor panics if the characteristic already contains another
+// descriptor with the same UUID.
+func (c *Characteristic) AddDescriptor(u UUID) *Descriptor {
+       for _, d := range c.descs {
+               if d.uuid.Equal(u) {
+                       panic("service already contains a characteristic with 
uuid " + u.String())
+               }
+       }
+       d := &Descriptor{uuid: u, char: c}
+       c.descs = append(c.descs, d)
+       return d
+}
+
+// SetValue makes the characteristic support read requests, and returns a
+// static value. SetValue must be called before the containing service is
+// added to a server.
+// SetValue panics if the characteristic has been configured with a 
ReadHandler.
+func (c *Characteristic) SetValue(b []byte) {
+       if c.rhandler != nil {
+               panic("charactristic has been configured with a read handler")
+       }
+       c.props |= CharRead
+       // c.secure |= CharRead
+       c.value = make([]byte, len(b))
+       copy(c.value, b)
+}
+
+// HandleRead makes the characteristic support read requests, and routes read
+// requests to h. HandleRead must be called before the containing service is
+// added to a server.
+// HandleRead panics if the characteristic has been configured with a static 
value.
+func (c *Characteristic) HandleRead(h ReadHandler) {
+       if c.value != nil {
+               panic("charactristic has been configured with a static value")
+       }
+       c.props |= CharRead
+       // c.secure |= CharRead
+       c.rhandler = h
+}
+
+// HandleReadFunc calls HandleRead(ReadHandlerFunc(f)).
+func (c *Characteristic) HandleReadFunc(f func(rsp ResponseWriter, req 
*ReadRequest)) {
+       c.HandleRead(ReadHandlerFunc(f))
+}
+
+// HandleWrite makes the characteristic support write and write-no-response
+// requests, and routes write requests to h.
+// The WriteHandler does not differentiate between write and write-no-response
+// requests; it is handled automatically.
+// HandleWrite must be called before the containing service is added to a 
server.
+func (c *Characteristic) HandleWrite(h WriteHandler) {
+       c.props |= CharWrite | CharWriteNR
+       // c.secure |= CharWrite | CharWriteNR
+       c.whandler = h
+}
+
+// HandleWriteFunc calls HandleWrite(WriteHandlerFunc(f)).
+func (c *Characteristic) HandleWriteFunc(f func(r Request, data []byte) 
(status byte)) {
+       c.HandleWrite(WriteHandlerFunc(f))
+}
+
+// HandleNotify makes the characteristic support notify requests, and routes
+// notification requests to h. HandleNotify must be called before the
+// containing service is added to a server.
+func (c *Characteristic) HandleNotify(h NotifyHandler) {
+       if c.cccd != nil {
+               return
+       }
+       p := CharNotify | CharIndicate
+       c.props |= p
+       c.nhandler = h
+
+       // add ccc (client characteristic configuration) descriptor
+       secure := Property(0)
+       // If the characteristic requested secure notifications,
+       // then set ccc security to r/w.
+       if c.secure&p != 0 {
+               secure = CharRead | CharWrite
+       }
+       cd := &Descriptor{
+               uuid:   attrClientCharacteristicConfigUUID,
+               props:  CharRead | CharWrite | CharWriteNR,
+               secure: secure,
+               // FIXME: currently, we always return 0, which is inaccurate.
+               // Each connection should have it's own copy of this value.
+               value: []byte{0x00, 0x00},
+               char:  c,
+       }
+       c.cccd = cd
+       c.descs = append(c.descs, cd)
+}
+
+// HandleNotifyFunc calls HandleNotify(NotifyHandlerFunc(f)).
+func (c *Characteristic) HandleNotifyFunc(f func(r Request, n Notifier)) {
+       c.HandleNotify(NotifyHandlerFunc(f))
+}
+
+// TODO
+// func (c *Characteristic) SubscribedCentrals() []Central{
+// }
+
+// Descriptor is a BLE descriptor
+type Descriptor struct {
+       uuid   UUID
+       char   *Characteristic
+       props  Property // enabled properties
+       secure Property // security enabled properties
+
+       h     uint16
+       value []byte
+
+       rhandler ReadHandler
+       whandler WriteHandler
+}
+
+// Handle returns the Handle of the descriptor.
+func (d *Descriptor) Handle() uint16 { return d.h }
+
+// SetHandle sets the Handle of the descriptor.
+func (d *Descriptor) SetHandle(h uint16) { d.h = h }
+
+// NewDescriptor creates and returns a Descriptor.
+func NewDescriptor(u UUID, h uint16, char *Characteristic) *Descriptor {
+       cd := &Descriptor{
+               uuid: u,
+               h:    h,
+               char: char,
+       }
+       return cd
+}
+
+// UUID returns the UUID of the descriptor.
+func (d *Descriptor) UUID() UUID {
+       return d.uuid
+}
+
+// Name returns the specificatin name of the descriptor.
+// If the UUID is not assigned, returns an empty string.
+func (d *Descriptor) Name() string {
+       return knownDescriptors[d.uuid.String()].Name
+}
+
+// Characteristic returns the containing characteristic of the descriptor.
+func (d *Descriptor) Characteristic() *Characteristic {
+       return d.char
+}
+
+// SetValue makes the descriptor support read requests, and returns a static 
value.
+// SetValue must be called before the containing service is added to a server.
+// SetValue panics if the descriptor has already configured with a ReadHandler.
+func (d *Descriptor) SetValue(b []byte) {
+       if d.rhandler != nil {
+               panic("descriptor has been configured with a read handler")
+       }
+       d.props |= CharRead
+       // d.secure |= CharRead
+       d.value = make([]byte, len(b))
+       copy(d.value, b)
+}
+
+// HandleRead makes the descriptor support read requests, and routes read 
requests to h.
+// HandleRead must be called before the containing service is added to a 
server.
+// HandleRead panics if the descriptor has been configured with a static value.
+func (d *Descriptor) HandleRead(h ReadHandler) {
+       if d.value != nil {
+               panic("descriptor has been configured with a static value")
+       }
+       d.props |= CharRead
+       // d.secure |= CharRead
+       d.rhandler = h
+}
+
+// HandleReadFunc calls HandleRead(ReadHandlerFunc(f)).
+func (d *Descriptor) HandleReadFunc(f func(rsp ResponseWriter, req 
*ReadRequest)) {
+       d.HandleRead(ReadHandlerFunc(f))
+}
+
+// HandleWrite makes the descriptor support write and write-no-response 
requests, and routes write requests to h.
+// The WriteHandler does not differentiate between write and write-no-response 
requests; it is handled automatically.
+// HandleWrite must be called before the containing service is added to a 
server.
+func (d *Descriptor) HandleWrite(h WriteHandler) {
+       d.props |= CharWrite | CharWriteNR
+       // d.secure |= CharWrite | CharWriteNR
+       d.whandler = h
+}
+
+// HandleWriteFunc calls HandleWrite(WriteHandlerFunc(f)).
+func (d *Descriptor) HandleWriteFunc(f func(r Request, data []byte) (status 
byte)) {
+       d.HandleWrite(WriteHandlerFunc(f))
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/const.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/const.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/const.go
new file mode 100644
index 0000000..4a04b04
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/const.go
@@ -0,0 +1,153 @@
+package gatt
+
+// This file includes constants from the BLE spec.
+
+var (
+       attrGAPUUID  = UUID16(0x1800)
+       attrGATTUUID = UUID16(0x1801)
+
+       attrPrimaryServiceUUID   = UUID16(0x2800)
+       attrSecondaryServiceUUID = UUID16(0x2801)
+       attrIncludeUUID          = UUID16(0x2802)
+       attrCharacteristicUUID   = UUID16(0x2803)
+
+       attrClientCharacteristicConfigUUID = UUID16(0x2902)
+       attrServerCharacteristicConfigUUID = UUID16(0x2903)
+
+       attrDeviceNameUUID        = UUID16(0x2A00)
+       attrAppearanceUUID        = UUID16(0x2A01)
+       attrPeripheralPrivacyUUID = UUID16(0x2A02)
+       attrReconnectionAddrUUID  = UUID16(0x2A03)
+       attrPeferredParamsUUID    = UUID16(0x2A04)
+       attrServiceChangedUUID    = UUID16(0x2A05)
+)
+
+const (
+       gattCCCNotifyFlag   = 0x0001
+       gattCCCIndicateFlag = 0x0002
+)
+
+const (
+       attOpError              = 0x01
+       attOpMtuReq             = 0x02
+       attOpMtuRsp             = 0x03
+       attOpFindInfoReq        = 0x04
+       attOpFindInfoRsp        = 0x05
+       attOpFindByTypeValueReq = 0x06
+       attOpFindByTypeValueRsp = 0x07
+       attOpReadByTypeReq      = 0x08
+       attOpReadByTypeRsp      = 0x09
+       attOpReadReq            = 0x0a
+       attOpReadRsp            = 0x0b
+       attOpReadBlobReq        = 0x0c
+       attOpReadBlobRsp        = 0x0d
+       attOpReadMultiReq       = 0x0e
+       attOpReadMultiRsp       = 0x0f
+       attOpReadByGroupReq     = 0x10
+       attOpReadByGroupRsp     = 0x11
+       attOpWriteReq           = 0x12
+       attOpWriteRsp           = 0x13
+       attOpWriteCmd           = 0x52
+       attOpPrepWriteReq       = 0x16
+       attOpPrepWriteRsp       = 0x17
+       attOpExecWriteReq       = 0x18
+       attOpExecWriteRsp       = 0x19
+       attOpHandleNotify       = 0x1b
+       attOpHandleInd          = 0x1d
+       attOpHandleCnf          = 0x1e
+       attOpSignedWriteCmd     = 0xd2
+)
+
+type attEcode byte
+
+const (
+       attEcodeSuccess           attEcode = 0x00 // Success
+       attEcodeInvalidHandle     attEcode = 0x01 // The attribute handle given 
was not valid on this server.
+       attEcodeReadNotPerm       attEcode = 0x02 // The attribute cannot be 
read.
+       attEcodeWriteNotPerm      attEcode = 0x03 // The attribute cannot be 
written.
+       attEcodeInvalidPDU        attEcode = 0x04 // The attribute PDU was 
invalid.
+       attEcodeAuthentication    attEcode = 0x05 // The attribute requires 
authentication before it can be read or written.
+       attEcodeReqNotSupp        attEcode = 0x06 // Attribute server does not 
support the request received from the client.
+       attEcodeInvalidOffset     attEcode = 0x07 // Offset specified was past 
the end of the attribute.
+       attEcodeAuthorization     attEcode = 0x08 // The attribute requires 
authorization before it can be read or written.
+       attEcodePrepQueueFull     attEcode = 0x09 // Too many prepare writes 
have been queued.
+       attEcodeAttrNotFound      attEcode = 0x0a // No attribute found within 
the given attribute handle range.
+       attEcodeAttrNotLong       attEcode = 0x0b // The attribute cannot be 
read or written using the Read Blob Request.
+       attEcodeInsuffEncrKeySize attEcode = 0x0c // The Encryption Key Size 
used for encrypting this link is insufficient.
+       attEcodeInvalAttrValueLen attEcode = 0x0d // The attribute value length 
is invalid for the operation.
+       attEcodeUnlikely          attEcode = 0x0e // The attribute request that 
was requested has encountered an error that was unlikely, and therefore could 
not be completed as requested.
+       attEcodeInsuffEnc         attEcode = 0x0f // The attribute requires 
encryption before it can be read or written.
+       attEcodeUnsuppGrpType     attEcode = 0x10 // The attribute type is not 
a supported grouping attribute as defined by a higher layer specification.
+       attEcodeInsuffResources   attEcode = 0x11 // Insufficient Resources to 
complete the request.
+)
+
+func (a attEcode) Error() string {
+       switch i := int(a); {
+       case i < 0x11:
+               return attEcodeName[a]
+       case i >= 0x12 && i <= 0x7F: // Reserved for future use
+               return "reserved error code"
+       case i >= 0x80 && i <= 0x9F: // Application Error, defined by higher 
level
+               return "reserved error code"
+       case i >= 0xA0 && i <= 0xDF: // Reserved for future use
+               return "reserved error code"
+       case i >= 0xE0 && i <= 0xFF: // Common profile and service error codes
+               return "profile or service error"
+       default: // can't happen, just make compiler happy
+               return "unkown error"
+       }
+}
+
+var attEcodeName = map[attEcode]string{
+       attEcodeSuccess:           "success",
+       attEcodeInvalidHandle:     "invalid handle",
+       attEcodeReadNotPerm:       "read not permitted",
+       attEcodeWriteNotPerm:      "write not permitted",
+       attEcodeInvalidPDU:        "invalid PDU",
+       attEcodeAuthentication:    "insufficient authentication",
+       attEcodeReqNotSupp:        "request not supported",
+       attEcodeInvalidOffset:     "invalid offset",
+       attEcodeAuthorization:     "insufficient authorization",
+       attEcodePrepQueueFull:     "prepare queue full",
+       attEcodeAttrNotFound:      "attribute not found",
+       attEcodeAttrNotLong:       "attribute not long",
+       attEcodeInsuffEncrKeySize: "insufficient encryption key size",
+       attEcodeInvalAttrValueLen: "invalid attribute value length",
+       attEcodeUnlikely:          "unlikely error",
+       attEcodeInsuffEnc:         "insufficient encryption",
+       attEcodeUnsuppGrpType:     "unsupported group type",
+       attEcodeInsuffResources:   "insufficient resources",
+}
+
+func attErrorRsp(op byte, h uint16, s attEcode) []byte {
+       return attErr{opcode: op, attr: h, status: s}.Marshal()
+}
+
+// attRspFor maps from att request
+// codes to att response codes.
+var attRspFor = map[byte]byte{
+       attOpMtuReq:             attOpMtuRsp,
+       attOpFindInfoReq:        attOpFindInfoRsp,
+       attOpFindByTypeValueReq: attOpFindByTypeValueRsp,
+       attOpReadByTypeReq:      attOpReadByTypeRsp,
+       attOpReadReq:            attOpReadRsp,
+       attOpReadBlobReq:        attOpReadBlobRsp,
+       attOpReadMultiReq:       attOpReadMultiRsp,
+       attOpReadByGroupReq:     attOpReadByGroupRsp,
+       attOpWriteReq:           attOpWriteRsp,
+       attOpPrepWriteReq:       attOpPrepWriteRsp,
+       attOpExecWriteReq:       attOpExecWriteRsp,
+}
+
+type attErr struct {
+       opcode uint8
+       attr   uint16
+       status attEcode
+}
+
+// TODO: Reformulate in a way that lets the caller avoid allocs.
+// Accept a []byte? Write directly to an io.Writer?
+func (e attErr) Marshal() []byte {
+       // little-endian encoding for attr
+       return []byte{attOpError, e.opcode, byte(e.attr), byte(e.attr >> 8), 
byte(e.status)}
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/device.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/device.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/device.go
new file mode 100644
index 0000000..eba96cf
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/device.go
@@ -0,0 +1,161 @@
+package gatt
+
+import "errors"
+
+var notImplemented = errors.New("not implemented")
+
+type State int
+
+const (
+       StateUnknown      State = 0
+       StateResetting    State = 1
+       StateUnsupported  State = 2
+       StateUnauthorized State = 3
+       StatePoweredOff   State = 4
+       StatePoweredOn    State = 5
+)
+
+func (s State) String() string {
+       str := []string{
+               "Unknown",
+               "Resetting",
+               "Unsupported",
+               "Unauthorized",
+               "PoweredOff",
+               "PoweredOn",
+       }
+       return str[int(s)]
+}
+
+// Device defines the interface for a BLE device.
+// Since an interface can't define fields(properties). To implement the
+// callback support for cerntain events, deviceHandler is defined and
+// implementation of Device on different platforms should embed it in
+// order to keep have keep compatible in API level.
+// Package users can use the Handler to set these handlers.
+type Device interface {
+       Init(stateChanged func(Device, State)) error
+
+       // Advertise advertise AdvPacket
+       Advertise(a *AdvPacket) error
+
+       // AdvertiseNameAndServices advertises device name, and specified 
service UUIDs.
+       // It tres to fit the UUIDs in the advertising packet as much as 
possible.
+       // If name doesn't fit in the advertising packet, it will be put in 
scan response.
+       AdvertiseNameAndServices(name string, ss []UUID) error
+
+       // AdvertiseIBeaconData advertise iBeacon with given manufacturer data.
+       AdvertiseIBeaconData(b []byte) error
+
+       // AdvertisingIbeacon advertises iBeacon with specified parameters.
+       AdvertiseIBeacon(u UUID, major, minor uint16, pwr int8) error
+
+       // StopAdvertising stops advertising.
+       StopAdvertising() error
+
+       // RemoveAllServices removes all services that are currently in the 
database.
+       RemoveAllServices() error
+
+       // Add Service add a service to database.
+       AddService(s *Service) error
+
+       // SetServices set the specified service to the database.
+       // It removes all currently added services, if any.
+       SetServices(ss []*Service) error
+
+       // Scan discovers surounding remote peripherals that have the Service 
UUID specified in ss.
+       // If ss is set to nil, all devices scanned are reported.
+       // dup specifies weather duplicated advertisement should be reported or 
not.
+       // When a remote peripheral is discovered, the PeripheralDiscovered 
Handler is called.
+       Scan(ss []UUID, dup bool)
+
+       // StopScanning stops scanning.
+       StopScanning()
+
+       // Connect connects to a remote peripheral.
+       Connect(p Peripheral)
+
+       // CancelConnection disconnects a remote peripheral.
+       CancelConnection(p Peripheral)
+
+       // Handle registers the specified handlers.
+       Handle(h ...Handler)
+
+       // Stop HCI Connection
+        Stop() error
+
+       // Option sets the options specified.
+       Option(o ...Option) error
+}
+
+// deviceHandler is the handlers(callbacks) of the Device.
+type deviceHandler struct {
+       // stateChanged is called when the device states changes.
+       stateChanged func(d Device, s State)
+
+       // connect is called when a remote central device connects to the 
device.
+       centralConnected func(c Central)
+
+       // disconnect is called when a remote central device disconnects to the 
device.
+       centralDisconnected func(c Central)
+
+       // peripheralDiscovered is called when a remote peripheral device is 
found during scan procedure.
+       peripheralDiscovered func(p Peripheral, a *Advertisement, rssi int)
+
+       // peripheralConnected is called when a remote peripheral is conneted.
+       peripheralConnected func(p Peripheral, err error)
+
+       // peripheralConnected is called when a remote peripheral is 
disconneted.
+       peripheralDisconnected func(p Peripheral, err error)
+}
+
+// A Handler is a self-referential function, which registers the options 
specified.
+// See 
http://commandcenter.blogspot.com.au/2014/01/self-referential-functions-and-design.html
 for more discussion.
+type Handler func(Device)
+
+// Handle registers the specified handlers.
+func (d *device) Handle(hh ...Handler) {
+       for _, h := range hh {
+               h(d)
+       }
+}
+
+// CentralConnected returns a Handler, which sets the specified function to be 
called when a device connects to the server.
+func CentralConnected(f func(Central)) Handler {
+       return func(d Device) { d.(*device).centralConnected = f }
+}
+
+// CentralDisconnected returns a Handler, which sets the specified function to 
be called when a device disconnects from the server.
+func CentralDisconnected(f func(Central)) Handler {
+       return func(d Device) { d.(*device).centralDisconnected = f }
+}
+
+// PeripheralDiscovered returns a Handler, which sets the specified function 
to be called when a remote peripheral device is found during scan procedure.
+func PeripheralDiscovered(f func(Peripheral, *Advertisement, int)) Handler {
+       return func(d Device) { d.(*device).peripheralDiscovered = f }
+}
+
+// PeripheralConnected returns a Handler, which sets the specified function to 
be called when a remote peripheral device connects.
+func PeripheralConnected(f func(Peripheral, error)) Handler {
+       return func(d Device) { d.(*device).peripheralConnected = f }
+}
+
+// PeripheralDisconnected returns a Handler, which sets the specified function 
to be called when a remote peripheral device disconnects.
+func PeripheralDisconnected(f func(Peripheral, error)) Handler {
+       return func(d Device) { d.(*device).peripheralDisconnected = f }
+}
+
+// An Option is a self-referential function, which sets the option specified.
+// Most Options are platform-specific, which gives more fine-grained control 
over the device at a cost of losing portibility.
+// See 
http://commandcenter.blogspot.com.au/2014/01/self-referential-functions-and-design.html
 for more discussion.
+type Option func(Device) error
+
+// Option sets the options specified.
+// Some options can only be set before the device is initialized; they are 
best used with NewDevice instead of Option.
+func (d *device) Option(opts ...Option) error {
+       var err error
+       for _, opt := range opts {
+               err = opt(d)
+       }
+       return err
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/device_darwin.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/device_darwin.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/device_darwin.go
new file mode 100644
index 0000000..acf4431
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/device_darwin.go
@@ -0,0 +1,513 @@
+package gatt
+
+import (
+       "bytes"
+       "encoding/binary"
+       "errors"
+       "fmt"
+       "log"
+       "sync"
+       "time"
+
+       "github.com/runtimeco/gatt/xpc"
+)
+
+const (
+       peripheralDiscovered   = 37
+       peripheralConnected    = 38
+       peripheralDisconnected = 40
+       // below constants for Yosemite
+       rssiRead                   = 55
+       includedServicesDiscovered = 63
+       serviceDiscovered          = 56
+       characteristicsDiscovered  = 64
+       characteristicRead         = 71
+       characteristicWritten      = 72
+       notificationValueSet       = 74
+       descriptorsDiscovered      = 76
+       descriptorRead             = 79
+       descriptorWritten          = 80
+)
+
+type device struct {
+       deviceHandler
+
+       conn xpc.XPC
+
+       role int // 1: peripheralManager (server), 0: centralManager (client)
+
+       reqc chan message
+       rspc chan message
+
+       // Only used in client/centralManager implementation
+       plist   map[string]*peripheral
+       plistmu *sync.Mutex
+
+       // Only used in server/peripheralManager implementation
+
+       attrN int
+       attrs map[int]*attr
+
+       subscribers map[string]*central
+}
+
+func NewDevice(opts ...Option) (Device, error) {
+       d := &device{
+               reqc:    make(chan message),
+               rspc:    make(chan message),
+               plist:   map[string]*peripheral{},
+               plistmu: &sync.Mutex{},
+
+               attrN: 1,
+               attrs: make(map[int]*attr),
+
+               subscribers: make(map[string]*central),
+       }
+       d.Option(opts...)
+       d.conn = xpc.XpcConnect("com.apple.blued", d)
+       return d, nil
+}
+
+func (d *device) Init(f func(Device, State)) error {
+       go d.loop()
+       rsp := d.sendReq(1, xpc.Dict{
+               "kCBMsgArgName":    fmt.Sprintf("gopher-%v", time.Now().Unix()),
+               "kCBMsgArgOptions": xpc.Dict{"kCBInitOptionShowPowerAlert": 1},
+               "kCBMsgArgType":    d.role,
+       })
+       d.stateChanged = f
+       go d.stateChanged(d, State(rsp.MustGetInt("kCBMsgArgState")))
+       return nil
+}
+
+func (d *device) Advertise(a *AdvPacket) error {
+       rsp := d.sendReq(8, xpc.Dict{
+               "kCBAdvDataAppleMfgData": a.b, // not a.Bytes(). should be slice
+       })
+
+       if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+               return errors.New("FIXME: Advertise error")
+       }
+       return nil
+}
+
+func (d *device) AdvertiseNameAndServices(name string, ss []UUID) error {
+       us := uuidSlice(ss)
+       rsp := d.sendReq(8, xpc.Dict{
+               "kCBAdvDataLocalName":    name,
+               "kCBAdvDataServiceUUIDs": us},
+       )
+       if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+               return errors.New("FIXME: Advertise error")
+       }
+       return nil
+}
+
+func (d *device) AdvertiseIBeaconData(data []byte) error {
+       var utsname xpc.Utsname
+       xpc.Uname(&utsname)
+
+       var rsp xpc.Dict
+
+       if utsname.Release >= "14." {
+               l := len(data)
+               buf := bytes.NewBuffer([]byte{byte(l + 5), 0xFF, 0x4C, 0x00, 
0x02, byte(l)})
+               buf.Write(data)
+               rsp = d.sendReq(8, xpc.Dict{"kCBAdvDataAppleMfgData": 
buf.Bytes()})
+       } else {
+               rsp = d.sendReq(8, xpc.Dict{"kCBAdvDataAppleBeaconKey": data})
+       }
+
+       if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+               return errors.New("FIXME: Advertise error")
+       }
+
+       return nil
+}
+
+func (d *device) AdvertiseIBeacon(u UUID, major, minor uint16, pwr int8) error 
{
+       b := make([]byte, 21)
+       copy(b, reverse(u.b))                     // Big endian
+       binary.BigEndian.PutUint16(b[16:], major) // Big endian
+       binary.BigEndian.PutUint16(b[18:], minor) // Big endian
+       b[20] = uint8(pwr)                        // Measured Tx Power
+       return d.AdvertiseIBeaconData(b)
+}
+
+func (d *device) StopAdvertising() error {
+       rsp := d.sendReq(9, nil)
+       if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+               return errors.New("FIXME: Stop Advertise error")
+       }
+       return nil
+}
+
+func (d *device) RemoveAllServices() error {
+       d.sendCmd(12, nil)
+       return nil
+}
+
+func (d *device) AddService(s *Service) error {
+       if s.uuid.Equal(attrGAPUUID) || s.uuid.Equal(attrGATTUUID) {
+               // skip GATT and GAP services
+               return nil
+       }
+
+       xs := xpc.Dict{
+               "kCBMsgArgAttributeID":     d.attrN,
+               "kCBMsgArgAttributeIDs":    []int{},
+               "kCBMsgArgCharacteristics": nil,
+               "kCBMsgArgType":            1, // 1 => primary, 0 => excluded
+               "kCBMsgArgUUID":            reverse(s.uuid.b),
+       }
+       d.attrN++
+
+       xcs := xpc.Array{}
+       for _, c := range s.Characteristics() {
+               props := 0
+               perm := 0
+               if c.props&CharRead != 0 {
+                       props |= 0x02
+                       if CharRead&c.secure != 0 {
+                               perm |= 0x04
+                       } else {
+                               perm |= 0x01
+                       }
+               }
+               if c.props&CharWriteNR != 0 {
+                       props |= 0x04
+                       if c.secure&CharWriteNR != 0 {
+                               perm |= 0x08
+                       } else {
+                               perm |= 0x02
+                       }
+               }
+               if c.props&CharWrite != 0 {
+                       props |= 0x08
+                       if c.secure&CharWrite != 0 {
+                               perm |= 0x08
+                       } else {
+                               perm |= 0x02
+                       }
+               }
+               if c.props&CharNotify != 0 {
+                       if c.secure&CharNotify != 0 {
+                               props |= 0x100
+                       } else {
+                               props |= 0x10
+                       }
+               }
+               if c.props&CharIndicate != 0 {
+                       if c.secure&CharIndicate != 0 {
+                               props |= 0x200
+                       } else {
+                               props |= 0x20
+                       }
+               }
+
+               xc := xpc.Dict{
+                       "kCBMsgArgAttributeID":              d.attrN,
+                       "kCBMsgArgUUID":                     reverse(c.uuid.b),
+                       "kCBMsgArgAttributePermissions":     perm,
+                       "kCBMsgArgCharacteristicProperties": props,
+                       "kCBMsgArgData":                     c.value,
+               }
+               d.attrs[d.attrN] = &attr{h: uint16(d.attrN), value: c.value, 
pvt: c}
+               d.attrN++
+
+               xds := xpc.Array{}
+               for _, d := range c.Descriptors() {
+                       if d.uuid.Equal(attrClientCharacteristicConfigUUID) {
+                               // skip CCCD
+                               continue
+                       }
+                       xd := xpc.Dict{
+                               "kCBMsgArgData": d.value,
+                               "kCBMsgArgUUID": reverse(d.uuid.b),
+                       }
+                       xds = append(xds, xd)
+               }
+               xc["kCBMsgArgDescriptors"] = xds
+               xcs = append(xcs, xc)
+       }
+       xs["kCBMsgArgCharacteristics"] = xcs
+
+       rsp := d.sendReq(10, xs)
+       if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+               return errors.New("FIXME: Add Srvice error")
+       }
+       return nil
+}
+
+func (d *device) SetServices(ss []*Service) error {
+       d.RemoveAllServices()
+       for _, s := range ss {
+               d.AddService(s)
+       }
+       return nil
+}
+
+func (d *device) Scan(ss []UUID, dup bool) {
+       args := xpc.Dict{
+               "kCBMsgArgUUIDs": uuidSlice(ss),
+               "kCBMsgArgOptions": xpc.Dict{
+                       "kCBScanOptionAllowDuplicates": map[bool]int{true: 1, 
false: 0}[dup],
+               },
+       }
+       d.sendCmd(29, args)
+}
+
+func (d *device) StopScanning() {
+       d.sendCmd(30, nil)
+}
+
+func (d *device) Connect(p Peripheral) {
+       pp := p.(*peripheral)
+       d.plist[pp.id.String()] = pp
+       d.sendCmd(31,
+               xpc.Dict{
+                       "kCBMsgArgDeviceUUID": pp.id,
+                       "kCBMsgArgOptions": xpc.Dict{
+                               "kCBConnectOptionNotifyOnDisconnection": 1,
+                       },
+               })
+}
+
+func (d *device) respondToRequest(id int, args xpc.Dict) {
+
+       switch id {
+       case 19: // ReadRequest
+               u := UUID{args.MustGetUUID("kCBMsgArgDeviceUUID")}
+               t := args.MustGetInt("kCBMsgArgTransactionID")
+               a := args.MustGetInt("kCBMsgArgAttributeID")
+               o := args.MustGetInt("kCBMsgArgOffset")
+
+               attr := d.attrs[a]
+               v := attr.value
+               if v == nil {
+                       c := newCentral(d, u)
+                       req := &ReadRequest{
+                               Request: Request{Central: c},
+                               Cap:     int(c.mtu - 1),
+                               Offset:  o,
+                       }
+                       rsp := newResponseWriter(int(c.mtu - 1))
+                       if c, ok := attr.pvt.(*Characteristic); ok {
+                               c.rhandler.ServeRead(rsp, req)
+                               v = rsp.bytes()
+                       }
+               }
+
+               d.sendCmd(13, xpc.Dict{
+                       "kCBMsgArgAttributeID":   a,
+                       "kCBMsgArgData":          v,
+                       "kCBMsgArgTransactionID": t,
+                       "kCBMsgArgResult":        0,
+               })
+
+       case 20: // WriteRequest
+               u := UUID{args.MustGetUUID("kCBMsgArgDeviceUUID")}
+               t := args.MustGetInt("kCBMsgArgTransactionID")
+               a := 0
+               noRsp := false
+               xxws := args.MustGetArray("kCBMsgArgATTWrites")
+               for _, xxw := range xxws {
+                       xw := xxw.(xpc.Dict)
+                       if a == 0 {
+                               a = xw.MustGetInt("kCBMsgArgAttributeID")
+                       }
+                       o := xw.MustGetInt("kCBMsgArgOffset")
+                       i := xw.MustGetInt("kCBMsgArgIgnoreResponse")
+                       b := xw.MustGetBytes("kCBMsgArgData")
+                       _ = o
+                       attr := d.attrs[a]
+                       c := newCentral(d, u)
+                       r := Request{Central: c}
+                       attr.pvt.(*Characteristic).whandler.ServeWrite(r, b)
+                       if i == 1 {
+                               noRsp = true
+                       }
+
+               }
+               if noRsp {
+                       break
+               }
+               d.sendCmd(13, xpc.Dict{
+                       "kCBMsgArgAttributeID":   a,
+                       "kCBMsgArgData":          nil,
+                       "kCBMsgArgTransactionID": t,
+                       "kCBMsgArgResult":        0,
+               })
+
+       case 21: // subscribed
+               u := UUID{args.MustGetUUID("kCBMsgArgDeviceUUID")}
+               a := args.MustGetInt("kCBMsgArgAttributeID")
+               attr := d.attrs[a]
+               c := newCentral(d, u)
+               d.subscribers[u.String()] = c
+               c.startNotify(attr, c.mtu)
+
+       case 22: // unubscribed
+               u := UUID{args.MustGetUUID("kCBMsgArgDeviceUUID")}
+               a := args.MustGetInt("kCBMsgArgAttributeID")
+               attr := d.attrs[a]
+               if c := d.subscribers[u.String()]; c != nil {
+                       c.stopNotify(attr)
+               }
+
+       case 23: // notificationSent
+       }
+}
+
+/*
+ * OSX GATT library currently doesn't work for Mynewt, so adding this stub to 
keep
+ * it buildable for OSX.
+ */
+func (d *device) Stop() error {
+       return nil
+}
+
+func (d *device) CancelConnection(p Peripheral) {
+       d.sendCmd(32, xpc.Dict{"kCBMsgArgDeviceUUID": p.(*peripheral).id})
+}
+
+// process device events and asynchronous errors
+// (implements XpcEventHandler)
+func (d *device) HandleXpcEvent(event xpc.Dict, err error) {
+       if err != nil {
+               log.Println("error:", err)
+               return
+       }
+
+       id := event.MustGetInt("kCBMsgId")
+       args := event.MustGetDict("kCBMsgArgs")
+       //log.Printf(">> %d, %v", id, args)
+
+       switch id {
+       case // device event
+               6,  // StateChanged
+               16, // AdvertisingStarted
+               17, // AdvertisingStopped
+               18: // ServiceAdded
+               d.rspc <- message{id: id, args: args}
+
+       case
+               19, // ReadRequest
+               20, // WriteRequest
+               21, // Subscribe
+               22, // Unubscribe
+               23: // Confirmation
+               d.respondToRequest(id, args)
+
+       case peripheralDiscovered:
+               xa := args.MustGetDict("kCBMsgArgAdvertisementData")
+               if len(xa) == 0 {
+                       return
+               }
+               u := UUID{args.MustGetUUID("kCBMsgArgDeviceUUID")}
+               a := &Advertisement{
+                       LocalName:        xa.GetString("kCBAdvDataLocalName", 
args.GetString("kCBMsgArgName", "")),
+                       TxPowerLevel:     xa.GetInt("kCBAdvDataTxPowerLevel", 
0),
+                       ManufacturerData: 
xa.GetBytes("kCBAdvDataManufacturerData", nil),
+               }
+
+               rssi := args.MustGetInt("kCBMsgArgRssi")
+
+               if xu, ok := xa["kCBAdvDataServiceUUIDs"]; ok {
+                       for _, xs := range xu.(xpc.Array) {
+                               s := UUID{reverse(xs.([]byte))}
+                               a.Services = append(a.Services, s)
+                       }
+               }
+               if xsds, ok := xa["kCBAdvDataServiceData"]; ok {
+                       xsd := xsds.(xpc.Array)
+                       for i := 0; i < len(xsd); i += 2 {
+                               sd := ServiceData{
+                                       UUID: UUID{xsd[i].([]byte)},
+                                       Data: xsd[i+1].([]byte),
+                               }
+                               a.ServiceData = append(a.ServiceData, sd)
+                       }
+               }
+               if d.peripheralDiscovered != nil {
+                       go d.peripheralDiscovered(&peripheral{id: 
xpc.UUID(u.b), d: d}, a, rssi)
+               }
+
+       case peripheralConnected:
+               u := UUID{args.MustGetUUID("kCBMsgArgDeviceUUID")}
+               p := &peripheral{
+                       id:    xpc.UUID(u.b),
+                       d:     d,
+                       reqc:  make(chan message),
+                       rspc:  make(chan message),
+                       quitc: make(chan struct{}),
+                       sub:   newSubscriber(),
+               }
+               d.plistmu.Lock()
+               d.plist[u.String()] = p
+               d.plistmu.Unlock()
+               go p.loop()
+
+               if d.peripheralConnected != nil {
+                       go d.peripheralConnected(p, nil)
+               }
+
+       case peripheralDisconnected:
+               u := UUID{args.MustGetUUID("kCBMsgArgDeviceUUID")}
+               d.plistmu.Lock()
+               p := d.plist[u.String()]
+               delete(d.plist, u.String())
+               d.plistmu.Unlock()
+               if d.peripheralDisconnected != nil {
+                       d.peripheralDisconnected(p, nil) // TODO: Get Result as 
error?
+               }
+               close(p.quitc)
+
+       case // Peripheral events
+               rssiRead,
+               serviceDiscovered,
+               includedServicesDiscovered,
+               characteristicsDiscovered,
+               characteristicRead,
+               characteristicWritten,
+               notificationValueSet,
+               descriptorsDiscovered,
+               descriptorRead,
+               descriptorWritten:
+
+               u := UUID{args.MustGetUUID("kCBMsgArgDeviceUUID")}
+               d.plistmu.Lock()
+               p := d.plist[u.String()]
+               d.plistmu.Unlock()
+               p.rspc <- message{id: id, args: args}
+
+       default:
+               log.Printf("Unhandled event: %#v", event)
+       }
+}
+
+func (d *device) sendReq(id int, args xpc.Dict) xpc.Dict {
+       m := message{id: id, args: args, rspc: make(chan xpc.Dict)}
+       d.reqc <- m
+       return <-m.rspc
+}
+
+func (d *device) sendCmd(id int, args xpc.Dict) {
+       d.reqc <- message{id: id, args: args}
+}
+
+func (d *device) loop() {
+       for req := range d.reqc {
+               d.sendCBMsg(req.id, req.args)
+               if req.rspc == nil {
+                       continue
+               }
+               m := <-d.rspc
+               req.rspc <- m.args
+       }
+}
+
+func (d *device) sendCBMsg(id int, args xpc.Dict) {
+       // log.Printf("<< %d, %v", id, args)
+       d.conn.Send(xpc.Dict{"kCBMsgId": id, "kCBMsgArgs": args}, false)
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/device_linux.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/device_linux.go 
b/newtmgr/vendor/github.com/runtimeco/gatt/device_linux.go
new file mode 100644
index 0000000..4c989e1
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/device_linux.go
@@ -0,0 +1,240 @@
+package gatt
+
+import (
+       "encoding/binary"
+       "net"
+
+       "github.com/runtimeco/gatt/linux"
+       "github.com/runtimeco/gatt/linux/cmd"
+)
+
+type device struct {
+       deviceHandler
+
+       hci   *linux.HCI
+       state State
+
+       // All the following fields are only used peripheralManager (server) 
implementation.
+       svcs  []*Service
+       attrs *attrRange
+
+       devID   int
+       chkLE   bool
+       maxConn int
+
+       advData   *cmd.LESetAdvertisingData
+       scanResp  *cmd.LESetScanResponseData
+       advParam  *cmd.LESetAdvertisingParameters
+       scanParam *cmd.LESetScanParameters
+}
+
+func NewDevice(opts ...Option) (Device, error) {
+       d := &device{
+               maxConn: 1,    // Support 1 connection at a time.
+               devID:   -1,   // Find an available HCI device.
+               chkLE:   true, // Check if the device supports LE.
+
+               advParam: &cmd.LESetAdvertisingParameters{
+                       AdvertisingIntervalMin:  0x800,     // [0x0800]: 0.625 
ms * 0x0800 = 1280.0 ms
+                       AdvertisingIntervalMax:  0x800,     // [0x0800]: 0.625 
ms * 0x0800 = 1280.0 ms
+                       AdvertisingType:         0x00,      // [0x00]: ADV_IND, 
0x01: DIRECT(HIGH), 0x02: SCAN, 0x03: NONCONN, 0x04: DIRECT(LOW)
+                       OwnAddressType:          0x00,      // [0x00]: public, 
0x01: random
+                       DirectAddressType:       0x00,      // [0x00]: public, 
0x01: random
+                       DirectAddress:           [6]byte{}, // Public or Random 
Address of the device to be connected
+                       AdvertisingChannelMap:   0x7,       // [0x07] 0x01: 
ch37, 0x2: ch38, 0x4: ch39
+                       AdvertisingFilterPolicy: 0x00,
+               },
+               scanParam: &cmd.LESetScanParameters{
+                       LEScanType:           0x01,   // [0x00]: passive, 0x01: 
active
+                       LEScanInterval:       0x0010, // [0x10]: 0.625ms * 16
+                       LEScanWindow:         0x0010, // [0x10]: 0.625ms * 16
+                       OwnAddressType:       0x00,   // [0x00]: public, 0x01: 
random
+                       ScanningFilterPolicy: 0x00,   // [0x00]: accept all, 
0x01: ignore non-white-listed.
+               },
+       }
+
+       d.Option(opts...)
+       h, err := linux.NewHCI(d.devID, d.chkLE, d.maxConn)
+       if err != nil {
+               return nil, err
+       }
+
+       d.hci = h
+       return d, nil
+}
+
+func (d *device) Init(f func(Device, State)) error {
+       d.hci.AcceptMasterHandler = func(pd *linux.PlatData) {
+               a := pd.Address
+               c := newCentral(d.attrs, net.HardwareAddr([]byte{a[5], a[4], 
a[3], a[2], a[1], a[0]}), pd.Conn)
+               if d.centralConnected != nil {
+                       d.centralConnected(c)
+               }
+               c.loop()
+               if d.centralDisconnected != nil {
+                       d.centralDisconnected(c)
+               }
+       }
+       d.hci.AcceptSlaveHandler = func(pd *linux.PlatData) {
+               p := &peripheral{
+                       d:     d,
+                       pd:    pd,
+                       l2c:   pd.Conn,
+                       reqc:  make(chan message),
+                       quitc: make(chan struct{}),
+                       sub:   newSubscriber(),
+               }
+               if d.peripheralConnected != nil {
+                       go d.peripheralConnected(p, nil)
+               }
+               p.loop()
+               if d.peripheralDisconnected != nil {
+                       d.peripheralDisconnected(p, nil)
+               }
+       }
+       d.hci.AdvertisementHandler = func(pd *linux.PlatData) {
+               a := &Advertisement{}
+               a.unmarshall(pd.Data)
+               a.Connectable = pd.Connectable
+               a.Address = pd.Address
+               a.AddressType = pd.AddressType
+               p := &peripheral{pd: pd, d: d}
+               if d.peripheralDiscovered != nil {
+                       pd.Name = a.LocalName
+                       d.peripheralDiscovered(p, a, int(pd.RSSI))
+               }
+       }
+       d.state = StatePoweredOn
+       d.stateChanged = f
+       go d.stateChanged(d, d.state)
+       return nil
+}
+
+func (d *device) Stop() error {
+       d.state = StatePoweredOff
+       defer d.stateChanged(d, d.state)
+       return d.hci.Close()
+}
+
+func (d *device) AddService(s *Service) error {
+       d.svcs = append(d.svcs, s)
+       d.attrs = generateAttributes(d.svcs, uint16(1)) // ble attrs start at 1
+       return nil
+}
+
+func (d *device) RemoveAllServices() error {
+       d.svcs = nil
+       d.attrs = nil
+       return nil
+}
+
+func (d *device) SetServices(s []*Service) error {
+       d.RemoveAllServices()
+       d.svcs = append(d.svcs, s...)
+       d.attrs = generateAttributes(d.svcs, uint16(1)) // ble attrs start at 1
+       return nil
+}
+
+func (d *device) Advertise(a *AdvPacket) error {
+       d.advData = &cmd.LESetAdvertisingData{
+               AdvertisingDataLength: uint8(a.Len()),
+               AdvertisingData:       a.Bytes(),
+       }
+
+       if err := d.update(); err != nil {
+               return err
+       }
+
+       return d.hci.SetAdvertiseEnable(true)
+}
+
+func (d *device) AdvertiseNameAndServices(name string, uu []UUID) error {
+       a := &AdvPacket{}
+       a.AppendFlags(flagGeneralDiscoverable | flagLEOnly)
+       a.AppendUUIDFit(uu)
+
+       if len(a.b)+len(name)+2 < MaxEIRPacketLength {
+               a.AppendName(name)
+               d.scanResp = nil
+       } else {
+               a := &AdvPacket{}
+               a.AppendName(name)
+               d.scanResp = &cmd.LESetScanResponseData{
+                       ScanResponseDataLength: uint8(a.Len()),
+                       ScanResponseData:       a.Bytes(),
+               }
+       }
+
+       return d.Advertise(a)
+}
+
+func (d *device) AdvertiseIBeaconData(b []byte) error {
+       a := &AdvPacket{}
+       a.AppendFlags(flagGeneralDiscoverable | flagLEOnly)
+       a.AppendManufacturerData(0x004C, b)
+       d.advData = &cmd.LESetAdvertisingData{
+               AdvertisingDataLength: uint8(a.Len()),
+               AdvertisingData:       a.Bytes(),
+       }
+
+       return d.Advertise(a)
+}
+
+func (d *device) AdvertiseIBeacon(u UUID, major, minor uint16, pwr int8) error 
{
+       b := make([]byte, 23)
+       b[0] = 0x02                               // Data type: iBeacon
+       b[1] = 0x15                               // Data length: 21 bytes
+       copy(b[2:], reverse(u.b))                 // Big endian
+       binary.BigEndian.PutUint16(b[18:], major) // Big endian
+       binary.BigEndian.PutUint16(b[20:], minor) // Big endian
+       b[22] = uint8(pwr)                        // Measured Tx Power
+       return d.AdvertiseIBeaconData(b)
+}
+
+func (d *device) StopAdvertising() error {
+       return d.hci.SetAdvertiseEnable(false)
+}
+
+func (d *device) Scan(ss []UUID, dup bool) {
+       // TODO: filter
+       d.hci.SetScanEnable(true, dup)
+}
+
+func (d *device) StopScanning() {
+       d.hci.SetScanEnable(false, true)
+}
+
+func (d *device) Connect(p Peripheral) {
+       d.hci.Connect(p.(*peripheral).pd)
+}
+
+func (d *device) CancelConnection(p Peripheral) {
+       d.hci.CancelConnection(p.(*peripheral).pd)
+}
+
+func (d *device) SendHCIRawCommand(c cmd.CmdParam) ([]byte, error) {
+       return d.hci.SendRawCommand(c)
+}
+
+// Flush pending advertising settings to the device.
+func (d *device) update() error {
+       if d.advParam != nil {
+               if err := d.hci.SendCmdWithAdvOff(d.advParam); err != nil {
+                       return err
+               }
+               d.advParam = nil
+       }
+       if d.scanResp != nil {
+               if err := d.hci.SendCmdWithAdvOff(d.scanResp); err != nil {
+                       return err
+               }
+               d.scanResp = nil
+       }
+       if d.advData != nil {
+               if err := d.hci.SendCmdWithAdvOff(d.advData); err != nil {
+                       return err
+               }
+               d.advData = nil
+       }
+       return nil
+}

Reply via email to