You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2017/03/06 21:44:30 UTC

[30/41] incubator-mynewt-newt git commit: MYNEWT-653 Use runtimeco gatt fork.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/hci.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/hci.go b/newtmgr/vendor/github.com/runtimeco/gatt/linux/hci.go
new file mode 100644
index 0000000..967680d
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/hci.go
@@ -0,0 +1,400 @@
+package linux
+
+import (
+	"fmt"
+	"io"
+	"log"
+	"sync"
+
+	"github.com/runtimeco/gatt/linux/cmd"
+	"github.com/runtimeco/gatt/linux/evt"
+)
+
+type HCI struct {
+	AcceptMasterHandler  func(pd *PlatData)
+	AcceptSlaveHandler   func(pd *PlatData)
+	AdvertisementHandler func(pd *PlatData)
+
+	d io.ReadWriteCloser
+	c *cmd.Cmd
+	e *evt.Evt
+
+	plist   map[bdaddr]*PlatData
+	plistmu *sync.Mutex
+
+	bufCnt  chan struct{}
+	bufSize int
+
+	maxConn int
+	connsmu *sync.Mutex
+	conns   map[uint16]*conn
+
+	adv   bool
+	advmu *sync.Mutex
+}
+
+type bdaddr [6]byte
+
+type PlatData struct {
+	Name        string
+	AddressType uint8
+	Address     [6]byte
+	Data        []byte
+	Connectable bool
+	RSSI        int8
+
+	Conn io.ReadWriteCloser
+}
+
+func NewHCI(devID int, chk bool, maxConn int) (*HCI, error) {
+	d, err := newDevice(devID, chk)
+	if err != nil {
+		return nil, err
+	}
+	c := cmd.NewCmd(d)
+	e := evt.NewEvt()
+
+	h := &HCI{
+		d: d,
+		c: c,
+		e: e,
+
+		plist:   make(map[bdaddr]*PlatData),
+		plistmu: &sync.Mutex{},
+
+		bufCnt:  make(chan struct{}, 15-1),
+		bufSize: 27,
+
+		maxConn: maxConn,
+		connsmu: &sync.Mutex{},
+		conns:   map[uint16]*conn{},
+
+		advmu: &sync.Mutex{},
+	}
+
+	e.HandleEvent(evt.LEMeta, evt.HandlerFunc(h.handleLEMeta))
+	e.HandleEvent(evt.DisconnectionComplete, evt.HandlerFunc(h.handleDisconnectionComplete))
+	e.HandleEvent(evt.NumberOfCompletedPkts, evt.HandlerFunc(h.handleNumberOfCompletedPkts))
+	e.HandleEvent(evt.CommandComplete, evt.HandlerFunc(c.HandleComplete))
+	e.HandleEvent(evt.CommandStatus, evt.HandlerFunc(c.HandleStatus))
+
+	go h.mainLoop()
+	h.resetDevice()
+	return h, nil
+}
+
+func (h *HCI) Close() error {
+	for _, c := range h.conns {
+		c.Close()
+	}
+	return h.d.Close()
+}
+
+func (h *HCI) SetAdvertiseEnable(en bool) error {
+	h.advmu.Lock()
+	h.adv = en
+	h.advmu.Unlock()
+	return h.setAdvertiseEnable(en)
+}
+
+func (h *HCI) setAdvertiseEnable(en bool) error {
+	h.advmu.Lock()
+	defer h.advmu.Unlock()
+	if en && h.adv && (len(h.conns) == h.maxConn) {
+		return nil
+	}
+	return h.c.SendAndCheckResp(
+		cmd.LESetAdvertiseEnable{
+			AdvertisingEnable: btoi(en),
+		}, []byte{0x00})
+}
+
+func (h *HCI) SendCmdWithAdvOff(c cmd.CmdParam) error {
+	h.setAdvertiseEnable(false)
+	err := h.c.SendAndCheckResp(c, nil)
+	if h.adv {
+		h.setAdvertiseEnable(true)
+	}
+	return err
+}
+
+func (h *HCI) SetScanEnable(en bool, dup bool) error {
+	return h.c.SendAndCheckResp(
+		cmd.LESetScanEnable{
+			LEScanEnable:     btoi(en),
+			FilterDuplicates: btoi(!dup),
+		}, []byte{0x00})
+}
+
+func (h *HCI) Connect(pd *PlatData) error {
+	h.c.Send(
+		cmd.LECreateConn{
+			LEScanInterval:        0x0004,         // N x 0.625ms
+			LEScanWindow:          0x0004,         // N x 0.625ms
+			InitiatorFilterPolicy: 0x00,           // white list not used
+			PeerAddressType:       pd.AddressType, // public or random
+			PeerAddress:           pd.Address,     //
+			OwnAddressType:        0x00,           // public
+			ConnIntervalMin:       6,         // N x 0.125ms
+			ConnIntervalMax:       7,         // N x 0.125ms
+			ConnLatency:           0x0000,         //
+			SupervisionTimeout:    0x00100,         // N x 10ms
+			MinimumCELength:       0x0000,         // N x 0.625ms
+			MaximumCELength:       0x0000,         // N x 0.625ms
+		})
+	return nil
+}
+
+func (h *HCI) CancelConnection(pd *PlatData) error {
+	return pd.Conn.Close()
+}
+
+func (h *HCI) SendRawCommand(c cmd.CmdParam) ([]byte, error) {
+	return h.c.Send(c)
+}
+
+func btoi(b bool) uint8 {
+	if b {
+		return 1
+	}
+	return 0
+}
+
+func (h *HCI) mainLoop() {
+	b := make([]byte, 4096)
+	for {
+		n, err := h.d.Read(b)
+		if err != nil {
+			return
+		}
+		if n == 0 {
+			return
+		}
+		p := make([]byte, n)
+		copy(p, b)
+		h.handlePacket(p)
+	}
+}
+
+func (h *HCI) handlePacket(b []byte) {
+	t, b := packetType(b[0]), b[1:]
+	var err error
+	switch t {
+	case typCommandPkt:
+		op := uint16(b[0]) | uint16(b[1])<<8
+		log.Printf("unmanaged cmd: opcode (%04x) [ % X ]\n", op, b)
+	case typACLDataPkt:
+		err = h.handleL2CAP(b)
+	case typSCODataPkt:
+		err = fmt.Errorf("SCO packet not supported")
+	case typEventPkt:
+		go func() {
+			err := h.e.Dispatch(b)
+			if err != nil {
+				log.Printf("hci: %s, [ % X]", err, b)
+			}
+		}()
+	case typVendorPkt:
+		err = fmt.Errorf("Vendor packet not supported")
+	default:
+		log.Fatalf("Unknown event: 0x%02X [ % X ]\n", t, b)
+	}
+	if err != nil {
+		log.Printf("hci: %s, [ % X]", err, b)
+	}
+}
+
+func (h *HCI) resetDevice() error {
+	seq := []cmd.CmdParam{
+		cmd.Reset{},
+		cmd.SetEventMask{EventMask: 0x3dbff807fffbffff},
+		cmd.LESetEventMask{LEEventMask: 0x000000000000001F},
+		cmd.WriteSimplePairingMode{SimplePairingMode: 1},
+		cmd.WriteLEHostSupported{LESupportedHost: 1, SimultaneousLEHost: 0},
+		cmd.WriteInquiryMode{InquiryMode: 2},
+		cmd.WritePageScanType{PageScanType: 1},
+		cmd.WriteInquiryScanType{ScanType: 1},
+		cmd.WriteClassOfDevice{ClassOfDevice: [3]byte{0x40, 0x02, 0x04}},
+		cmd.WritePageTimeout{PageTimeout: 0x2000},
+		cmd.WriteDefaultLinkPolicy{DefaultLinkPolicySettings: 0x5},
+		cmd.HostBufferSize{
+			HostACLDataPacketLength:            0x1000,
+			HostSynchronousDataPacketLength:    0xff,
+			HostTotalNumACLDataPackets:         0x0014,
+			HostTotalNumSynchronousDataPackets: 0x000a},
+		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.
+		},
+	}
+	for _, s := range seq {
+		if err := h.c.SendAndCheckResp(s, []byte{0x00}); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (h *HCI) handleAdvertisement(b []byte) {
+	// If no one is interested, don't bother.
+	if h.AdvertisementHandler == nil {
+		return
+	}
+	ep := &evt.LEAdvertisingReportEP{}
+	if err := ep.Unmarshal(b); err != nil {
+		return
+	}
+	for i := 0; i < int(ep.NumReports); i++ {
+		addr := bdaddr(ep.Address[i])
+		et := ep.EventType[i]
+		connectable := et == advInd || et == advDirectInd
+		scannable := et == advInd || et == advScanInd
+
+		if et == scanRsp {
+			h.plistmu.Lock()
+			pd, ok := h.plist[addr]
+			h.plistmu.Unlock()
+			if ok {
+				pd.Data = append(pd.Data, ep.Data[i]...)
+				h.AdvertisementHandler(pd)
+			}
+			continue
+		}
+
+		pd := &PlatData{
+			AddressType: ep.AddressType[i],
+			Address:     ep.Address[i],
+			Data:        ep.Data[i],
+			Connectable: connectable,
+			RSSI:        ep.RSSI[i],
+		}
+		h.plistmu.Lock()
+		h.plist[addr] = pd
+		h.plistmu.Unlock()
+		if scannable {
+			continue
+		}
+		h.AdvertisementHandler(pd)
+	}
+}
+
+func (h *HCI) handleNumberOfCompletedPkts(b []byte) error {
+	ep := &evt.NumberOfCompletedPktsEP{}
+	if err := ep.Unmarshal(b); err != nil {
+		return err
+	}
+	for _, r := range ep.Packets {
+		for i := 0; i < int(r.NumOfCompletedPkts); i++ {
+			<-h.bufCnt
+		}
+	}
+	return nil
+}
+
+func (h *HCI) handleConnection(b []byte) {
+	ep := &evt.LEConnectionCompleteEP{}
+	if err := ep.Unmarshal(b); err != nil {
+		return // FIXME
+	}
+	hh := ep.ConnectionHandle
+	c := newConn(h, hh)
+	h.connsmu.Lock()
+	h.conns[hh] = c
+	h.connsmu.Unlock()
+	h.setAdvertiseEnable(true)
+
+	// FIXME: sloppiness. This call should be called by the package user once we
+	// flesh out the support of l2cap signaling packets (CID:0x0001,0x0005)
+	if ep.ConnLatency != 0 || ep.ConnInterval > 0x18 {
+		c.updateConnection()
+	}
+
+	// master connection
+	if ep.Role == 0x01 {
+		pd := &PlatData{
+			Address: ep.PeerAddress,
+			Conn:    c,
+		}
+		h.AcceptMasterHandler(pd)
+		return
+	}
+	h.plistmu.Lock()
+	pd := h.plist[ep.PeerAddress]
+	h.plistmu.Unlock()
+	pd.Conn = c
+	h.AcceptSlaveHandler(pd)
+}
+
+func (h *HCI) handleDisconnectionComplete(b []byte) error {
+	ep := &evt.DisconnectionCompleteEP{}
+	if err := ep.Unmarshal(b); err != nil {
+		return err
+	}
+	hh := ep.ConnectionHandle
+	h.connsmu.Lock()
+	defer h.connsmu.Unlock()
+	c, found := h.conns[hh]
+	if !found {
+		// should not happen, just be cautious for now.
+		log.Printf("l2conn: disconnecting a disconnected 0x%04X connection", hh)
+		return nil
+	}
+	delete(h.conns, hh)
+	close(c.aclc)
+	h.setAdvertiseEnable(true)
+	return nil
+}
+
+func (h *HCI) handleLEMeta(b []byte) error {
+	code := evt.LEEventCode(b[0])
+	switch code {
+	case evt.LEConnectionComplete:
+		go h.handleConnection(b)
+	case evt.LEConnectionUpdateComplete:
+		// anything to do here?
+	case evt.LEAdvertisingReport:
+		go h.handleAdvertisement(b)
+	// case evt.LEReadRemoteUsedFeaturesComplete:
+	// case evt.LELTKRequest:
+	// case evt.LERemoteConnectionParameterRequest:
+	default:
+		return fmt.Errorf("Unhandled LE event: %s, [ % X ]", code, b)
+	}
+	return nil
+}
+
+func (h *HCI) handleL2CAP(b []byte) error {
+        a := &aclData{}
+	if err := a.unmarshal(b); err != nil {
+		return err
+	}
+	h.connsmu.Lock()
+	defer h.connsmu.Unlock()
+	c, found := h.conns[a.attr]
+
+        if a.flags != 0x002 {
+	    if !found {
+		    // should not happen, just be cautious for now.
+		    log.Printf("l2conn: got data for disconnected handle: 0x%04x", a.attr)
+		    return nil
+	        if len(a.b) < 4 {
+		    log.Printf("l2conn: l2cap packet is too short/corrupt, length is %d", len(a.b))
+		    return nil
+	        }
+	        cid := uint16(a.b[2]) | (uint16(a.b[3]) << 8)
+	        if cid == 5 {
+		    c.handleSignal(a)
+		    return nil
+	        }
+            }
+        }
+	c.aclc <- a
+	return nil
+}
+
+func (h *HCI) trace(fmt string, v ...interface{}) {
+	log.Printf(fmt, v)
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/l2cap.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/l2cap.go b/newtmgr/vendor/github.com/runtimeco/gatt/linux/l2cap.go
new file mode 100644
index 0000000..daca82f
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/l2cap.go
@@ -0,0 +1,174 @@
+package linux
+
+import (
+	"fmt"
+	"io"
+	"log"
+
+	"github.com/runtimeco/gatt/linux/cmd"
+)
+
+type aclData struct {
+	attr  uint16
+	flags uint8
+	dlen  uint16
+	b     []byte
+}
+
+func (a *aclData) unmarshal(b []byte) error {
+	if len(b) < 4 {
+		return fmt.Errorf("malformed acl packet")
+	}
+	attr := uint16(b[0]) | (uint16(b[1]&0x0f) << 8)
+	flags := b[1] >> 4
+	dlen := uint16(b[2]) | (uint16(b[3]) << 8)
+	if len(b) != 4+int(dlen) {
+		return fmt.Errorf("malformed acl packet")
+	}
+
+	*a = aclData{attr: attr, flags: flags, dlen: dlen, b: b[4:]}
+	return nil
+}
+
+type conn struct {
+	hci  *HCI
+	attr uint16
+	aclc chan *aclData
+}
+
+func newConn(hci *HCI, hh uint16) *conn {
+	return &conn{
+		hci:  hci,
+		attr: hh,
+		aclc: make(chan *aclData),
+	}
+}
+
+func (c *conn) updateConnection() (int, error) {
+	b := []byte{
+		0x12,       // Code (Connection Param Update)
+		0x02,       // ID
+		0x08, 0x00, // DataLength
+		0x08, 0x00, // IntervalMin
+		0x18, 0x00, // IntervalMax
+		0x00, 0x00, // SlaveLatency
+		0xC8, 0x00} // TimeoutMultiplier
+	return c.write(0x05, b)
+}
+
+// write writes the l2cap payload to the controller.
+// It first prepend the l2cap header (4-bytes), and diassemble the payload
+// if it is larger than the HCI LE buffer size that the conntroller can support.
+func (c *conn) write(cid int, b []byte) (int, error) {
+	flag := uint8(0) // ACL data continuation flag
+	tlen := len(b)   // Total length of the l2cap payload
+
+	// log.Printf("W: [ % X ]", b)
+	w := append(
+		[]byte{
+			0,    // packet type
+			0, 0, // attr
+			0, 0, // dlen
+			uint8(tlen), uint8(tlen >> 8), // l2cap header
+			uint8(cid), uint8(cid >> 8), // l2cap header
+		}, b...)
+
+	n := 4 + tlen // l2cap header + l2cap payload
+	for n > 0 {
+		dlen := n
+		if dlen > c.hci.bufSize {
+			dlen = c.hci.bufSize
+		}
+		w[0] = 0x02 // packetTypeACL
+		w[1] = uint8(c.attr)
+		w[2] = uint8(c.attr>>8) | flag
+		w[3] = uint8(dlen)
+		w[4] = uint8(dlen >> 8)
+
+		// make sure we don't send more buffers than the controller can handdle
+		c.hci.bufCnt <- struct{}{}
+
+		c.hci.d.Write(w[:5+dlen])
+		w = w[dlen:] // advance the pointer to the next segment, if any.
+		flag = 0x10  // the rest of iterations attr continued segments, if any.
+		n -= dlen
+	}
+
+	return len(b), nil
+}
+
+func (c *conn) Read(b []byte) (int, error) {
+	a, ok := <-c.aclc
+	if !ok {
+		return 0, io.EOF
+	}
+	tlen := int(uint16(a.b[0]) | uint16(a.b[1])<<8)
+	if tlen > len(b) {
+		return 0, io.ErrShortBuffer
+	}
+	d := a.b[4:] // skip l2cap header
+	copy(b, d)
+	n := len(d)
+
+	// Keep receiving and reassemble continued l2cap segments
+	for n != tlen {
+		if a, ok = <-c.aclc; !ok || (a.flags&0x1) == 0 {
+			return n, io.ErrUnexpectedEOF
+		}
+		copy(b[n:], a.b)
+		n += len(a.b)
+	}
+	// log.Printf("R: [ % X ]", b[:n])
+	return n, nil
+}
+
+func (c *conn) Write(b []byte) (int, error) {
+	return c.write(0x04, b)
+}
+
+// Close disconnects the connection by sending HCI disconnect command to the device.
+func (c *conn) Close() error {
+	h := c.hci
+	hh := c.attr
+	h.connsmu.Lock()
+	defer h.connsmu.Unlock()
+	_, found := h.conns[hh]
+	if !found {
+		// log.Printf("l2conn: 0x%04x already disconnected", hh)
+		return nil
+	}
+	if err, _ := h.c.Send(cmd.Disconnect{ConnectionHandle: hh, Reason: 0x13}); err != nil {
+		return fmt.Errorf("l2conn: failed to disconnect, %s", err)
+	}
+	return nil
+}
+
+// Signal Packets
+// 0x00 Reserved								Any
+// 0x01 Command reject							0x0001 and 0x0005
+// 0x02 Connection request						0x0001
+// 0x03 Connection response 					0x0001
+// 0x04 Configure request						0x0001
+// 0x05 Configure response						0x0001
+// 0x06 Disconnection request					0x0001 and 0x0005
+// 0x07 Disconnection response					0x0001 and 0x0005
+// 0x08 Echo request							0x0001
+// 0x09 Echo response							0x0001
+// 0x0A Information request						0x0001
+// 0x0B Information response					0x0001
+// 0x0C Create Channel request					0x0001
+// 0x0D Create Channel response					0x0001
+// 0x0E Move Channel request					0x0001
+// 0x0F Move Channel response					0x0001
+// 0x10 Move Channel Confirmation				0x0001
+// 0x11 Move Channel Confirmation response		0x0001
+// 0x12 Connection Parameter Update request		0x0005
+// 0x13 Connection Parameter Update response	0x0005
+// 0x14 LE Credit Based Connection request		0x0005
+// 0x15 LE Credit Based Connection response		0x0005
+// 0x16 LE Flow Control Credit					0x0005
+func (c *conn) handleSignal(a *aclData) error {
+	log.Printf("ignore l2cap signal:[ % X ]", a.b)
+	// FIXME: handle LE signaling channel (CID: 5)
+	return nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/asm.s
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/asm.s b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/asm.s
new file mode 100644
index 0000000..d4ca868
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/asm.s
@@ -0,0 +1,8 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT �use(SB),NOSPLIT,$0
+	RET

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/asm_linux_386.s
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/asm_linux_386.s b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/asm_linux_386.s
new file mode 100644
index 0000000..5d3ad9a
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/asm_linux_386.s
@@ -0,0 +1,33 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+//
+// System calls for 386, Linux
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	�Syscall(SB),NOSPLIT,$0-28
+	JMP	syscall�Syscall(SB)
+
+TEXT	�Syscall6(SB),NOSPLIT,$0-40
+	JMP	syscall�Syscall6(SB)
+
+TEXT �RawSyscall(SB),NOSPLIT,$0-28
+	JMP	syscall�RawSyscall(SB)
+
+TEXT	�RawSyscall6(SB),NOSPLIT,$0-40
+	JMP	syscall�RawSyscall6(SB)
+
+TEXT �socketcall(SB),NOSPLIT,$0-36
+	JMP	syscall�socketcall(SB)
+
+TEXT �rawsocketcall(SB),NOSPLIT,$0-36
+	JMP	syscall�rawsocketcall(SB)
+
+TEXT �seek(SB),NOSPLIT,$0-28
+	JMP	syscall�seek(SB)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket.go b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket.go
new file mode 100644
index 0000000..ffc49a6
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket.go
@@ -0,0 +1,121 @@
+// Package socket implements a minimal set of function of the HCI Socket,
+// which is not yet supported by the Go standard library. Most of the code
+// follow suit the existing code in the standard library. Once it gets
+// supported officially, we can get rid of this package entirely.
+
+package socket
+
+import (
+	"errors"
+	"syscall"
+	"time"
+	"unsafe"
+)
+
+// Bluetooth Protocols
+const (
+	BTPROTO_L2CAP  = 0
+	BTPROTO_HCI    = 1
+	BTPROTO_SCO    = 2
+	BTPROTO_RFCOMM = 3
+	BTPROTO_BNEP   = 4
+	BTPROTO_CMTP   = 5
+	BTPROTO_HIDP   = 6
+	BTPROTO_AVDTP  = 7
+)
+
+const (
+	HCI_CHANNEL_RAW     = 0
+	HCI_CHANNEL_USER    = 1
+	HCI_CHANNEL_MONITOR = 2
+	HCI_CHANNEL_CONTROL = 3
+)
+
+var (
+	ErrSocketOpenFailed  = errors.New("unable to open bluetooth socket to device")
+	ErrSocketBindTimeout = errors.New("timeout occured binding to bluetooth device")
+)
+
+type _Socklen uint32
+
+type Sockaddr interface {
+	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
+}
+
+type rawSockaddrHCI struct {
+	Family  uint16
+	Dev     uint16
+	Channel uint16
+}
+
+type SockaddrHCI struct {
+	Dev     int
+	Channel uint16
+	raw     rawSockaddrHCI
+}
+
+const sizeofSockaddrHCI = unsafe.Sizeof(rawSockaddrHCI{})
+
+func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Dev < 0 || sa.Dev > 0xFFFF {
+		return nil, 0, syscall.EINVAL
+	}
+	if sa.Channel < 0 || sa.Channel > 0xFFFF {
+		return nil, 0, syscall.EINVAL
+	}
+	sa.raw.Family = AF_BLUETOOTH
+	sa.raw.Dev = uint16(sa.Dev)
+	sa.raw.Channel = sa.Channel
+	return unsafe.Pointer(&sa.raw), _Socklen(sizeofSockaddrHCI), nil
+}
+
+func Socket(domain, typ, proto int) (int, error) {
+	for i := 0; i < 5; i++ {
+		if fd, err := syscall.Socket(domain, typ, proto); err == nil || err != syscall.EBUSY {
+			return fd, err
+		}
+		time.Sleep(time.Second)
+	}
+	return 0, ErrSocketOpenFailed
+}
+
+func Bind(fd int, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	for i := 0; i < 5; i++ {
+		if err = bind(fd, ptr, n); err == nil || err != syscall.EBUSY {
+			return err
+		}
+		time.Sleep(time.Second)
+	}
+	return ErrSocketBindTimeout
+}
+
+// Socket Level
+const (
+	SOL_HCI    = 0
+	SOL_L2CAP  = 6
+	SOL_SCO    = 17
+	SOL_RFCOMM = 18
+
+	SOL_BLUETOOTH = 274
+)
+
+// HCI Socket options
+const (
+	HCI_DATA_DIR   = 1
+	HCI_FILTER     = 2
+	HCI_TIME_STAMP = 3
+)
+
+type HCIFilter struct {
+	TypeMask  uint32
+	EventMask [2]uint32
+	opcode    uint16
+}
+
+func SetsockoptFilter(fd int, f *HCIFilter) (err error) {
+	return setsockopt(fd, SOL_HCI, HCI_FILTER, unsafe.Pointer(f), unsafe.Sizeof(*f))
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_common.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_common.go b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_common.go
new file mode 100644
index 0000000..b01ceeb
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_common.go
@@ -0,0 +1,24 @@
+// +build !386
+
+package socket
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := syscall.Syscall(syscall.SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_darwin.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_darwin.go b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_darwin.go
new file mode 100644
index 0000000..abb96a5
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_darwin.go
@@ -0,0 +1,6 @@
+// +build darwin
+
+package socket
+
+// For compile time compatibility
+const AF_BLUETOOTH = 0

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_linux.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_linux.go b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_linux.go
new file mode 100644
index 0000000..4793915
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_linux.go
@@ -0,0 +1,7 @@
+// +build linux
+
+package socket
+
+import "syscall"
+
+const AF_BLUETOOTH = syscall.AF_BLUETOOTH

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_linux_386.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_linux_386.go b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_linux_386.go
new file mode 100644
index 0000000..05ca65c
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/socket/socket_linux_386.go
@@ -0,0 +1,31 @@
+// +build linux,386
+
+package socket
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const (
+	BIND         = 2
+	SETSOCKETOPT = 14
+)
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, e1 := socketcall(BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, e1 := socketcall(SETSOCKETOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/linux/util/util.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/linux/util/util.go b/newtmgr/vendor/github.com/runtimeco/gatt/linux/util/util.go
new file mode 100644
index 0000000..4933008
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/linux/util/util.go
@@ -0,0 +1,16 @@
+package util
+
+import "encoding/binary"
+
+type order struct{ binary.ByteOrder }
+
+var Order = order{binary.LittleEndian}
+
+func (o order) Int8(b []byte) int8   { return int8(b[0]) }
+func (o order) Uint8(b []byte) uint8 { return b[0] }
+func (o order) MAC(b []byte) [6]byte { return [6]byte{b[5], b[4], b[3], b[2], b[1], b[0]} }
+
+func (o order) PutUint8(b []byte, v uint8) { b[0] = v }
+func (o order) PutMAC(b []byte, m [6]byte) {
+	b[0], b[1], b[2], b[3], b[4], b[5] = m[5], m[4], m[3], m[2], m[1], m[0]
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/option_darwin.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/option_darwin.go b/newtmgr/vendor/github.com/runtimeco/gatt/option_darwin.go
new file mode 100644
index 0000000..617db21
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/option_darwin.go
@@ -0,0 +1,15 @@
+package gatt
+
+const (
+	CentralManager    = 0 // Client functions (default)
+	PeripheralManager = 1 // Server functions
+)
+
+// MacDeviceRole specify the XPC connection type to connect blued.
+// THis option can only be used with NewDevice on OS X implementation.
+func MacDeviceRole(r int) Option {
+	return func(d Device) error {
+		d.(*device).role = r
+		return nil
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/option_linux.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/option_linux.go b/newtmgr/vendor/github.com/runtimeco/gatt/option_linux.go
new file mode 100644
index 0000000..bf2360c
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/option_linux.go
@@ -0,0 +1,87 @@
+package gatt
+
+import (
+	"errors"
+	"io"
+
+	"github.com/runtimeco/gatt/linux/cmd"
+)
+
+// LnxDeviceID specifies which HCI device to use.
+// If n is set to -1, all the available HCI devices will be probed.
+// If chk is set to true, LnxDeviceID checks the LE support in the feature list of the HCI device.
+// This is to filter devices that does not support LE. In case some LE driver that doesn't correctly
+// set the LE support in its feature list, user can turn off the check.
+// This option can only be used with NewDevice on Linux implementation.
+func LnxDeviceID(n int, chk bool) Option {
+	return func(d Device) error {
+		d.(*device).devID = n
+		d.(*device).chkLE = chk
+		return nil
+	}
+}
+
+// LnxMaxConnections is an optional parameter.
+// If set, it overrides the default max connections supported.
+// This option can only be used with NewDevice on Linux implementation.
+func LnxMaxConnections(n int) Option {
+	return func(d Device) error {
+		d.(*device).maxConn = n
+		return nil
+	}
+}
+
+// LnxSetAdvertisingEnable sets the advertising data to the HCI device.
+// This option can be used with Option on Linux implementation.
+func LnxSetAdvertisingEnable(en bool) Option {
+	return func(d Device) error {
+		dd := d.(*device)
+		if dd == nil {
+			return errors.New("device is not initialized")
+		}
+		if err := dd.update(); err != nil {
+			return err
+		}
+		return dd.hci.SetAdvertiseEnable(en)
+	}
+}
+
+// LnxSetAdvertisingData sets the advertising data to the HCI device.
+// This option can be used with NewDevice or Option on Linux implementation.
+func LnxSetAdvertisingData(c *cmd.LESetAdvertisingData) Option {
+	return func(d Device) error {
+		d.(*device).advData = c
+		return nil
+	}
+}
+
+// LnxSetScanResponseData sets the scan response data to the HXI device.
+// This option can be used with NewDevice or Option on Linux implementation.
+func LnxSetScanResponseData(c *cmd.LESetScanResponseData) Option {
+	return func(d Device) error {
+		d.(*device).scanResp = c
+		return nil
+	}
+}
+
+// LnxSetAdvertisingParameters sets the advertising parameters to the HCI device.
+// This option can be used with NewDevice or Option on Linux implementation.
+func LnxSetAdvertisingParameters(c *cmd.LESetAdvertisingParameters) Option {
+	return func(d Device) error {
+		d.(*device).advParam = c
+		return nil
+	}
+}
+
+// LnxSendHCIRawCommand sends a raw command to the HCI device
+// This option can be used with NewDevice or Option on Linux implementation.
+func LnxSendHCIRawCommand(c cmd.CmdParam, rsp io.Writer) Option {
+	return func(d Device) error {
+		b, err := d.(*device).SendHCIRawCommand(c)
+		if rsp == nil {
+			return err
+		}
+		rsp.Write(b)
+		return err
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/peripheral.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/peripheral.go b/newtmgr/vendor/github.com/runtimeco/gatt/peripheral.go
new file mode 100644
index 0000000..36ad578
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/peripheral.go
@@ -0,0 +1,102 @@
+package gatt
+
+import (
+	"errors"
+	"sync"
+)
+
+// Peripheral is the interface that represent a remote peripheral device.
+type Peripheral interface {
+	// Device returns the underlying device.
+	Device() Device
+
+	// ID is the platform specific unique ID of the remote peripheral, e.g. MAC for Linux, Peripheral UUID for MacOS.
+	ID() string
+
+	// Name returns the name of the remote peripheral.
+	// This can be the advertised name, if exists, or the GAP device name, which takes priority
+	Name() string
+
+	// Services returnns the services of the remote peripheral which has been discovered.
+	Services() []*Service
+
+	// DiscoverServices discover the specified services of the remote peripheral.
+	// If the specified services is set to nil, all the available services of the remote peripheral are returned.
+	DiscoverServices(s []UUID) ([]*Service, error)
+
+	// DiscoverIncludedServices discovers the specified included services of a service.
+	// If the specified services is set to nil, all the included services of the service are returned.
+	DiscoverIncludedServices(ss []UUID, s *Service) ([]*Service, error)
+
+	// DiscoverCharacteristics discovers the specified characteristics of a service.
+	// If the specified characterstics is set to nil, all the characteristic of the service are returned.
+	DiscoverCharacteristics(c []UUID, s *Service) ([]*Characteristic, error)
+
+	// DiscoverDescriptors discovers the descriptors of a characteristic.
+	// If the specified descriptors is set to nil, all the descriptors of the characteristic are returned.
+	DiscoverDescriptors(d []UUID, c *Characteristic) ([]*Descriptor, error)
+
+	// ReadCharacteristic retrieves the value of a specified characteristic.
+	ReadCharacteristic(c *Characteristic) ([]byte, error)
+
+	// ReadLongCharacteristic retrieves the value of a specified characteristic that is longer than the
+	// MTU.
+	ReadLongCharacteristic(c *Characteristic) ([]byte, error)
+
+	// ReadDescriptor retrieves the value of a specified characteristic descriptor.
+	ReadDescriptor(d *Descriptor) ([]byte, error)
+
+	// WriteCharacteristic writes the value of a characteristic.
+	WriteCharacteristic(c *Characteristic, b []byte, noRsp bool) error
+
+	// WriteDescriptor writes the value of a characteristic descriptor.
+	WriteDescriptor(d *Descriptor, b []byte) error
+
+	// SetNotifyValue sets notifications for the value of a specified characteristic.
+	SetNotifyValue(c *Characteristic, f func(*Characteristic, []byte, error)) error
+
+	// SetIndicateValue sets indications for the value of a specified characteristic.
+	SetIndicateValue(c *Characteristic, f func(*Characteristic, []byte, error)) error
+
+	// ReadRSSI retrieves the current RSSI value for the remote peripheral.
+	ReadRSSI() int
+
+	// SetMTU sets the mtu for the remote peripheral.
+	SetMTU(mtu uint16) error
+}
+
+type subscriber struct {
+	sub map[uint16]subscribefn
+	mu  *sync.Mutex
+}
+
+type subscribefn func([]byte, error)
+
+func newSubscriber() *subscriber {
+	return &subscriber{
+		sub: make(map[uint16]subscribefn),
+		mu:  &sync.Mutex{},
+	}
+}
+
+func (s *subscriber) subscribe(h uint16, f subscribefn) {
+	s.mu.Lock()
+	s.sub[h] = f
+	s.mu.Unlock()
+}
+
+func (s *subscriber) unsubscribe(h uint16) {
+	s.mu.Lock()
+	delete(s.sub, h)
+	s.mu.Unlock()
+}
+
+func (s *subscriber) fn(h uint16) subscribefn {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	return s.sub[h]
+}
+
+var (
+	ErrInvalidLength = errors.New("invalid length")
+)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/peripheral_darwin.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/peripheral_darwin.go b/newtmgr/vendor/github.com/runtimeco/gatt/peripheral_darwin.go
new file mode 100644
index 0000000..9174e61
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/peripheral_darwin.go
@@ -0,0 +1,277 @@
+package gatt
+
+import (
+	"errors"
+	"log"
+
+	"github.com/runtimeco/gatt/xpc"
+)
+
+type peripheral struct {
+	// NameChanged is called whenever the peripheral GAP Device name has changed.
+	NameChanged func(Peripheral)
+
+	// ServicesModified is called when one or more service of a peripheral have changed.
+	// A list of invalid service is provided in the parameter.
+	ServicesModified func(Peripheral, []*Service)
+
+	d    *device
+	svcs []*Service
+
+	sub *subscriber
+
+	id   xpc.UUID
+	name string
+
+	reqc  chan message
+	rspc  chan message
+	quitc chan struct{}
+}
+
+func NewPeripheral(u UUID) Peripheral { return &peripheral{id: xpc.UUID(u.b)} }
+
+func (p *peripheral) Device() Device       { return p.d }
+func (p *peripheral) ID() string           { return p.id.String() }
+func (p *peripheral) Name() string         { return p.name }
+func (p *peripheral) Services() []*Service { return p.svcs }
+
+func (p *peripheral) DiscoverServices(ss []UUID) ([]*Service, error) {
+	rsp := p.sendReq(45, xpc.Dict{
+		"kCBMsgArgDeviceUUID": p.id,
+		"kCBMsgArgUUIDs":      uuidSlice(ss),
+	})
+	if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+		return nil, attEcode(res)
+	}
+	svcs := []*Service{}
+	for _, xss := range rsp["kCBMsgArgServices"].(xpc.Array) {
+		xs := xss.(xpc.Dict)
+		u := MustParseUUID(xs.MustGetHexBytes("kCBMsgArgUUID"))
+		h := uint16(xs.MustGetInt("kCBMsgArgServiceStartHandle"))
+		endh := uint16(xs.MustGetInt("kCBMsgArgServiceEndHandle"))
+		svcs = append(svcs, &Service{uuid: u, h: h, endh: endh})
+	}
+	p.svcs = svcs
+	return svcs, nil
+}
+
+func (p *peripheral) DiscoverIncludedServices(ss []UUID, s *Service) ([]*Service, error) {
+	rsp := p.sendReq(60, xpc.Dict{
+		"kCBMsgArgDeviceUUID":         p.id,
+		"kCBMsgArgServiceStartHandle": s.h,
+		"kCBMsgArgServiceEndHandle":   s.endh,
+		"kCBMsgArgUUIDs":              uuidSlice(ss),
+	})
+	if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+		return nil, attEcode(res)
+	}
+	// TODO
+	return nil, notImplemented
+}
+
+func (p *peripheral) DiscoverCharacteristics(cs []UUID, s *Service) ([]*Characteristic, error) {
+	rsp := p.sendReq(62, xpc.Dict{
+		"kCBMsgArgDeviceUUID":         p.id,
+		"kCBMsgArgServiceStartHandle": s.h,
+		"kCBMsgArgServiceEndHandle":   s.endh,
+		"kCBMsgArgUUIDs":              uuidSlice(cs),
+	})
+	if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+		return nil, attEcode(res)
+	}
+	for _, xcs := range rsp.MustGetArray("kCBMsgArgCharacteristics") {
+		xc := xcs.(xpc.Dict)
+		u := MustParseUUID(xc.MustGetHexBytes("kCBMsgArgUUID"))
+		ch := uint16(xc.MustGetInt("kCBMsgArgCharacteristicHandle"))
+		vh := uint16(xc.MustGetInt("kCBMsgArgCharacteristicValueHandle"))
+		props := Property(xc.MustGetInt("kCBMsgArgCharacteristicProperties"))
+		c := &Characteristic{uuid: u, svc: s, props: props, h: ch, vh: vh}
+		s.chars = append(s.chars, c)
+	}
+	return s.chars, nil
+}
+
+func (p *peripheral) DiscoverDescriptors(ds []UUID, c *Characteristic) ([]*Descriptor, error) {
+	rsp := p.sendReq(70, xpc.Dict{
+		"kCBMsgArgDeviceUUID":                p.id,
+		"kCBMsgArgCharacteristicHandle":      c.h,
+		"kCBMsgArgCharacteristicValueHandle": c.vh,
+		"kCBMsgArgUUIDs":                     uuidSlice(ds),
+	})
+	for _, xds := range rsp.MustGetArray("kCBMsgArgDescriptors") {
+		xd := xds.(xpc.Dict)
+		u := MustParseUUID(xd.MustGetHexBytes("kCBMsgArgUUID"))
+		h := uint16(xd.MustGetInt("kCBMsgArgDescriptorHandle"))
+		d := &Descriptor{uuid: u, char: c, h: h}
+		c.descs = append(c.descs, d)
+	}
+	return c.descs, nil
+}
+
+func (p *peripheral) ReadCharacteristic(c *Characteristic) ([]byte, error) {
+	rsp := p.sendReq(65, xpc.Dict{
+		"kCBMsgArgDeviceUUID":                p.id,
+		"kCBMsgArgCharacteristicHandle":      c.h,
+		"kCBMsgArgCharacteristicValueHandle": c.vh,
+	})
+	if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+		return nil, attEcode(res)
+	}
+	b := rsp.MustGetBytes("kCBMsgArgData")
+	return b, nil
+}
+
+func (p *peripheral) ReadLongCharacteristic(c *Characteristic) ([]byte, error) {
+	return nil, errors.New("Not implemented")
+}
+
+func (p *peripheral) WriteCharacteristic(c *Characteristic, b []byte, noRsp bool) error {
+	args := xpc.Dict{
+		"kCBMsgArgDeviceUUID":                p.id,
+		"kCBMsgArgCharacteristicHandle":      c.h,
+		"kCBMsgArgCharacteristicValueHandle": c.vh,
+		"kCBMsgArgData":                      b,
+		"kCBMsgArgType":                      map[bool]int{false: 0, true: 1}[noRsp],
+	}
+	if noRsp {
+		p.sendCmd(66, args)
+		return nil
+	}
+	rsp := p.sendReq(65, args)
+	if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+		return attEcode(res)
+	}
+	return nil
+}
+
+func (p *peripheral) ReadDescriptor(d *Descriptor) ([]byte, error) {
+	rsp := p.sendReq(77, xpc.Dict{
+		"kCBMsgArgDeviceUUID":       p.id,
+		"kCBMsgArgDescriptorHandle": d.h,
+	})
+	if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+		return nil, attEcode(res)
+	}
+	b := rsp.MustGetBytes("kCBMsgArgData")
+	return b, nil
+}
+
+func (p *peripheral) WriteDescriptor(d *Descriptor, b []byte) error {
+	rsp := p.sendReq(78, xpc.Dict{
+		"kCBMsgArgDeviceUUID":       p.id,
+		"kCBMsgArgDescriptorHandle": d.h,
+		"kCBMsgArgData":             b,
+	})
+	if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+		return attEcode(res)
+	}
+	return nil
+}
+
+func (p *peripheral) SetNotifyValue(c *Characteristic, f func(*Characteristic, []byte, error)) error {
+	set := 1
+	if f == nil {
+		set = 0
+	}
+	// To avoid race condition, registeration is handled before requesting the server.
+	if f != nil {
+		// Note: when notified, core bluetooth reports characteristic handle, not value's handle.
+		p.sub.subscribe(c.h, func(b []byte, err error) { f(c, b, err) })
+	}
+	rsp := p.sendReq(68, xpc.Dict{
+		"kCBMsgArgDeviceUUID":                p.id,
+		"kCBMsgArgCharacteristicHandle":      c.h,
+		"kCBMsgArgCharacteristicValueHandle": c.vh,
+		"kCBMsgArgState":                     set,
+	})
+	if res := rsp.MustGetInt("kCBMsgArgResult"); res != 0 {
+		return attEcode(res)
+	}
+	// To avoid race condition, unregisteration is handled after server responses.
+	if f == nil {
+		p.sub.unsubscribe(c.h)
+	}
+	return nil
+}
+
+func (p *peripheral) SetIndicateValue(c *Characteristic,
+	f func(*Characteristic, []byte, error)) error {
+	// TODO: Implement set indications logic for darwin (https://github.com/runtimeco/gatt/issues/32)
+	return nil
+}
+
+func (p *peripheral) ReadRSSI() int {
+	rsp := p.sendReq(43, xpc.Dict{"kCBMsgArgDeviceUUID": p.id})
+	return rsp.MustGetInt("kCBMsgArgData")
+}
+
+func (p *peripheral) SetMTU(mtu uint16) error {
+	return errors.New("Not implemented")
+}
+
+func uuidSlice(uu []UUID) [][]byte {
+	us := [][]byte{}
+	for _, u := range uu {
+		us = append(us, reverse(u.b))
+	}
+	return us
+}
+
+type message struct {
+	id   int
+	args xpc.Dict
+	rspc chan xpc.Dict
+}
+
+func (p *peripheral) sendCmd(id int, args xpc.Dict) {
+	p.reqc <- message{id: id, args: args}
+}
+
+func (p *peripheral) sendReq(id int, args xpc.Dict) xpc.Dict {
+	m := message{id: id, args: args, rspc: make(chan xpc.Dict)}
+	p.reqc <- m
+	return <-m.rspc
+}
+
+func (p *peripheral) loop() {
+	rspc := make(chan message)
+
+	go func() {
+		for {
+			select {
+			case req := <-p.reqc:
+				p.d.sendCBMsg(req.id, req.args)
+				if req.rspc == nil {
+					break
+				}
+				m := <-rspc
+				req.rspc <- m.args
+			case <-p.quitc:
+				return
+			}
+		}
+	}()
+
+	for {
+		select {
+		case rsp := <-p.rspc:
+			// Notification
+			if rsp.id == 71 && rsp.args.GetInt("kCBMsgArgIsNotification", 0) != 0 {
+				// While we're notified with the value's handle, blued reports the characteristic handle.
+				ch := uint16(rsp.args.MustGetInt("kCBMsgArgCharacteristicHandle"))
+				b := rsp.args.MustGetBytes("kCBMsgArgData")
+				f := p.sub.fn(ch)
+				if f == nil {
+					log.Printf("notified by unsubscribed handle")
+					// FIXME: should terminate the connection?
+				} else {
+					go f(b, nil)
+				}
+				break
+			}
+			rspc <- rsp
+		case <-p.quitc:
+			return
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/peripheral_linux.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/peripheral_linux.go b/newtmgr/vendor/github.com/runtimeco/gatt/peripheral_linux.go
new file mode 100644
index 0000000..43ec067
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/peripheral_linux.go
@@ -0,0 +1,448 @@
+package gatt
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"strings"
+
+	"github.com/runtimeco/gatt/linux"
+)
+
+type peripheral struct {
+	// NameChanged is called whenever the peripheral GAP device name has changed.
+	NameChanged func(*peripheral)
+
+	// ServicedModified is called when one or more service of a peripheral have changed.
+	// A list of invalid service is provided in the parameter.
+	ServicesModified func(*peripheral, []*Service)
+
+	d    *device
+	svcs []*Service
+
+	sub *subscriber
+
+	mtu uint16
+	l2c io.ReadWriteCloser
+
+	reqc  chan message
+	quitc chan struct{}
+
+	pd *linux.PlatData // platform specific data
+}
+
+func (p *peripheral) Device() Device       { return p.d }
+func (p *peripheral) ID() string           { return strings.ToUpper(net.HardwareAddr(p.pd.Address[:]).String()) }
+func (p *peripheral) Name() string         { return p.pd.Name }
+func (p *peripheral) Services() []*Service { return p.svcs }
+
+func finish(op byte, h uint16, b []byte) bool {
+	done := b[0] == attOpError && b[1] == op && b[2] == byte(h) && b[3] == byte(h>>8)
+	e := attEcode(b[4])
+	if e != attEcodeAttrNotFound {
+		// log.Printf("unexpected protocol error: %s", e)
+		// FIXME: terminate the connection
+	}
+	return done
+}
+
+func (p *peripheral) DiscoverServices(s []UUID) ([]*Service, error) {
+	// TODO: implement the UUID filters
+	// p.pd.Conn.Write([]byte{0x02, 0x87, 0x00}) // MTU
+	done := false
+	start := uint16(0x0001)
+	for !done {
+		op := byte(attOpReadByGroupReq)
+		b := make([]byte, 7)
+		b[0] = op
+		binary.LittleEndian.PutUint16(b[1:3], start)
+		binary.LittleEndian.PutUint16(b[3:5], 0xFFFF)
+		binary.LittleEndian.PutUint16(b[5:7], 0x2800)
+
+		b = p.sendReq(op, b)
+		if finish(op, start, b) {
+			break
+		}
+		b = b[1:]
+		l, b := int(b[0]), b[1:]
+		switch {
+		case l == 6 && (len(b)%6 == 0):
+		case l == 20 && (len(b)%20 == 0):
+		default:
+			return nil, ErrInvalidLength
+		}
+
+		for len(b) != 0 {
+			h := binary.LittleEndian.Uint16(b[:2])
+			endh := binary.LittleEndian.Uint16(b[2:4])
+			s := &Service{
+				uuid: UUID{b[4:l]},
+				h:    h,
+				endh: endh,
+			}
+			p.svcs = append(p.svcs, s)
+			b = b[l:]
+			done = endh == 0xFFFF
+			start = endh + 1
+		}
+	}
+	return p.svcs, nil
+}
+
+func (p *peripheral) DiscoverIncludedServices(ss []UUID, s *Service) ([]*Service, error) {
+	// TODO
+	return nil, nil
+}
+
+func (p *peripheral) DiscoverCharacteristics(cs []UUID, s *Service) ([]*Characteristic, error) {
+	// TODO: implement the UUID filters
+	done := false
+	start := s.h
+	var prev *Characteristic
+	for !done {
+		op := byte(attOpReadByTypeReq)
+		b := make([]byte, 7)
+		b[0] = op
+		binary.LittleEndian.PutUint16(b[1:3], start)
+		binary.LittleEndian.PutUint16(b[3:5], s.endh)
+		binary.LittleEndian.PutUint16(b[5:7], 0x2803)
+
+		b = p.sendReq(op, b)
+		if finish(op, start, b) {
+			break
+		}
+		b = b[1:]
+
+		l, b := int(b[0]), b[1:]
+		switch {
+		case l == 7 && (len(b)%7 == 0):
+		case l == 21 && (len(b)%21 == 0):
+		default:
+			return nil, ErrInvalidLength
+		}
+
+		for len(b) != 0 {
+			h := binary.LittleEndian.Uint16(b[:2])
+			props := Property(b[2])
+			vh := binary.LittleEndian.Uint16(b[3:5])
+			u := UUID{b[5:l]}
+			s := searchService(p.svcs, h, vh)
+			if s == nil {
+				log.Printf("Can't find service range that contains 0x%04X - 0x%04X", h, vh)
+				return nil, fmt.Errorf("Can't find service range that contains 0x%04X - 0x%04X", h, vh)
+			}
+			c := &Characteristic{
+				uuid:  u,
+				svc:   s,
+				props: props,
+				h:     h,
+				vh:    vh,
+			}
+			s.chars = append(s.chars, c)
+			b = b[l:]
+			done = vh == s.endh
+			start = vh + 1
+			if prev != nil {
+				prev.endh = c.h - 1
+			}
+			prev = c
+		}
+	}
+	if len(s.chars) > 1 {
+		s.chars[len(s.chars)-1].endh = s.endh
+	}
+	return s.chars, nil
+}
+
+func (p *peripheral) DiscoverDescriptors(ds []UUID, c *Characteristic) ([]*Descriptor, error) {
+	// TODO: implement the UUID filters
+	done := false
+	start := c.vh + 1
+	for !done {
+		if c.endh == 0 {
+			c.endh = c.svc.endh
+		}
+		op := byte(attOpFindInfoReq)
+		b := make([]byte, 5)
+		b[0] = op
+		binary.LittleEndian.PutUint16(b[1:3], start)
+		binary.LittleEndian.PutUint16(b[3:5], c.endh)
+
+		b = p.sendReq(op, b)
+		if finish(attOpFindInfoReq, start, b) {
+			break
+		}
+		b = b[1:]
+
+		var l int
+		f, b := int(b[0]), b[1:]
+		switch {
+		case f == 1 && (len(b)%4 == 0):
+			l = 4
+		case f == 2 && (len(b)%18 == 0):
+			l = 18
+		default:
+			return nil, ErrInvalidLength
+		}
+
+		for len(b) != 0 {
+			h := binary.LittleEndian.Uint16(b[:2])
+			u := UUID{b[2:l]}
+			d := &Descriptor{uuid: u, h: h, char: c}
+			c.descs = append(c.descs, d)
+			if u.Equal(attrClientCharacteristicConfigUUID) {
+				c.cccd = d
+			}
+			b = b[l:]
+			done = h == c.endh
+			start = h + 1
+		}
+	}
+	return c.descs, nil
+}
+
+func (p *peripheral) ReadCharacteristic(c *Characteristic) ([]byte, error) {
+	b := make([]byte, 3)
+	op := byte(attOpReadReq)
+	b[0] = op
+	binary.LittleEndian.PutUint16(b[1:3], c.vh)
+
+	b = p.sendReq(op, b)
+	b = b[1:]
+	return b, nil
+}
+
+func (p *peripheral) ReadLongCharacteristic(c *Characteristic) ([]byte, error) {
+	// The spec says that a read blob request should fail if the characteristic
+	// is smaller than mtu - 1.  To simplify the API, the first read is done
+	// with a regular read request.  If the buffer received is equal to mtu -1,
+	// then we read the rest of the data using read blob.
+	firstRead, err := p.ReadCharacteristic(c)
+	if err != nil {
+		return nil, err
+	}
+	if len(firstRead) < int(p.mtu)-1 {
+		return firstRead, nil
+	}
+
+	var buf bytes.Buffer
+	buf.Write(firstRead)
+	off := uint16(len(firstRead))
+	for {
+		b := make([]byte, 5)
+		op := byte(attOpReadBlobReq)
+		b[0] = op
+		binary.LittleEndian.PutUint16(b[1:3], c.vh)
+		binary.LittleEndian.PutUint16(b[3:5], off)
+
+		b = p.sendReq(op, b)
+		b = b[1:]
+		if len(b) == 0 {
+			break
+		}
+		buf.Write(b)
+		off += uint16(len(b))
+		if len(b) < int(p.mtu)-1 {
+			break
+		}
+	}
+	return buf.Bytes(), nil
+}
+
+func (p *peripheral) WriteCharacteristic(c *Characteristic, value []byte, noRsp bool) error {
+	b := make([]byte, 3+len(value))
+	op := byte(attOpWriteReq)
+	b[0] = op
+	if noRsp {
+		b[0] = attOpWriteCmd
+	}
+	binary.LittleEndian.PutUint16(b[1:3], c.vh)
+	copy(b[3:], value)
+
+	if noRsp {
+		p.sendCmd(op, b)
+		return nil
+	}
+	b = p.sendReq(op, b)
+	// TODO: error handling
+	b = b[1:]
+	return nil
+}
+
+func (p *peripheral) ReadDescriptor(d *Descriptor) ([]byte, error) {
+	b := make([]byte, 3)
+	op := byte(attOpReadReq)
+	b[0] = op
+	binary.LittleEndian.PutUint16(b[1:3], d.h)
+
+	b = p.sendReq(op, b)
+	b = b[1:]
+	// TODO: error handling
+	return b, nil
+}
+
+func (p *peripheral) WriteDescriptor(d *Descriptor, value []byte) error {
+	b := make([]byte, 3+len(value))
+	op := byte(attOpWriteReq)
+	b[0] = op
+	binary.LittleEndian.PutUint16(b[1:3], d.h)
+	copy(b[3:], value)
+
+	b = p.sendReq(op, b)
+	b = b[1:]
+	// TODO: error handling
+	return nil
+}
+
+func (p *peripheral) setNotifyValue(c *Characteristic, flag uint16,
+	f func(*Characteristic, []byte, error)) error {
+/*
+	if c.cccd == nil {
+		return errors.New("no cccd") // FIXME
+	}
+	ccc := uint16(0)
+	if f != nil {
+		ccc = flag
+*/
+		p.sub.subscribe(c.vh, func(b []byte, err error) { f(c, b, err) })
+/*
+	}
+	b := make([]byte, 5)
+	op := byte(attOpWriteReq)
+	b[0] = op
+	binary.LittleEndian.PutUint16(b[1:3], c.cccd.h)
+	binary.LittleEndian.PutUint16(b[3:5], ccc)
+
+	b = p.sendReq(op, b)
+	b = b[1:]
+	// TODO: error handling
+	if f == nil {
+		p.sub.unsubscribe(c.vh)
+	}
+*/
+	return nil
+}
+
+func (p *peripheral) SetNotifyValue(c *Characteristic,
+	f func(*Characteristic, []byte, error)) error {
+	return p.setNotifyValue(c, gattCCCNotifyFlag, f)
+}
+
+func (p *peripheral) SetIndicateValue(c *Characteristic,
+	f func(*Characteristic, []byte, error)) error {
+	return p.setNotifyValue(c, gattCCCIndicateFlag, f)
+}
+
+func (p *peripheral) ReadRSSI() int {
+	// TODO: implement
+	return -1
+}
+
+func searchService(ss []*Service, start, end uint16) *Service {
+	for _, s := range ss {
+		if s.h < start && s.endh >= end {
+			return s
+		}
+	}
+	return nil
+}
+
+// TODO: unifiy the message with OS X pots and refactor
+type message struct {
+	op   byte
+	b    []byte
+	rspc chan []byte
+}
+
+func (p *peripheral) sendCmd(op byte, b []byte) {
+	p.reqc <- message{op: op, b: b}
+}
+
+func (p *peripheral) sendReq(op byte, b []byte) []byte {
+	m := message{op: op, b: b, rspc: make(chan []byte)}
+	p.reqc <- m
+	return <-m.rspc
+}
+
+func (p *peripheral) loop() {
+	// Serialize the request.
+	rspc := make(chan []byte)
+
+	// Dequeue request loop
+	go func() {
+		for {
+			select {
+			case req := <-p.reqc:
+				p.l2c.Write(req.b)
+				if req.rspc == nil {
+					break
+				}
+				r := <-rspc
+				switch reqOp, rspOp := req.b[0], r[0]; {
+				case rspOp == attRspFor[reqOp]:
+				case rspOp == attOpError && r[1] == reqOp:
+				default:
+					log.Printf("Request 0x%02x got a mismatched response: 0x%02x", reqOp, rspOp)
+					// FIXME: terminate the connection?
+				}
+				req.rspc <- r
+			case <-p.quitc:
+				return
+			}
+		}
+	}()
+
+	// L2CAP implementations shall support a minimum MTU size of 48 bytes.
+	// The default value is 672 bytes
+	buf := make([]byte, 672)
+
+	// Handling response or notification/indication
+	for {
+		n, err := p.l2c.Read(buf)
+		if n == 0 || err != nil {
+			close(p.quitc)
+			return
+		}
+
+		b := make([]byte, n)
+		copy(b, buf)
+
+		if (b[0] != attOpHandleNotify) && (b[0] != attOpHandleInd) {
+			rspc <- b
+			continue
+		}
+
+		h := binary.LittleEndian.Uint16(b[1:3])
+		f := p.sub.fn(h)
+		if f == nil {
+			log.Printf("notified by unsubscribed handle")
+			// FIXME: terminate the connection?
+		} else {
+			go f(b[3:], nil)
+		}
+
+		if b[0] == attOpHandleInd {
+			// write aknowledgement for indication
+			p.l2c.Write([]byte{attOpHandleCnf})
+		}
+
+	}
+}
+
+func (p *peripheral) SetMTU(mtu uint16) error {
+	b := make([]byte, 3)
+	op := byte(attOpMtuReq)
+	b[0] = op
+	binary.LittleEndian.PutUint16(b[1:3], uint16(mtu))
+
+	b = p.sendReq(op, b)
+	serverMTU := binary.LittleEndian.Uint16(b[1:3])
+	if serverMTU < mtu {
+		mtu = serverMTU
+	}
+	p.mtu = mtu
+	return nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/readme.md
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/readme.md b/newtmgr/vendor/github.com/runtimeco/gatt/readme.md
new file mode 100644
index 0000000..ea3a957
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/readme.md
@@ -0,0 +1,115 @@
+# Package gatt provides a Bluetooth Low Energy GATT implementation.
+
+Gatt (Generic Attribute Profile) is the protocol used to write BLE peripherals (servers) and centrals (clients).
+
+As a peripheral, you can create services, characteristics, and descriptors,
+advertise, accept connections, and handle requests.
+
+As a central, you can scan, connect, discover services, and make requests.
+
+## SETUP
+
+### gatt supports both Linux and OS X.
+
+### On Linux:
+To gain complete and exclusive control of the HCI device, gatt uses
+HCI_CHANNEL_USER (introduced in Linux v3.14) instead of HCI_CHANNEL_RAW.
+Those who must use an older kernel may patch in these relevant commits
+from Marcel Holtmann:
+
+    Bluetooth: Introduce new HCI socket channel for user operation
+    Bluetooth: Introduce user channel flag for HCI devices
+    Bluetooth: Refactor raw socket filter into more readable code
+
+Note that because gatt uses HCI_CHANNEL_USER, once gatt has opened the
+device no other program may access it.
+
+Before starting a gatt program, make sure that your BLE device is down:
+
+    sudo hciconfig
+    sudo hciconfig hci0 down  # or whatever hci device you want to use
+
+If you have BlueZ 5.14+ (or aren't sure), stop the built-in
+bluetooth server, which interferes with gatt, e.g.:
+
+    sudo service bluetooth stop
+
+Because gatt programs administer network devices, they must
+either be run as root, or be granted appropriate capabilities:
+
+    sudo <executable>
+    # OR
+    sudo setcap 'cap_net_raw,cap_net_admin=eip' <executable>
+    <executable>
+
+## Usage
+Please see [godoc.org](http://godoc.org/github.com/paypal/gatt) for documentation.
+
+## Examples
+
+### Build and run the examples on a native environment (Linux or OS X)
+
+Go is a compiled language, which means to run the examples you need to build them first.
+
+    # Build the sample server.
+    go build examples/server.go
+    # Start the sample server.
+    sudo ./server
+
+Alternatively, you can use "go run" to build and run the examples in a single step:
+
+    # Build and run the sample server.
+    sudo go run examples/server.go
+
+Discoverer and explorer demonstrates central (client) functions:
+
+    # Discover surrounding peripherals.
+    sudo go run examples/discoverer.go
+
+    # Connect to and explorer a peripheral device.
+    sudo go run examples/explorer.go <peripheral ID>
+
+### Cross-compile and deploy to a target device
+
+    # Build and run the server example on a ARMv5 target device.
+    GOARCH=arm GOARM=5 GOOS=linux go build examples/server.go
+    cp server <target device>
+    # Start the server on the target device
+    sudo ./server
+
+See the server.go, discoverer.go, and explorer.go in the examples/
+directory for writing server or client programs that run on Linux
+and OS X.
+
+Users, especially on Linux platforms, seeking finer-grained control
+over the devices can see the examples/server_lnx.go for the usage
+of Option, which are platform specific.
+
+See the rest of the docs for other options and finer-grained control.
+
+## Note
+Note that some BLE central devices, particularly iOS, may aggressively
+cache results from previous connections. If you change your services or
+characteristics, you may need to reboot the other device to pick up the
+changes. This is a common source of confusion and apparent bugs. For an
+OS X central, see http://stackoverflow.com/questions/20553957.
+
+## Known Issues
+
+Currently OS X vesion  does not support subscribing to indications. 
+Please check [#32](https://github.com/paypal/gatt/issues/32) for the status of this issue.
+
+## REFERENCES
+
+gatt started life as a port of bleno, to which it is indebted:
+https://github.com/sandeepmistry/bleno. If you are having
+problems with gatt, particularly around installation, issues
+filed with bleno might also be helpful references.
+
+To try out your GATT server, it is useful to experiment with a
+generic BLE client. LightBlue is a good choice. It is available
+free for both iOS and OS X.
+
+gatt is similar to [bleno](https://github.com/sandeepmistry/bleno) and [noble](https://github.com/sandeepmistry/noble), which offer BLE GATT implementations for node.js.
+
+Gatt is released under a [BSD-style license](./LICENSE.md).

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/uuid.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/uuid.go b/newtmgr/vendor/github.com/runtimeco/gatt/uuid.go
new file mode 100644
index 0000000..393e548
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/uuid.go
@@ -0,0 +1,86 @@
+package gatt
+
+import (
+	"bytes"
+	"encoding/binary"
+	"encoding/hex"
+	"fmt"
+	"strings"
+)
+
+// A UUID is a BLE UUID.
+type UUID struct {
+	// Hide the bytes, so that we can enforce that they have length 2 or 16,
+	// and that they are immutable. This simplifies the code and API.
+	b []byte
+}
+
+// UUID16 converts a uint16 (such as 0x1800) to a UUID.
+func UUID16(i uint16) UUID {
+	b := make([]byte, 2)
+	binary.LittleEndian.PutUint16(b, i)
+	return UUID{b}
+}
+
+// ParseUUID parses a standard-format UUID string, such
+// as "1800" or "34DA3AD1-7110-41A1-B1EF-4430F509CDE7".
+func ParseUUID(s string) (UUID, error) {
+	s = strings.Replace(s, "-", "", -1)
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		return UUID{}, err
+	}
+	if err := lenErr(len(b)); err != nil {
+		return UUID{}, err
+	}
+	return UUID{reverse(b)}, nil
+}
+
+// MustParseUUID parses a standard-format UUID string,
+// like ParseUUID, but panics in case of error.
+func MustParseUUID(s string) UUID {
+	u, err := ParseUUID(s)
+	if err != nil {
+		panic(err)
+	}
+	return u
+}
+
+// lenErr returns an error if n is an invalid UUID length.
+func lenErr(n int) error {
+	switch n {
+	case 2, 16:
+		return nil
+	}
+	return fmt.Errorf("UUIDs must have length 2 or 16, got %d", n)
+}
+
+// Len returns the length of the UUID, in bytes.
+// BLE UUIDs are either 2 or 16 bytes.
+func (u UUID) Len() int {
+	return len(u.b)
+}
+
+// String hex-encodes a UUID.
+func (u UUID) String() string {
+	return fmt.Sprintf("%x", reverse(u.b))
+}
+
+// Equal returns a boolean reporting whether v represent the same UUID as u.
+func (u UUID) Equal(v UUID) bool {
+	return bytes.Equal(u.b, v.b)
+}
+
+// reverse returns a reversed copy of u.
+func reverse(u []byte) []byte {
+	// Special-case 16 bit UUIDS for speed.
+	l := len(u)
+	if l == 2 {
+		return []byte{u[1], u[0]}
+	}
+	b := make([]byte, l)
+	for i := 0; i < l/2+1; i++ {
+		b[i], b[l-i-1] = u[l-i-1], u[i]
+	}
+	return b
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/xpc/LICENSE
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/xpc/LICENSE b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/LICENSE
new file mode 100644
index 0000000..766a0a5
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) {{{year}}} {{{fullname}}}
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/xpc/doc.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/xpc/doc.go b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/doc.go
new file mode 100644
index 0000000..d292249
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/doc.go
@@ -0,0 +1,8 @@
+// Package xpc provides minimal OS X XPC support required for gatt
+//
+// This is adapted from [goble], by Raffaele Sena.
+//
+//     http://godoc.org/github.com/raff/goble
+//     https://github.com/raff/goble
+
+package xpc

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_darwin.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_darwin.go b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_darwin.go
new file mode 100644
index 0000000..2a85a99
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_darwin.go
@@ -0,0 +1,350 @@
+package xpc
+
+/*
+#include "xpc_wrapper_darwin.h"
+#include "sys/utsname.h"
+*/
+import "C"
+
+import (
+	"errors"
+	"fmt"
+	"log"
+	r "reflect"
+	"unsafe"
+)
+
+type XPC struct {
+	conn C.xpc_connection_t
+}
+
+func (x *XPC) Send(msg interface{}, verbose bool) {
+	// verbose == true converts the type from bool to C._Bool
+	C.XpcSendMessage(x.conn, goToXpc(msg), true, verbose == true)
+}
+
+//
+// minimal XPC support required for BLE
+//
+
+// a dictionary of things
+type Dict map[string]interface{}
+
+func (d Dict) Contains(k string) bool {
+	_, ok := d[k]
+	return ok
+}
+
+func (d Dict) MustGetDict(k string) Dict {
+	return d[k].(Dict)
+}
+
+func (d Dict) MustGetArray(k string) Array {
+	return d[k].(Array)
+}
+
+func (d Dict) MustGetBytes(k string) []byte {
+	return d[k].([]byte)
+}
+
+func (d Dict) MustGetHexBytes(k string) string {
+	return fmt.Sprintf("%x", d[k].([]byte))
+}
+
+func (d Dict) MustGetInt(k string) int {
+	return int(d[k].(int64))
+}
+
+func (d Dict) MustGetUUID(k string) []byte {
+	u := d[k].(UUID)
+	return u[:]
+}
+
+func (d Dict) GetString(k, defv string) string {
+	if v := d[k]; v != nil {
+		//log.Printf("GetString %s %#v\n", k, v)
+		return v.(string)
+	} else {
+		//log.Printf("GetString %s default %#v\n", k, defv)
+		return defv
+	}
+}
+
+func (d Dict) GetBytes(k string, defv []byte) []byte {
+	if v := d[k]; v != nil {
+		//log.Printf("GetBytes %s %#v\n", k, v)
+		return v.([]byte)
+	} else {
+		//log.Printf("GetBytes %s default %#v\n", k, defv)
+		return defv
+	}
+}
+
+func (d Dict) GetInt(k string, defv int) int {
+	if v := d[k]; v != nil {
+		//log.Printf("GetString %s %#v\n", k, v)
+		return int(v.(int64))
+	} else {
+		//log.Printf("GetString %s default %#v\n", k, defv)
+		return defv
+	}
+}
+
+func (d Dict) GetUUID(k string) UUID {
+	return GetUUID(d[k])
+}
+
+// an array of things
+type Array []interface{}
+
+func (a Array) GetUUID(k int) UUID {
+	return GetUUID(a[k])
+}
+
+// a UUID
+type UUID []byte
+
+func MakeUUID(s string) UUID {
+	var sl []byte
+	fmt.Sscanf(s, "%32x", &sl)
+
+	var uuid [16]byte
+	copy(uuid[:], sl)
+	return UUID(uuid[:])
+}
+
+func (uuid UUID) String() string {
+	return fmt.Sprintf("%x", []byte(uuid))
+}
+
+func GetUUID(v interface{}) UUID {
+	if v == nil {
+		return UUID{}
+	}
+
+	if uuid, ok := v.(UUID); ok {
+		return uuid
+	}
+
+	if bytes, ok := v.([]byte); ok {
+		uuid := UUID{}
+
+		for i, b := range bytes {
+			uuid[i] = b
+		}
+
+		return uuid
+	}
+
+	if bytes, ok := v.([]uint8); ok {
+		uuid := UUID{}
+
+		for i, b := range bytes {
+			uuid[i] = b
+		}
+
+		return uuid
+	}
+
+	log.Fatalf("invalid type for UUID: %#v", v)
+	return UUID{}
+}
+
+var (
+	CONNECTION_INVALID     = errors.New("connection invalid")
+	CONNECTION_INTERRUPTED = errors.New("connection interrupted")
+	CONNECTION_TERMINATED  = errors.New("connection terminated")
+
+	TYPE_OF_UUID  = r.TypeOf(UUID{})
+	TYPE_OF_BYTES = r.TypeOf([]byte{})
+)
+
+type XpcEventHandler interface {
+	HandleXpcEvent(event Dict, err error)
+}
+
+func XpcConnect(service string, eh XpcEventHandler) XPC {
+	cservice := C.CString(service)
+	defer C.free(unsafe.Pointer(cservice))
+	return XPC{conn: C.XpcConnect(cservice, unsafe.Pointer(&eh))}
+}
+
+//export handleXpcEvent
+func handleXpcEvent(event C.xpc_object_t, p unsafe.Pointer) {
+	//log.Printf("handleXpcEvent %#v %#v\n", event, p)
+
+	t := C.xpc_get_type(event)
+	eh := *((*XpcEventHandler)(p))
+
+	if t == C.TYPE_ERROR {
+		if event == C.ERROR_CONNECTION_INVALID {
+			// The client process on the other end of the connection has either
+			// crashed or cancelled the connection. After receiving this error,
+			// the connection is in an invalid state, and you do not need to
+			// call xpc_connection_cancel(). Just tear down any associated state
+			// here.
+			//log.Println("connection invalid")
+			eh.HandleXpcEvent(nil, CONNECTION_INVALID)
+		} else if event == C.ERROR_CONNECTION_INTERRUPTED {
+			//log.Println("connection interrupted")
+			eh.HandleXpcEvent(nil, CONNECTION_INTERRUPTED)
+		} else if event == C.ERROR_CONNECTION_TERMINATED {
+			// Handle per-connection termination cleanup.
+			//log.Println("connection terminated")
+			eh.HandleXpcEvent(nil, CONNECTION_TERMINATED)
+		} else {
+			//log.Println("got some error", event)
+			eh.HandleXpcEvent(nil, fmt.Errorf("%v", event))
+		}
+	} else {
+		eh.HandleXpcEvent(xpcToGo(event).(Dict), nil)
+	}
+}
+
+// goToXpc converts a go object to an xpc object
+func goToXpc(o interface{}) C.xpc_object_t {
+	return valueToXpc(r.ValueOf(o))
+}
+
+// valueToXpc converts a go Value to an xpc object
+//
+// note that not all the types are supported, but only the subset required for Blued
+func valueToXpc(val r.Value) C.xpc_object_t {
+	if !val.IsValid() {
+		return nil
+	}
+
+	var xv C.xpc_object_t
+
+	switch val.Kind() {
+	case r.Int, r.Int8, r.Int16, r.Int32, r.Int64:
+		xv = C.xpc_int64_create(C.int64_t(val.Int()))
+
+	case r.Uint, r.Uint8, r.Uint16, r.Uint32:
+		xv = C.xpc_int64_create(C.int64_t(val.Uint()))
+
+	case r.String:
+		xv = C.xpc_string_create(C.CString(val.String()))
+
+	case r.Map:
+		xv = C.xpc_dictionary_create(nil, nil, 0)
+		for _, k := range val.MapKeys() {
+			v := valueToXpc(val.MapIndex(k))
+			C.xpc_dictionary_set_value(xv, C.CString(k.String()), v)
+			if v != nil {
+				C.xpc_release(v)
+			}
+		}
+
+	case r.Array, r.Slice:
+		if val.Type() == TYPE_OF_UUID {
+			// array of bytes
+			var uuid [16]byte
+			r.Copy(r.ValueOf(uuid[:]), val)
+			xv = C.xpc_uuid_create(C.ptr_to_uuid(unsafe.Pointer(&uuid[0])))
+		} else if val.Type() == TYPE_OF_BYTES {
+			// slice of bytes
+			xv = C.xpc_data_create(unsafe.Pointer(val.Pointer()), C.size_t(val.Len()))
+		} else {
+			xv = C.xpc_array_create(nil, 0)
+			l := val.Len()
+
+			for i := 0; i < l; i++ {
+				v := valueToXpc(val.Index(i))
+				C.xpc_array_append_value(xv, v)
+				if v != nil {
+					C.xpc_release(v)
+				}
+			}
+		}
+
+	case r.Interface, r.Ptr:
+		xv = valueToXpc(val.Elem())
+
+	default:
+		log.Fatalf("unsupported %#v", val.String())
+	}
+
+	return xv
+}
+
+//export arraySet
+func arraySet(u unsafe.Pointer, i C.int, v C.xpc_object_t) {
+	a := *(*Array)(u)
+	a[i] = xpcToGo(v)
+}
+
+//export dictSet
+func dictSet(u unsafe.Pointer, k *C.char, v C.xpc_object_t) {
+	d := *(*Dict)(u)
+	d[C.GoString(k)] = xpcToGo(v)
+}
+
+// xpcToGo converts an xpc object to a go object
+//
+// note that not all the types are supported, but only the subset required for Blued
+func xpcToGo(v C.xpc_object_t) interface{} {
+	t := C.xpc_get_type(v)
+
+	switch t {
+	case C.TYPE_ARRAY:
+		a := make(Array, C.int(C.xpc_array_get_count(v)))
+		C.XpcArrayApply(unsafe.Pointer(&a), v)
+		return a
+
+	case C.TYPE_DATA:
+		return C.GoBytes(C.xpc_data_get_bytes_ptr(v), C.int(C.xpc_data_get_length(v)))
+
+	case C.TYPE_DICT:
+		d := make(Dict)
+		C.XpcDictApply(unsafe.Pointer(&d), v)
+		return d
+
+	case C.TYPE_INT64:
+		return int64(C.xpc_int64_get_value(v))
+
+	case C.TYPE_STRING:
+		return C.GoString(C.xpc_string_get_string_ptr(v))
+
+	case C.TYPE_UUID:
+		a := [16]byte{}
+		C.XpcUUIDGetBytes(unsafe.Pointer(&a), v)
+		return UUID(a[:])
+
+	default:
+		log.Fatalf("unexpected type %#v, value %#v", t, v)
+	}
+
+	return nil
+}
+
+// xpc_release is needed by tests, since they can't use CGO
+func xpc_release(xv C.xpc_object_t) {
+	C.xpc_release(xv)
+}
+
+// this is used to check the OS version
+
+type Utsname struct {
+	Sysname  string
+	Nodename string
+	Release  string
+	Version  string
+	Machine  string
+}
+
+func Uname(utsname *Utsname) error {
+	var cstruct C.struct_utsname
+	if err := C.uname(&cstruct); err != 0 {
+		return errors.New("utsname error")
+	}
+
+	// XXX: this may crash if any value is exactly 256 characters (no 0 terminator)
+	utsname.Sysname = C.GoString(&cstruct.sysname[0])
+	utsname.Nodename = C.GoString(&cstruct.nodename[0])
+	utsname.Release = C.GoString(&cstruct.release[0])
+	utsname.Version = C.GoString(&cstruct.version[0])
+	utsname.Machine = C.GoString(&cstruct.machine[0])
+
+	return nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_wrapper_darwin.c
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_wrapper_darwin.c b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_wrapper_darwin.c
new file mode 100644
index 0000000..7bcb83d
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_wrapper_darwin.c
@@ -0,0 +1,85 @@
+#include <dispatch/dispatch.h>
+#include <xpc/xpc.h>
+#include <xpc/connection.h>
+#include <Block.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "_cgo_export.h"
+
+//
+// types and errors are implemented as macros
+// create some real objects to make them accessible to Go
+//
+xpc_type_t TYPE_ERROR = XPC_TYPE_ERROR;
+
+xpc_type_t TYPE_ARRAY = XPC_TYPE_ARRAY;
+xpc_type_t TYPE_DATA = XPC_TYPE_DATA;
+xpc_type_t TYPE_DICT = XPC_TYPE_DICTIONARY;
+xpc_type_t TYPE_INT64 = XPC_TYPE_INT64;
+xpc_type_t TYPE_STRING = XPC_TYPE_STRING;
+xpc_type_t TYPE_UUID = XPC_TYPE_UUID;
+
+xpc_object_t ERROR_CONNECTION_INVALID = (xpc_object_t) XPC_ERROR_CONNECTION_INVALID;
+xpc_object_t ERROR_CONNECTION_INTERRUPTED = (xpc_object_t) XPC_ERROR_CONNECTION_INTERRUPTED;
+xpc_object_t ERROR_CONNECTION_TERMINATED = (xpc_object_t) XPC_ERROR_TERMINATION_IMMINENT;
+
+const ptr_to_uuid_t ptr_to_uuid(void *p) { return (ptr_to_uuid_t)p; }
+
+
+//
+// connect to XPC service
+//
+xpc_connection_t XpcConnect(char *service, void *ctx) {
+    dispatch_queue_t queue = dispatch_queue_create(service, 0);
+    xpc_connection_t conn = xpc_connection_create_mach_service(service, queue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
+
+    // making a local copy, that should be made "persistent" with the following Block_copy
+    GoInterface ictx = *((GoInterface*)ctx);
+
+    xpc_connection_set_event_handler(conn,
+        Block_copy(^(xpc_object_t event) {
+            handleXpcEvent(event, (void *)&ictx);
+        })
+    );
+
+    xpc_connection_resume(conn);
+    return conn;
+}
+
+void XpcSendMessage(xpc_connection_t conn, xpc_object_t message, bool release, bool reportDelivery) {
+    xpc_connection_send_message(conn,  message);
+    xpc_connection_send_barrier(conn, ^{
+        // Block is invoked on connection's target queue
+        // when 'message' has been sent.
+        if (reportDelivery) { // maybe this could be a callback
+            puts("message delivered");
+        }
+    });
+    if (release) {
+        xpc_release(message);
+    }
+}
+
+void XpcArrayApply(void *v, xpc_object_t arr) {
+  xpc_array_apply(arr, ^bool(size_t index, xpc_object_t value) {
+    arraySet(v, index, value);
+    return true;
+  });
+}
+
+void XpcDictApply(void *v, xpc_object_t dict) {
+  xpc_dictionary_apply(dict, ^bool(const char *key, xpc_object_t value) {
+    dictSet(v, (char *)key, value);
+    return true;
+  });
+}
+
+void XpcUUIDGetBytes(void *v, xpc_object_t uuid) {
+   const uint8_t *src = xpc_uuid_get_bytes(uuid);
+   uint8_t *dest = (uint8_t *)v;
+
+   for (int i=0; i < sizeof(uuid_t); i++) {
+     dest[i] = src[i];
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_wrapper_darwin.h
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_wrapper_darwin.h b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_wrapper_darwin.h
new file mode 100644
index 0000000..e2cfb5c
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/gatt/xpc/xpc_wrapper_darwin.h
@@ -0,0 +1,32 @@
+#ifndef _XPC_WRAPPER_H_
+#define _XPC_WRAPPER_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <xpc/xpc.h>
+
+extern xpc_type_t TYPE_ERROR;
+
+extern xpc_type_t TYPE_ARRAY;
+extern xpc_type_t TYPE_DATA;
+extern xpc_type_t TYPE_DICT;
+extern xpc_type_t TYPE_INT64;
+extern xpc_type_t TYPE_STRING;
+extern xpc_type_t TYPE_UUID;
+
+extern xpc_object_t ERROR_CONNECTION_INVALID;
+extern xpc_object_t ERROR_CONNECTION_INTERRUPTED;
+extern xpc_object_t ERROR_CONNECTION_TERMINATED;
+
+extern xpc_connection_t XpcConnect(char *, void *);
+extern void XpcSendMessage(xpc_connection_t, xpc_object_t, bool, bool);
+extern void XpcArrayApply(void *, xpc_object_t);
+extern void XpcDictApply(void *, xpc_object_t);
+extern void XpcUUIDGetBytes(void *, xpc_object_t);
+
+// the input type for xpc_uuid_create should be uuid_t but CGO instists on unsigned char *
+// typedef uuid_t * ptr_to_uuid_t;
+typedef unsigned char * ptr_to_uuid_t;
+extern const ptr_to_uuid_t ptr_to_uuid(void *p);
+
+#endif

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

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a1553084/newtmgr/vendor/github.com/runtimeinc/gatt/LICENSE.md
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeinc/gatt/LICENSE.md b/newtmgr/vendor/github.com/runtimeinc/gatt/LICENSE.md
deleted file mode 100644
index 51c07a6..0000000
--- a/newtmgr/vendor/github.com/runtimeinc/gatt/LICENSE.md
+++ /dev/null
@@ -1,27 +0,0 @@
-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/runtimeinc/gatt/adv.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeinc/gatt/adv.go b/newtmgr/vendor/github.com/runtimeinc/gatt/adv.go
deleted file mode 100644
index 3b8a747..0000000
--- a/newtmgr/vendor/github.com/runtimeinc/gatt/adv.go
+++ /dev/null
@@ -1,234 +0,0 @@
-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/runtimeinc/gatt/attr.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/github.com/runtimeinc/gatt/attr.go b/newtmgr/vendor/github.com/runtimeinc/gatt/attr.go
deleted file mode 100644
index d1ae09d..0000000
--- a/newtmgr/vendor/github.com/runtimeinc/gatt/attr.go
+++ /dev/null
@@ -1,160 +0,0 @@
-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
-}