You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/08/11 17:57:07 UTC

[mynewt-newtmgr] branch master updated (a09fa37 -> 0e5f37c)

This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git.


    from a09fa37  newtmgr - revendor
     new eba277e  nmxact - replace public service with iotivity.
     new 2737add  nmxact - Make CoapServiceCfg fields public.
     new 0e5f37c  newtmgr - revendor

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 newtmgr/Godeps/Godeps.json                         |   72 +-
 .../vendor/github.com/currantlabs/ble/.gitignore   |    5 +
 .../{tarm/serial => currantlabs/ble}/LICENSE       |    4 +-
 .../vendor/github.com/currantlabs/ble/README.md    |    3 +
 newtmgr/vendor/github.com/currantlabs/ble/addr.go  |   20 +
 newtmgr/vendor/github.com/currantlabs/ble/adv.go   |   28 +
 .../vendor/github.com/currantlabs/ble/client.go    |   69 +
 newtmgr/vendor/github.com/currantlabs/ble/conn.go  |   39 +
 newtmgr/vendor/github.com/currantlabs/ble/const.go |   33 +
 .../github.com/currantlabs/ble/darwin/adv.go       |   73 +
 .../github.com/currantlabs/ble/darwin/client.go    |  282 ++++
 .../github.com/currantlabs/ble/darwin/conn.go      |  135 ++
 .../github.com/currantlabs/ble/darwin/device.go    |  515 +++++++
 .../github.com/currantlabs/ble/darwin/log.go       |    7 +
 .../github.com/currantlabs/ble/darwin/msg.go       |   64 +
 .../github.com/currantlabs/ble/darwin/option.go    |   20 +
 .../github.com/currantlabs/ble/darwin/state.go     |   26 +
 .../github.com/currantlabs/ble/darwin/util.go      |   11 +
 newtmgr/vendor/github.com/currantlabs/ble/dev.go   |   42 +
 newtmgr/vendor/github.com/currantlabs/ble/error.go |   75 +
 .../ble/examples/lib/dev/default_darwin.go         |   11 +
 .../ble/examples/lib/dev/default_linux.go          |   11 +
 .../currantlabs/ble/examples/lib/dev/dev.go        |    8 +
 newtmgr/vendor/github.com/currantlabs/ble/gatt.go  |  188 +++
 .../vendor/github.com/currantlabs/ble/handler.go   |  188 +++
 .../github.com/currantlabs/ble/linux/adv/const.go  |   57 +
 .../github.com/currantlabs/ble/linux/adv/packet.go |  289 ++++
 .../github.com/currantlabs/ble/linux/att/README.md |   40 +
 .../github.com/currantlabs/ble/linux/att/att.go    |   30 +
 .../currantlabs/ble/linux/att/att_gen.go           |  639 ++++++++
 .../github.com/currantlabs/ble/linux/att/attr.go   |   14 +
 .../github.com/currantlabs/ble/linux/att/client.go |  560 +++++++
 .../github.com/currantlabs/ble/linux/att/db.go     |  210 +++
 .../github.com/currantlabs/ble/linux/att/log.go    |    7 +
 .../github.com/currantlabs/ble/linux/att/server.go |  594 ++++++++
 .../github.com/currantlabs/ble/linux/device.go     |  165 +++
 .../currantlabs/ble/linux/gatt/README.md           |   47 +
 .../currantlabs/ble/linux/gatt/client.go           |  385 +++++
 .../currantlabs/ble/linux/gatt/server.go           |   83 ++
 .../github.com/currantlabs/ble/linux/hci/README.md |  116 ++
 .../github.com/currantlabs/ble/linux/hci/adv.go    |  135 ++
 .../github.com/currantlabs/ble/linux/hci/buffer.go |   74 +
 .../currantlabs/ble/linux/hci/cmd/cmd.go           |   31 +
 .../currantlabs/ble/linux/hci/cmd/cmd_gen.go       | 1562 ++++++++++++++++++++
 .../github.com/currantlabs/ble/linux/hci/conn.go   |  338 +++++
 .../github.com/currantlabs/ble/linux/hci/const.go  |   30 +
 .../github.com/currantlabs/ble/linux/hci/error.go  |  161 ++
 .../currantlabs/ble/linux/hci/evt/evt.go           |   55 +
 .../currantlabs/ble/linux/hci/evt/evt_gen.go       |  227 +++
 .../github.com/currantlabs/ble/linux/hci/gap.go    |  214 +++
 .../github.com/currantlabs/ble/linux/hci/hci.go    |  517 +++++++
 .../github.com/currantlabs/ble/linux/hci/log.go    |    7 +
 .../github.com/currantlabs/ble/linux/hci/option.go |   42 +
 .../github.com/currantlabs/ble/linux/hci/params.go |   55 +
 .../github.com/currantlabs/ble/linux/hci/signal.go |  223 +++
 .../currantlabs/ble/linux/hci/signal_gen.go        |  205 +++
 .../github.com/currantlabs/ble/linux/hci/smp.go    |   61 +
 .../currantlabs/ble/linux/hci/socket/dummy.go      |   10 +
 .../currantlabs/ble/linux/hci/socket/socket.go     |  146 ++
 .../vendor/github.com/currantlabs/ble/profile.go   |  221 +++
 newtmgr/vendor/github.com/currantlabs/ble/uuid.go  |  217 +++
 .../{runtimeco/go-coap => raff/goble}/LICENSE      |    2 +-
 newtmgr/vendor/github.com/raff/goble/xpc/xpc.go    |  381 +++++
 .../vendor/github.com/raff/goble/xpc/xpc_wrapper.c |   85 ++
 .../vendor/github.com/raff/goble/xpc/xpc_wrapper.h |   33 +
 newtmgr/vendor/mynewt.apache.org/newt/util/util.go |   14 +-
 .../newtmgr/nmxact/bledefs/bledefs.go              |    6 +-
 .../newtmgr/nmxact/nmble/ble_util.go               |   34 +-
 nmxact/bledefs/bledefs.go                          |    6 +-
 nmxact/nmble/ble_util.go                           |   34 +-
 70 files changed, 10210 insertions(+), 81 deletions(-)
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/.gitignore
 copy newtmgr/vendor/github.com/{tarm/serial => currantlabs/ble}/LICENSE (92%)
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/README.md
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/addr.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/adv.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/client.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/conn.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/const.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/adv.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/client.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/conn.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/device.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/log.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/msg.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/option.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/state.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/darwin/util.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/dev.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/error.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/default_darwin.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/default_linux.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/dev.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/gatt.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/handler.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/adv/const.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/adv/packet.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/att/README.md
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/att/att.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/att/att_gen.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/att/attr.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/att/client.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/att/db.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/att/log.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/att/server.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/device.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/README.md
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/client.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/server.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/README.md
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/adv.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/buffer.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/cmd/cmd.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/cmd/cmd_gen.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/conn.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/const.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/error.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/evt/evt.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/evt/evt_gen.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/gap.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/hci.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/log.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/option.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/params.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/signal.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/signal_gen.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/smp.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/socket/dummy.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/linux/hci/socket/socket.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/profile.go
 create mode 100644 newtmgr/vendor/github.com/currantlabs/ble/uuid.go
 copy newtmgr/vendor/github.com/{runtimeco/go-coap => raff/goble}/LICENSE (96%)
 create mode 100644 newtmgr/vendor/github.com/raff/goble/xpc/xpc.go
 create mode 100644 newtmgr/vendor/github.com/raff/goble/xpc/xpc_wrapper.c
 create mode 100644 newtmgr/vendor/github.com/raff/goble/xpc/xpc_wrapper.h

-- 
To stop receiving notification emails like this one, please contact
['"commits@mynewt.apache.org" <co...@mynewt.apache.org>'].

[mynewt-newtmgr] 01/03: nmxact - replace public service with iotivity.

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit eba277e9a6d9c361b8e5f99d6894924f0eaba896
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Fri Aug 11 10:51:28 2017 -0700

    nmxact - replace public service with iotivity.
---
 nmxact/bledefs/bledefs.go | 6 +++---
 nmxact/nmble/ble_util.go  | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/nmxact/bledefs/bledefs.go b/nmxact/bledefs/bledefs.go
index 780587e..6b31ca2 100644
--- a/nmxact/bledefs/bledefs.go
+++ b/nmxact/bledefs/bledefs.go
@@ -33,9 +33,9 @@ const BLE_ATT_MTU_DFLT = 23
 
 const CccdUuid = 0x2902
 
-const PublicSvcUuid = "40e32721-9153-43a3-9ab3-ee7d4c84fcb2"
-const PublicReqChrUuid = "223387b6-63e6-4d16-8a58-988542253a54"
-const PublicRspChrUuid = "cb9564db-184c-4b9d-b221-6362679cad10"
+const IotivitySvcUuid = "ade3d529-c784-4f63-a987-eb69f70ee816"
+const IotivityReqChrUuid = "ad7b334f-4637-4b86-90b6-9d787f03d218"
+const IotivityRspChrUuid = "ad7b334f-4637-4b86-90b6-9d787f03d218"
 
 const UnauthSvcUuid = "0c08c213-98ed-4e43-a499-7e1137c39567"
 const UnauthReqChrUuid = "69b8a928-2ab2-487b-923e-54ce53a18bc1"
diff --git a/nmxact/nmble/ble_util.go b/nmxact/nmble/ble_util.go
index 8a11ec0..d410ea5 100644
--- a/nmxact/nmble/ble_util.go
+++ b/nmxact/nmble/ble_util.go
@@ -765,9 +765,9 @@ func BuildMgmtChrs(mgmtProto sesn.MgmtProto) (BleMgmtChrs, error) {
 	ompReqChrUuid, _ := ParseUuid(OmpUnsecReqChrUuid)
 	ompRspChrUuid, _ := ParseUuid(OmpUnsecRspChrUuid)
 
-	publicSvcUuid, _ := ParseUuid(PublicSvcUuid)
-	publicReqChrUuid, _ := ParseUuid(PublicReqChrUuid)
-	publicRspChrUuid, _ := ParseUuid(PublicRspChrUuid)
+	publicSvcUuid, _ := ParseUuid(IotivitySvcUuid)
+	publicReqChrUuid, _ := ParseUuid(IotivityReqChrUuid)
+	publicRspChrUuid, _ := ParseUuid(IotivityRspChrUuid)
 
 	unauthSvcUuid, _ := ParseUuid(UnauthSvcUuid)
 	unauthReqChrUuid, _ := ParseUuid(UnauthReqChrUuid)

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.

[mynewt-newtmgr] 02/03: nmxact - Make CoapServiceCfg fields public.

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit 2737add6819ac8d0f77e56eeb27b56cc9382616e
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Fri Aug 11 10:51:42 2017 -0700

    nmxact - Make CoapServiceCfg fields public.
---
 nmxact/nmble/ble_util.go | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/nmxact/nmble/ble_util.go b/nmxact/nmble/ble_util.go
index d410ea5..d1d0bfb 100644
--- a/nmxact/nmble/ble_util.go
+++ b/nmxact/nmble/ble_util.go
@@ -683,36 +683,36 @@ func GattService() BleSvc {
 }
 
 type CoapServiceCfg struct {
-	x          *BleXport
-	svcUuid    BleUuid
-	reqChrUuid BleUuid
-	rspChrUuid BleUuid
-	enc        bool
-	auth       bool
-	resources  []oic.Resource
+	X          *BleXport
+	SvcUuid    BleUuid
+	ReqChrUuid BleUuid
+	RspChrUuid BleUuid
+	Enc        bool
+	Auth       bool
+	Resources  []oic.Resource
 }
 
 func GenCoapService(cfg CoapServiceCfg) (BleSvc, error) {
-	svr := NewBleOicSvr(cfg.x, cfg.svcUuid, cfg.rspChrUuid)
-	for _, r := range cfg.resources {
+	svr := NewBleOicSvr(cfg.X, cfg.SvcUuid, cfg.RspChrUuid)
+	for _, r := range cfg.Resources {
 		if err := svr.AddResource(r); err != nil {
 			return BleSvc{}, err
 		}
 	}
 
 	var secFlags BleChrFlags
-	if cfg.enc {
+	if cfg.Enc {
 		secFlags |= BLE_GATT_F_WRITE_ENC
 	}
-	if cfg.auth {
+	if cfg.Auth {
 		secFlags |= BLE_GATT_F_WRITE_AUTHEN
 	}
 	svc := BleSvc{
-		Uuid:    cfg.svcUuid,
+		Uuid:    cfg.SvcUuid,
 		SvcType: BLE_SVC_TYPE_PRIMARY,
 		Chrs: []BleChr{
 			BleChr{
-				Uuid:       cfg.reqChrUuid,
+				Uuid:       cfg.ReqChrUuid,
 				Flags:      BLE_GATT_F_WRITE_NO_RSP | secFlags,
 				MinKeySize: 0,
 				AccessCb: func(access BleGattAccess) (uint8, []byte) {
@@ -720,7 +720,7 @@ func GenCoapService(cfg CoapServiceCfg) (BleSvc, error) {
 				},
 			},
 			BleChr{
-				Uuid:       cfg.rspChrUuid,
+				Uuid:       cfg.RspChrUuid,
 				Flags:      BLE_GATT_F_NOTIFY,
 				MinKeySize: 0,
 				AccessCb:   nil,

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.

[mynewt-newtmgr] 03/03: newtmgr - revendor

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git

commit 0e5f37c153da3f926e1f9f7ede5b70f432defd3b
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Fri Aug 11 10:47:46 2017 -0700

    newtmgr - revendor
---
 newtmgr/Godeps/Godeps.json                         |   72 +-
 .../vendor/github.com/currantlabs/ble/.gitignore   |    5 +
 newtmgr/vendor/github.com/currantlabs/ble/LICENSE  |   27 +
 .../vendor/github.com/currantlabs/ble/README.md    |    3 +
 newtmgr/vendor/github.com/currantlabs/ble/addr.go  |   20 +
 newtmgr/vendor/github.com/currantlabs/ble/adv.go   |   28 +
 .../vendor/github.com/currantlabs/ble/client.go    |   69 +
 newtmgr/vendor/github.com/currantlabs/ble/conn.go  |   39 +
 newtmgr/vendor/github.com/currantlabs/ble/const.go |   33 +
 .../github.com/currantlabs/ble/darwin/adv.go       |   73 +
 .../github.com/currantlabs/ble/darwin/client.go    |  282 ++++
 .../github.com/currantlabs/ble/darwin/conn.go      |  135 ++
 .../github.com/currantlabs/ble/darwin/device.go    |  515 +++++++
 .../github.com/currantlabs/ble/darwin/log.go       |    7 +
 .../github.com/currantlabs/ble/darwin/msg.go       |   64 +
 .../github.com/currantlabs/ble/darwin/option.go    |   20 +
 .../github.com/currantlabs/ble/darwin/state.go     |   26 +
 .../github.com/currantlabs/ble/darwin/util.go      |   11 +
 newtmgr/vendor/github.com/currantlabs/ble/dev.go   |   42 +
 newtmgr/vendor/github.com/currantlabs/ble/error.go |   75 +
 .../ble/examples/lib/dev/default_darwin.go         |   11 +
 .../ble/examples/lib/dev/default_linux.go          |   11 +
 .../currantlabs/ble/examples/lib/dev/dev.go        |    8 +
 newtmgr/vendor/github.com/currantlabs/ble/gatt.go  |  188 +++
 .../vendor/github.com/currantlabs/ble/handler.go   |  188 +++
 .../github.com/currantlabs/ble/linux/adv/const.go  |   57 +
 .../github.com/currantlabs/ble/linux/adv/packet.go |  289 ++++
 .../github.com/currantlabs/ble/linux/att/README.md |   40 +
 .../github.com/currantlabs/ble/linux/att/att.go    |   30 +
 .../currantlabs/ble/linux/att/att_gen.go           |  639 ++++++++
 .../github.com/currantlabs/ble/linux/att/attr.go   |   14 +
 .../github.com/currantlabs/ble/linux/att/client.go |  560 +++++++
 .../github.com/currantlabs/ble/linux/att/db.go     |  210 +++
 .../github.com/currantlabs/ble/linux/att/log.go    |    7 +
 .../github.com/currantlabs/ble/linux/att/server.go |  594 ++++++++
 .../github.com/currantlabs/ble/linux/device.go     |  165 +++
 .../currantlabs/ble/linux/gatt/README.md           |   47 +
 .../currantlabs/ble/linux/gatt/client.go           |  385 +++++
 .../currantlabs/ble/linux/gatt/server.go           |   83 ++
 .../github.com/currantlabs/ble/linux/hci/README.md |  116 ++
 .../github.com/currantlabs/ble/linux/hci/adv.go    |  135 ++
 .../github.com/currantlabs/ble/linux/hci/buffer.go |   74 +
 .../currantlabs/ble/linux/hci/cmd/cmd.go           |   31 +
 .../currantlabs/ble/linux/hci/cmd/cmd_gen.go       | 1562 ++++++++++++++++++++
 .../github.com/currantlabs/ble/linux/hci/conn.go   |  338 +++++
 .../github.com/currantlabs/ble/linux/hci/const.go  |   30 +
 .../github.com/currantlabs/ble/linux/hci/error.go  |  161 ++
 .../currantlabs/ble/linux/hci/evt/evt.go           |   55 +
 .../currantlabs/ble/linux/hci/evt/evt_gen.go       |  227 +++
 .../github.com/currantlabs/ble/linux/hci/gap.go    |  214 +++
 .../github.com/currantlabs/ble/linux/hci/hci.go    |  517 +++++++
 .../github.com/currantlabs/ble/linux/hci/log.go    |    7 +
 .../github.com/currantlabs/ble/linux/hci/option.go |   42 +
 .../github.com/currantlabs/ble/linux/hci/params.go |   55 +
 .../github.com/currantlabs/ble/linux/hci/signal.go |  223 +++
 .../currantlabs/ble/linux/hci/signal_gen.go        |  205 +++
 .../github.com/currantlabs/ble/linux/hci/smp.go    |   61 +
 .../currantlabs/ble/linux/hci/socket/dummy.go      |   10 +
 .../currantlabs/ble/linux/hci/socket/socket.go     |  146 ++
 .../vendor/github.com/currantlabs/ble/profile.go   |  221 +++
 newtmgr/vendor/github.com/currantlabs/ble/uuid.go  |  217 +++
 newtmgr/vendor/github.com/raff/goble/LICENSE       |   20 +
 newtmgr/vendor/github.com/raff/goble/xpc/xpc.go    |  381 +++++
 .../vendor/github.com/raff/goble/xpc/xpc_wrapper.c |   85 ++
 .../vendor/github.com/raff/goble/xpc/xpc_wrapper.h |   33 +
 newtmgr/vendor/mynewt.apache.org/newt/util/util.go |   14 +-
 .../newtmgr/nmxact/bledefs/bledefs.go              |    6 +-
 .../newtmgr/nmxact/nmble/ble_util.go               |   34 +-
 68 files changed, 10234 insertions(+), 58 deletions(-)

diff --git a/newtmgr/Godeps/Godeps.json b/newtmgr/Godeps/Godeps.json
index f35cbe9..ce5ab65 100644
--- a/newtmgr/Godeps/Godeps.json
+++ b/newtmgr/Godeps/Godeps.json
@@ -107,93 +107,93 @@
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newt/util",
-			"Comment": "mynewt_1_1_0_rc2_tag",
-			"Rev": "0e174a618b473e89b5c0d681957830f0d4b7a665"
+			"Comment": "mynewt_1_0_1_tag-26-gd70e83c",
+			"Rev": "d70e83caba3debbd8eff933308d619fe67c51dce"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newt/util/unixchild",
-			"Comment": "mynewt_1_1_0_rc2_tag",
-			"Rev": "0e174a618b473e89b5c0d681957830f0d4b7a665"
+			"Comment": "mynewt_1_0_1_tag-26-gd70e83c",
+			"Rev": "d70e83caba3debbd8eff933308d619fe67c51dce"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newt/viper",
-			"Comment": "mynewt_1_1_0_rc2_tag",
-			"Rev": "0e174a618b473e89b5c0d681957830f0d4b7a665"
+			"Comment": "mynewt_1_0_1_tag-26-gd70e83c",
+			"Rev": "d70e83caba3debbd8eff933308d619fe67c51dce"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newt/yaml",
-			"Comment": "mynewt_1_1_0_rc2_tag",
-			"Rev": "0e174a618b473e89b5c0d681957830f0d4b7a665"
+			"Comment": "mynewt_1_0_1_tag-26-gd70e83c",
+			"Rev": "d70e83caba3debbd8eff933308d619fe67c51dce"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/adv",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/bledefs",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/mgmt",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmble",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmp",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmserial",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmxutil",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/oic",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/omp",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/scan",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/sesn",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/udp",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/xact",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/xport",
-			"Comment": "mynewt_1_1_0_tag-28-ga1eb1c2",
-			"Rev": "a1eb1c28dad0c19919d624039c042de9ae63ce8a"
+			"Comment": "mynewt_1_1_0_tag-31-gf0af75a",
+			"Rev": "f0af75a43db81b781f26f3ef05d7c81322ec5a44"
 		}
 	]
 }
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/.gitignore b/newtmgr/vendor/github.com/currantlabs/ble/.gitignore
new file mode 100644
index 0000000..f8a9d56
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/.gitignore
@@ -0,0 +1,5 @@
+.*.swp
+.tags
+.tags1
+
+/examples/bin/*
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/LICENSE b/newtmgr/vendor/github.com/currantlabs/ble/LICENSE
new file mode 100644
index 0000000..0d29b8e
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2016 Currant 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 Currant 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.
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/README.md b/newtmgr/vendor/github.com/currantlabs/ble/README.md
new file mode 100644
index 0000000..28f954d
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/README.md
@@ -0,0 +1,3 @@
+# bt
+
+bt is a Bluetooth library for Go; its API is still under active development, and may change without warning.
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/addr.go b/newtmgr/vendor/github.com/currantlabs/ble/addr.go
new file mode 100644
index 0000000..d19317a
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/addr.go
@@ -0,0 +1,20 @@
+package ble
+
+import "strings"
+
+// Addr represents a network end point address.
+// It's MAC address on Linux or Device UUID on OS X.
+type Addr interface {
+	String() string
+}
+
+// NewAddr creates an Addr from string
+func NewAddr(s string) Addr {
+	return addr(strings.ToLower(s))
+}
+
+type addr string
+
+func (a addr) String() string {
+	return string(a)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/adv.go b/newtmgr/vendor/github.com/currantlabs/ble/adv.go
new file mode 100644
index 0000000..24c1228
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/adv.go
@@ -0,0 +1,28 @@
+package ble
+
+// AdvHandler handles advertisement.
+type AdvHandler func(a Advertisement)
+
+// AdvFilter returns true if the advertisement matches specified condition.
+type AdvFilter func(a Advertisement) bool
+
+// Advertisement ...
+type Advertisement interface {
+	LocalName() string
+	ManufacturerData() []byte
+	ServiceData() []ServiceData
+	Services() []UUID
+	OverflowService() []UUID
+	TxPowerLevel() int
+	Connectable() bool
+	SolicitedService() []UUID
+
+	RSSI() int
+	Address() Addr
+}
+
+// ServiceData ...
+type ServiceData struct {
+	UUID UUID
+	Data []byte
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/client.go b/newtmgr/vendor/github.com/currantlabs/ble/client.go
new file mode 100644
index 0000000..e21ccf1
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/client.go
@@ -0,0 +1,69 @@
+package ble
+
+// A Client is a GATT client.
+type Client interface {
+	// Address returns platform specific unique ID of the remote peripheral, e.g. MAC on Linux, Client UUID on OS X.
+	Address() Addr
+
+	// 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
+
+	// Profile returns discovered profile.
+	Profile() *Profile
+
+	// DiscoverProfile discovers the whole hierachy of a server.
+	DiscoverProfile(force bool) (*Profile, error)
+
+	// DiscoverServices finds all the primary services on a server. [Vol 3, Part G, 4.4.1]
+	// If filter is specified, only filtered services are returned.
+	DiscoverServices(filter []UUID) ([]*Service, error)
+
+	// DiscoverIncludedServices finds the included services of a service. [Vol 3, Part G, 4.5.1]
+	// If filter is specified, only filtered services are returned.
+	DiscoverIncludedServices(filter []UUID, s *Service) ([]*Service, error)
+
+	// DiscoverCharacteristics finds all the characteristics within a service. [Vol 3, Part G, 4.6.1]
+	// If filter is specified, only filtered characteristics are returned.
+	DiscoverCharacteristics(filter []UUID, s *Service) ([]*Characteristic, error)
+
+	// DiscoverDescriptors finds all the descriptors within a characteristic. [Vol 3, Part G, 4.7.1]
+	// If filter is specified, only filtered descriptors are returned.
+	DiscoverDescriptors(filter []UUID, c *Characteristic) ([]*Descriptor, error)
+
+	// ReadCharacteristic reads a characteristic value from a server. [Vol 3, Part G, 4.8.1]
+	ReadCharacteristic(c *Characteristic) ([]byte, error)
+
+	// ReadLongCharacteristic reads a characteristic value which is longer than the MTU. [Vol 3, Part G, 4.8.3]
+	ReadLongCharacteristic(c *Characteristic) ([]byte, error)
+
+	// WriteCharacteristic writes a characteristic value to a server. [Vol 3, Part G, 4.9.3]
+	WriteCharacteristic(c *Characteristic, value []byte, noRsp bool) error
+
+	// ReadDescriptor reads a characteristic descriptor from a server. [Vol 3, Part G, 4.12.1]
+	ReadDescriptor(d *Descriptor) ([]byte, error)
+
+	// WriteDescriptor writes a characteristic descriptor to a server. [Vol 3, Part G, 4.12.3]
+	WriteDescriptor(d *Descriptor, v []byte) error
+
+	// ReadRSSI retrieves the current RSSI value of remote peripheral. [Vol 2, Part E, 7.5.4]
+	ReadRSSI() int
+
+	// ExchangeMTU set the ATT_MTU to the maximum possible value that can be supported by both devices [Vol 3, Part G, 4.3.1]
+	ExchangeMTU(rxMTU int) (txMTU int, err error)
+
+	// Subscribe subscribes to indication (if ind is set true), or notification of a characteristic value. [Vol 3, Part G, 4.10 & 4.11]
+	Subscribe(c *Characteristic, ind bool, h NotificationHandler) error
+
+	// Unsubscribe unsubscribes to indication (if ind is set true), or notification of a specified characteristic value. [Vol 3, Part G, 4.10 & 4.11]
+	Unsubscribe(c *Characteristic, ind bool) error
+
+	// ClearSubscriptions clears all subscriptions to notifications and indications.
+	ClearSubscriptions() error
+
+	// CancelConnection disconnects the connection.
+	CancelConnection() error
+
+	// Disconnected returns a receiving channel, which is closed when the client disconnects.
+	Disconnected() <-chan struct{}
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/conn.go b/newtmgr/vendor/github.com/currantlabs/ble/conn.go
new file mode 100644
index 0000000..1ddb3a9
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/conn.go
@@ -0,0 +1,39 @@
+package ble
+
+import (
+	"io"
+
+	"golang.org/x/net/context"
+)
+
+// Conn implements a L2CAP connection.
+type Conn interface {
+	io.ReadWriteCloser
+
+	// Context returns the context that is used by this Conn.
+	Context() context.Context
+
+	// SetContext sets the context that is used by this Conn.
+	SetContext(ctx context.Context)
+
+	// LocalAddr returns local device's address.
+	LocalAddr() Addr
+
+	// RemoteAddr returns remote device's address.
+	RemoteAddr() Addr
+
+	// RxMTU returns the ATT_MTU which the local device is capable of accepting.
+	RxMTU() int
+
+	// SetRxMTU sets the ATT_MTU which the local device is capable of accepting.
+	SetRxMTU(mtu int)
+
+	// TxMTU returns the ATT_MTU which the remote device is capable of accepting.
+	TxMTU() int
+
+	// SetTxMTU sets the ATT_MTU which the remote device is capable of accepting.
+	SetTxMTU(mtu int)
+
+	// Disconnected returns a receiving channel, which is closed when the connection disconnects.
+	Disconnected() <-chan struct{}
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/const.go b/newtmgr/vendor/github.com/currantlabs/ble/const.go
new file mode 100644
index 0000000..f4c142b
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/const.go
@@ -0,0 +1,33 @@
+package ble
+
+// DefaultMTU defines the default MTU of ATT protocol including 3 bytes of ATT header.
+const DefaultMTU = 23
+
+// MaxMTU is maximum of ATT_MTU, which is 512 bytes of value length, plus 3 bytes of ATT header.
+// The maximum length of an attribute value shall be 512 octets [Vol 3, Part F, 3.2.9]
+const MaxMTU = 512 + 3
+
+// UUIDs ...
+var (
+	GAPUUID         = UUID16(0x1800) // Generic Access
+	GATTUUID        = UUID16(0x1801) // Generic Attribute
+	CurrentTimeUUID = UUID16(0x1805) // Current Time Service
+	DeviceInfoUUID  = UUID16(0x180A) // Device Information
+	BatteryUUID     = UUID16(0x180F) // Battery Service
+	HIDUUID         = UUID16(0x1812) // Human Interface Device
+
+	PrimaryServiceUUID   = UUID16(0x2800)
+	SecondaryServiceUUID = UUID16(0x2801)
+	IncludeUUID          = UUID16(0x2802)
+	CharacteristicUUID   = UUID16(0x2803)
+
+	ClientCharacteristicConfigUUID = UUID16(0x2902)
+	ServerCharacteristicConfigUUID = UUID16(0x2903)
+
+	DeviceNameUUID        = UUID16(0x2A00)
+	AppearanceUUID        = UUID16(0x2A01)
+	PeripheralPrivacyUUID = UUID16(0x2A02)
+	ReconnectionAddrUUID  = UUID16(0x2A03)
+	PeferredParamsUUID    = UUID16(0x2A04)
+	ServiceChangedUUID    = UUID16(0x2A05)
+)
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/adv.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/adv.go
new file mode 100644
index 0000000..b7af334
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/adv.go
@@ -0,0 +1,73 @@
+package darwin
+
+import (
+	"github.com/currantlabs/ble"
+	"github.com/raff/goble/xpc"
+)
+
+type adv struct {
+	args xpc.Dict
+	ad   xpc.Dict
+}
+
+func (a *adv) LocalName() string {
+	return a.ad.GetString("kCBAdvDataLocalName", a.args.GetString("kCBMsgArgName", ""))
+}
+
+func (a *adv) ManufacturerData() []byte {
+	return a.ad.GetBytes("kCBAdvDataManufacturerData", nil)
+}
+
+func (a *adv) ServiceData() []ble.ServiceData {
+	xSDs, ok := a.ad["kCBAdvDataServiceData"]
+	if !ok {
+		return nil
+	}
+
+	xSD := xSDs.(xpc.Array)
+	var sd []ble.ServiceData
+	for i := 0; i < len(xSD); i += 2 {
+		sd = append(
+			sd, ble.ServiceData{
+				UUID: ble.UUID(xSD[i].([]byte)),
+				Data: xSD[i+1].([]byte),
+			})
+	}
+	return sd
+}
+
+func (a *adv) Services() []ble.UUID {
+	xUUIDs, ok := a.ad["kCBAdvDataServiceUUIDs"]
+	if !ok {
+		return nil
+	}
+	var uuids []ble.UUID
+	for _, xUUID := range xUUIDs.(xpc.Array) {
+		uuids = append(uuids, ble.UUID(ble.Reverse(xUUID.([]byte))))
+	}
+	return uuids
+}
+
+func (a *adv) OverflowService() []ble.UUID {
+	return nil // TODO
+}
+
+func (a *adv) TxPowerLevel() int {
+	return a.ad.GetInt("kCBAdvDataTxPowerLevel", 0)
+}
+
+func (a *adv) SolicitedService() []ble.UUID {
+	return nil // TODO
+}
+
+func (a *adv) Connectable() bool {
+	return a.ad.GetInt("kCBAdvDataIsConnectable", 0) > 0
+}
+
+func (a *adv) RSSI() int {
+	return a.args.GetInt("kCBMsgArgRssi", 0)
+}
+
+func (a *adv) Address() ble.Addr {
+	return xpc.UUID(a.args.MustGetUUID("kCBMsgArgDeviceUUID"))
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/client.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/client.go
new file mode 100644
index 0000000..668b408
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/client.go
@@ -0,0 +1,282 @@
+package darwin
+
+import (
+	"fmt"
+
+	"github.com/currantlabs/ble"
+	"github.com/raff/goble/xpc"
+)
+
+// A Client is a GATT client.
+type Client struct {
+	profile *ble.Profile
+	name    string
+
+	id   xpc.UUID
+	conn *conn
+}
+
+// NewClient ...
+func NewClient(c ble.Conn) (*Client, error) {
+	return &Client{
+		conn: c.(*conn),
+		id:   xpc.MakeUUID(c.RemoteAddr().String()),
+	}, nil
+}
+
+// Address returns UUID of the remote peripheral.
+func (cln *Client) Address() ble.Addr {
+	return cln.conn.RemoteAddr()
+}
+
+// Name returns the name of the remote peripheral.
+// This can be the advertised name, if exists, or the GAP device name, which takes priority.
+func (cln *Client) Name() string {
+	return cln.name
+}
+
+// Profile returns the discovered profile.
+func (cln *Client) Profile() *ble.Profile {
+	return cln.profile
+}
+
+// DiscoverProfile discovers the whole hierachy of a server.
+func (cln *Client) DiscoverProfile(force bool) (*ble.Profile, error) {
+	if cln.profile != nil && !force {
+		return cln.profile, nil
+	}
+	ss, err := cln.DiscoverServices(nil)
+	if err != nil {
+		return nil, fmt.Errorf("can't discover services: %s\n", err)
+	}
+	for _, s := range ss {
+		cs, err := cln.DiscoverCharacteristics(nil, s)
+		if err != nil {
+			return nil, fmt.Errorf("can't discover characteristics: %s\n", err)
+		}
+		for _, c := range cs {
+			_, err := cln.DiscoverDescriptors(nil, c)
+			if err != nil {
+				return nil, fmt.Errorf("can't discover descriptors: %s\n", err)
+			}
+		}
+	}
+	cln.profile = &ble.Profile{Services: ss}
+	return cln.profile, nil
+}
+
+// DiscoverServices finds all the primary services on a server. [Vol 3, Part G, 4.4.1]
+// If filter is specified, only filtered services are returned.
+func (cln *Client) DiscoverServices(ss []ble.UUID) ([]*ble.Service, error) {
+	rsp := cln.conn.sendReq(45, xpc.Dict{
+		"kCBMsgArgDeviceUUID": cln.id,
+		"kCBMsgArgUUIDs":      uuidSlice(ss),
+	})
+	if rsp.err() != nil {
+		return nil, rsp.err()
+	}
+	svcs := []*ble.Service{}
+	for _, xss := range rsp.services() {
+		xs := msg(xss.(xpc.Dict))
+		svcs = append(svcs, &ble.Service{
+			UUID:      ble.MustParse(xs.uuid()),
+			Handle:    uint16(xs.serviceStartHandle()),
+			EndHandle: uint16(xs.serviceEndHandle()),
+		})
+	}
+	if cln.profile == nil {
+		cln.profile = &ble.Profile{Services: svcs}
+	}
+	return svcs, nil
+}
+
+// DiscoverIncludedServices finds the included services of a service. [Vol 3, Part G, 4.5.1]
+// If filter is specified, only filtered services are returned.
+func (cln *Client) DiscoverIncludedServices(ss []ble.UUID, s *ble.Service) ([]*ble.Service, error) {
+	rsp := cln.conn.sendReq(60, xpc.Dict{
+		"kCBMsgArgDeviceUUID":         cln.id,
+		"kCBMsgArgServiceStartHandle": s.Handle,
+		"kCBMsgArgServiceEndHandle":   s.EndHandle,
+		"kCBMsgArgUUIDs":              uuidSlice(ss),
+	})
+	if rsp.err() != nil {
+		return nil, rsp.err()
+	}
+	return nil, ble.ErrNotImplemented
+}
+
+// DiscoverCharacteristics finds all the characteristics within a service. [Vol 3, Part G, 4.6.1]
+// If filter is specified, only filtered characteristics are returned.
+func (cln *Client) DiscoverCharacteristics(cs []ble.UUID, s *ble.Service) ([]*ble.Characteristic, error) {
+	rsp := cln.conn.sendReq(62, xpc.Dict{
+		"kCBMsgArgDeviceUUID":         cln.id,
+		"kCBMsgArgServiceStartHandle": s.Handle,
+		"kCBMsgArgServiceEndHandle":   s.EndHandle,
+		"kCBMsgArgUUIDs":              uuidSlice(cs),
+	})
+	if rsp.err() != nil {
+		return nil, rsp.err()
+	}
+	for _, xcs := range rsp.characteristics() {
+		xc := msg(xcs.(xpc.Dict))
+		s.Characteristics = append(s.Characteristics, &ble.Characteristic{
+			UUID:        ble.MustParse(xc.uuid()),
+			Property:    ble.Property(xc.characteristicProperties()),
+			Handle:      uint16(xc.characteristicHandle()),
+			ValueHandle: uint16(xc.characteristicValueHandle()),
+		})
+	}
+	return s.Characteristics, nil
+}
+
+// DiscoverDescriptors finds all the descriptors within a characteristic. [Vol 3, Part G, 4.7.1]
+// If filter is specified, only filtered descriptors are returned.
+func (cln *Client) DiscoverDescriptors(ds []ble.UUID, c *ble.Characteristic) ([]*ble.Descriptor, error) {
+	rsp := cln.conn.sendReq(70, xpc.Dict{
+		"kCBMsgArgDeviceUUID":                cln.id,
+		"kCBMsgArgCharacteristicHandle":      c.Handle,
+		"kCBMsgArgCharacteristicValueHandle": c.ValueHandle,
+		"kCBMsgArgUUIDs":                     uuidSlice(ds),
+	})
+	for _, xds := range rsp.descriptors() {
+		xd := msg(xds.(xpc.Dict))
+		c.Descriptors = append(c.Descriptors, &ble.Descriptor{
+			UUID:   ble.MustParse(xd.uuid()),
+			Handle: uint16(xd.descriptorHandle()),
+		})
+	}
+	return c.Descriptors, nil
+}
+
+// ReadCharacteristic reads a characteristic value from a server. [Vol 3, Part G, 4.8.1]
+func (cln *Client) ReadCharacteristic(c *ble.Characteristic) ([]byte, error) {
+	rsp := cln.conn.sendReq(65, xpc.Dict{
+		"kCBMsgArgDeviceUUID":                cln.id,
+		"kCBMsgArgCharacteristicHandle":      c.Handle,
+		"kCBMsgArgCharacteristicValueHandle": c.ValueHandle,
+	})
+	if rsp.err() != nil {
+		return nil, rsp.err()
+	}
+	return rsp.data(), nil
+}
+
+// ReadLongCharacteristic reads a characteristic value which is longer than the MTU. [Vol 3, Part G, 4.8.3]
+func (cln *Client) ReadLongCharacteristic(c *ble.Characteristic) ([]byte, error) {
+	return nil, ble.ErrNotImplemented
+}
+
+// WriteCharacteristic writes a characteristic value to a server. [Vol 3, Part G, 4.9.3]
+func (cln *Client) WriteCharacteristic(c *ble.Characteristic, b []byte, noRsp bool) error {
+	args := xpc.Dict{
+		"kCBMsgArgDeviceUUID":                cln.id,
+		"kCBMsgArgCharacteristicHandle":      c.Handle,
+		"kCBMsgArgCharacteristicValueHandle": c.ValueHandle,
+		"kCBMsgArgData":                      b,
+		"kCBMsgArgType":                      map[bool]int{false: 0, true: 1}[noRsp],
+	}
+	if noRsp {
+		cln.conn.sendCmd(66, args)
+		return nil
+	}
+	return cln.conn.sendReq(66, args).err()
+}
+
+// ReadDescriptor reads a characteristic descriptor from a server. [Vol 3, Part G, 4.12.1]
+func (cln *Client) ReadDescriptor(d *ble.Descriptor) ([]byte, error) {
+	rsp := cln.conn.sendReq(77, xpc.Dict{
+		"kCBMsgArgDeviceUUID":       cln.id,
+		"kCBMsgArgDescriptorHandle": d.Handle,
+	})
+	if rsp.err() != nil {
+		return nil, rsp.err()
+	}
+	return rsp.data(), nil
+}
+
+// WriteDescriptor writes a characteristic descriptor to a server. [Vol 3, Part G, 4.12.3]
+func (cln *Client) WriteDescriptor(d *ble.Descriptor, b []byte) error {
+	rsp := cln.conn.sendReq(78, xpc.Dict{
+		"kCBMsgArgDeviceUUID":       cln.id,
+		"kCBMsgArgDescriptorHandle": d.Handle,
+		"kCBMsgArgData":             b,
+	})
+	return rsp.err()
+}
+
+// ReadRSSI retrieves the current RSSI value of remote peripheral. [Vol 2, Part E, 7.5.4]
+func (cln *Client) ReadRSSI() int {
+	rsp := cln.conn.sendReq(44, xpc.Dict{"kCBMsgArgDeviceUUID": cln.id})
+	if rsp.err() != nil {
+		return 0
+	}
+	return rsp.rssi()
+}
+
+// ExchangeMTU set the ATT_MTU to the maximum possible value that can be
+// supported by both devices [Vol 3, Part G, 4.3.1]
+func (cln *Client) ExchangeMTU(mtu int) (int, error) {
+	// TODO: find the xpc command to tell OS X the rxMTU we can handle.
+	return cln.conn.TxMTU(), nil
+}
+
+// Subscribe subscribes to indication (if ind is set true), or notification of a
+// characteristic value. [Vol 3, Part G, 4.10 & 4.11]
+func (cln *Client) Subscribe(c *ble.Characteristic, ind bool, fn ble.NotificationHandler) error {
+	cln.conn.Lock()
+	defer cln.conn.Unlock()
+	cln.conn.subs[c.Handle] = &sub{fn: fn, char: c}
+	rsp := cln.conn.sendReq(68, xpc.Dict{
+		"kCBMsgArgDeviceUUID":                cln.id,
+		"kCBMsgArgCharacteristicHandle":      c.Handle,
+		"kCBMsgArgCharacteristicValueHandle": c.ValueHandle,
+		"kCBMsgArgState":                     1,
+	})
+	if rsp.err() != nil {
+		delete(cln.conn.subs, c.Handle)
+		return rsp.err()
+	}
+	return nil
+}
+
+// Unsubscribe unsubscribes to indication (if ind is set true), or notification
+// of a specified characteristic value. [Vol 3, Part G, 4.10 & 4.11]
+func (cln *Client) Unsubscribe(c *ble.Characteristic, ind bool) error {
+	rsp := cln.conn.sendReq(68, xpc.Dict{
+		"kCBMsgArgDeviceUUID":                cln.id,
+		"kCBMsgArgCharacteristicHandle":      c.Handle,
+		"kCBMsgArgCharacteristicValueHandle": c.ValueHandle,
+		"kCBMsgArgState":                     0,
+	})
+	if rsp.err() != nil {
+		return rsp.err()
+	}
+	cln.conn.Lock()
+	defer cln.conn.Unlock()
+	delete(cln.conn.subs, c.Handle)
+	return nil
+}
+
+// ClearSubscriptions clears all subscriptions to notifications and indications.
+func (cln *Client) ClearSubscriptions() error {
+	for _, s := range cln.conn.subs {
+		cln.Unsubscribe(s.char, false)
+	}
+	return nil
+}
+
+// CancelConnection disconnects the connection.
+func (cln *Client) CancelConnection() error {
+	rsp := cln.conn.sendReq(32, xpc.Dict{"kCBMsgArgDeviceUUID": cln.id})
+	return rsp.err()
+}
+
+// Disconnected returns a receiving channel, which is closed when the client disconnects.
+func (cln *Client) Disconnected() <-chan struct{} {
+	return cln.conn.Disconnected()
+}
+
+type sub struct {
+	fn   ble.NotificationHandler
+	char *ble.Characteristic
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/conn.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/conn.go
new file mode 100644
index 0000000..c0abf35
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/conn.go
@@ -0,0 +1,135 @@
+package darwin
+
+import (
+	"sync"
+
+	"golang.org/x/net/context"
+
+	"github.com/currantlabs/ble"
+	"github.com/raff/goble/xpc"
+)
+
+func newConn(d *Device, a ble.Addr) *conn {
+	return &conn{
+		dev:   d,
+		rxMTU: 23,
+		txMTU: 23,
+		addr:  a,
+		done:  make(chan struct{}),
+
+		notifiers: make(map[uint16]ble.Notifier),
+		subs:      make(map[uint16]*sub),
+
+		rspc: make(chan msg),
+	}
+}
+
+type conn struct {
+	sync.RWMutex
+
+	dev   *Device
+	role  int
+	ctx   context.Context
+	rxMTU int
+	txMTU int
+	addr  ble.Addr
+	done  chan struct{}
+
+	rspc chan msg
+
+	connInterval       int
+	connLatency        int
+	supervisionTimeout int
+
+	notifiers map[uint16]ble.Notifier // central connection only
+
+	subs map[uint16]*sub
+}
+
+func (c *conn) Context() context.Context {
+	return c.ctx
+}
+
+func (c *conn) SetContext(ctx context.Context) {
+	c.ctx = ctx
+}
+
+func (c *conn) LocalAddr() ble.Addr {
+	// return c.dev.Address()
+	return c.addr // FIXME
+}
+
+func (c *conn) RemoteAddr() ble.Addr {
+	return c.addr
+}
+
+func (c *conn) RxMTU() int {
+	return c.rxMTU
+}
+
+func (c *conn) SetRxMTU(mtu int) {
+	c.rxMTU = mtu
+}
+
+func (c *conn) TxMTU() int {
+	return c.txMTU
+}
+
+func (c *conn) SetTxMTU(mtu int) {
+	c.txMTU = mtu
+}
+
+func (c *conn) Read(b []byte) (int, error) {
+	return 0, nil
+}
+
+func (c *conn) Write(b []byte) (int, error) {
+	return 0, nil
+}
+
+func (c *conn) Close() error {
+	return nil
+}
+
+// Disconnected returns a receiving channel, which is closed when the connection disconnects.
+func (c *conn) Disconnected() <-chan struct{} {
+	return c.done
+}
+
+// server (peripheral)
+func (c *conn) subscribed(char *ble.Characteristic) {
+	h := char.Handle
+	if _, found := c.notifiers[h]; found {
+		return
+	}
+	send := func(b []byte) (int, error) {
+		c.dev.sendCmd(c.dev.pm, 15, xpc.Dict{
+			"kCBMsgArgUUIDs":       [][]byte{},
+			"kCBMsgArgAttributeID": h,
+			"kCBMsgArgData":        b,
+		})
+		return len(b), nil
+	}
+	n := ble.NewNotifier(send)
+	c.notifiers[h] = n
+	req := ble.NewRequest(c, nil, 0) // convey *conn to user handler.
+	go char.NotifyHandler.ServeNotify(req, n)
+}
+
+// server (peripheral)
+func (c *conn) unsubscribed(char *ble.Characteristic) {
+	if n, found := c.notifiers[char.Handle]; found {
+		n.Close()
+		delete(c.notifiers, char.Handle)
+	}
+}
+
+func (c *conn) sendReq(id int, args xpc.Dict) msg {
+	c.dev.sendCmd(c.dev.cm, id, args)
+	m := <-c.rspc
+	return msg(m.args())
+}
+
+func (c *conn) sendCmd(id int, args xpc.Dict) {
+	c.dev.sendCmd(c.dev.pm, id, args)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/device.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/device.go
new file mode 100644
index 0000000..1275394
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/device.go
@@ -0,0 +1,515 @@
+package darwin
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"log"
+	"time"
+
+	"github.com/pkg/errors"
+	"github.com/raff/goble/xpc"
+	"golang.org/x/net/context"
+
+	"github.com/currantlabs/ble"
+)
+
+const (
+	evtStateChanged               = 6
+	evtAdvertisingStarted         = 16
+	evtAdvertisingStopped         = 17
+	evtServiceAdded               = 18
+	evtReadRequest                = 19
+	evtWriteRequest               = 20
+	evtSubscribe                  = 21
+	evtUnubscribe                 = 22
+	evtConfirmation               = 23
+	evtPeripheralDiscovered       = 37
+	evtPeripheralConnected        = 38
+	evtPeripheralDisconnected     = 40
+	evtATTMTU                     = 53
+	evtRSSIRead                   = 55
+	evtServiceDiscovered          = 56
+	evtIncludedServicesDiscovered = 63
+	evtCharacteristicsDiscovered  = 64
+	evtCharacteristicRead         = 71
+	evtCharacteristicWritten      = 72
+	evtNotificationValueSet       = 74
+	evtDescriptorsDiscovered      = 76
+	evtDescriptorRead             = 79
+	evtDescriptorWritten          = 80
+	evtSleveConnectionComplete    = 81
+	evtMasterConnectionComplete   = 82
+)
+
+// Device is either a Peripheral or Central device.
+type Device struct {
+	pm xpc.XPC // peripheralManager
+	cm xpc.XPC // centralManager
+
+	role int // 1: peripheralManager (server), 0: centralManager (client)
+
+	rspc chan msg
+
+	conns map[string]*conn
+
+	// Only used in client/centralManager implementation
+	advHandler ble.AdvHandler
+	chConn     chan *conn
+
+	// Only used in server/peripheralManager implementation
+	chars map[int]*ble.Characteristic
+	base  int
+}
+
+// NewDevice returns a BLE device.
+func NewDevice(opts ...Option) (*Device, error) {
+	d := &Device{
+		rspc:   make(chan msg),
+		conns:  make(map[string]*conn),
+		chConn: make(chan *conn),
+		chars:  make(map[int]*ble.Characteristic),
+		base:   1,
+	}
+	if err := d.Option(opts...); err != nil {
+		return nil, err
+	}
+
+	d.pm = xpc.XpcConnect("com.apple.blued", d)
+	d.cm = xpc.XpcConnect("com.apple.blued", d)
+
+	return d, errors.Wrap(d.Init(), "can't init")
+}
+
+// Option sets the options specified.
+func (d *Device) Option(opts ...Option) error {
+	var err error
+	for _, opt := range opts {
+		err = opt(d)
+	}
+	return err
+}
+
+// Init ...
+func (d *Device) Init() error {
+	rsp := d.sendReq(d.cm, 1, xpc.Dict{
+		"kCBMsgArgName": fmt.Sprintf("gopher-%v", time.Now().Unix()),
+		"kCBMsgArgOptions": xpc.Dict{
+			"kCBInitOptionShowPowerAlert": 1,
+		},
+		"kCBMsgArgType": 0,
+	})
+	s := State(rsp.state())
+	if s != StatePoweredOn {
+		return fmt.Errorf("state: %s", s)
+	}
+
+	rsp = d.sendReq(d.pm, 1, xpc.Dict{
+		"kCBMsgArgName": fmt.Sprintf("gopher-%v", time.Now().Unix()),
+		"kCBMsgArgOptions": xpc.Dict{
+			"kCBInitOptionShowPowerAlert": 1,
+		},
+		"kCBMsgArgType": 1,
+	})
+	s = State(rsp.state())
+	if s != StatePoweredOn {
+		return fmt.Errorf("state: %s", s)
+	}
+	return nil
+}
+
+// AdvertiseMfgData ...
+func (d *Device) AdvertiseMfgData(ctx context.Context, id uint16, md []byte) error {
+	l := len(md)
+	b := []byte{byte(l + 3), 0xFF, uint8(id), uint8(id >> 8)}
+	if err := d.sendReq(d.pm, 8, xpc.Dict{
+		"kCBAdvDataAppleMfgData": append(b, md...),
+	}).err(); err != nil {
+		return errors.Wrap(err, "can't advertise")
+	}
+	<-ctx.Done()
+	return ctx.Err()
+}
+
+// AdvertiseServiceData16 advertises data associated with a 16bit service uuid
+func (d *Device) AdvertiseServiceData16(ctx context.Context, id uint16, b []byte) error {
+	l := len(b)
+	prefix := []byte{
+		0x03, 0x03, uint8(id), uint8(id >> 8),
+		byte(l + 3), 0x16, uint8(id), uint8(id >> 8),
+	}
+	if err := d.sendReq(d.pm, 8, xpc.Dict{
+		"kCBAdvDataAppleMfgData": append(prefix, b...),
+	}).err(); err != nil {
+		return errors.Wrap(err, "can't advertise")
+	}
+	<-ctx.Done()
+	return ctx.Err()
+}
+
+// AdvertiseNameAndServices advertises name and specifid service UUIDs.
+func (d *Device) AdvertiseNameAndServices(ctx context.Context, name string, ss ...ble.UUID) error {
+	if err := d.sendReq(d.pm, 8, xpc.Dict{
+		"kCBAdvDataLocalName":    name,
+		"kCBAdvDataServiceUUIDs": uuidSlice(ss)},
+	).err(); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	d.stopAdvertising()
+	return ctx.Err()
+}
+
+// AdvertiseIBeaconData advertises iBeacon packet with specified manufacturer data.
+func (d *Device) AdvertiseIBeaconData(ctx context.Context, md []byte) error {
+	var utsname xpc.Utsname
+	xpc.Uname(&utsname)
+
+	if utsname.Release >= "14." {
+		ibeaconCode := []byte{0x02, 0x15}
+		return d.AdvertiseMfgData(ctx, 0x004C, append(ibeaconCode, md...))
+	}
+	if err := d.sendReq(d.pm, 8, xpc.Dict{"kCBAdvDataAppleBeaconKey": md}).err(); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	return d.stopAdvertising()
+}
+
+// AdvertiseIBeacon advertises iBeacon packet.
+func (d *Device) AdvertiseIBeacon(ctx context.Context, u ble.UUID, major, minor uint16, pwr int8) error {
+	b := make([]byte, 21)
+	copy(b, ble.Reverse(u))                   // 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(ctx, b)
+}
+
+// stopAdvertising stops advertising.
+func (d *Device) stopAdvertising() error {
+	return errors.Wrap(d.sendReq(d.pm, 9, nil).err(), "can't stop advertising")
+}
+
+// Scan ...
+func (d *Device) Scan(ctx context.Context, allowDup bool, h ble.AdvHandler) error {
+	d.advHandler = h
+	if err := d.sendCmd(d.cm, 29, xpc.Dict{
+		// "kCBMsgArgUUIDs": uuidSlice(ss),
+		"kCBMsgArgOptions": xpc.Dict{
+			"kCBScanOptionAllowDuplicates": map[bool]int{true: 1, false: 0}[allowDup],
+		},
+	}); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	if err := d.stopScanning(); err != nil {
+		return errors.Wrap(ctx.Err(), err.Error())
+	}
+	return ctx.Err()
+}
+
+// stopAdvertising stops advertising.
+func (d *Device) stopScanning() error {
+	return errors.Wrap(d.sendCmd(d.cm, 30, nil), "can't stop scanning")
+}
+
+// RemoveAllServices removes all services of device's
+func (d *Device) RemoveAllServices() error {
+	return d.sendCmd(d.pm, 12, nil)
+}
+
+// AddService adds a service to device's database.
+// The following services are ignored as they are provided by OS X.
+//
+// 0x1800 (Generic Access)
+// 0x1801 (Generic Attribute)
+// 0x1805 (Current Time Service)
+// 0x180A (Device Information)
+// 0x180F (Battery Service)
+// 0x1812 (Human Interface Device)
+func (d *Device) AddService(s *ble.Service) error {
+	if s.UUID.Equal(ble.GAPUUID) ||
+		s.UUID.Equal(ble.GATTUUID) ||
+		s.UUID.Equal(ble.CurrentTimeUUID) ||
+		s.UUID.Equal(ble.DeviceInfoUUID) ||
+		s.UUID.Equal(ble.BatteryUUID) ||
+		s.UUID.Equal(ble.HIDUUID) {
+		return nil
+	}
+	xs := xpc.Dict{
+		"kCBMsgArgAttributeID":     d.base,
+		"kCBMsgArgAttributeIDs":    []int{},
+		"kCBMsgArgCharacteristics": nil,
+		"kCBMsgArgType":            1, // 1 => primary, 0 => excluded
+		"kCBMsgArgUUID":            ble.Reverse(s.UUID),
+	}
+	d.base++
+
+	xcs := xpc.Array{}
+	for _, c := range s.Characteristics {
+		props := 0
+		perm := 0
+		if c.Property&ble.CharRead != 0 {
+			props |= 0x02
+			if ble.CharRead&c.Secure != 0 {
+				perm |= 0x04
+			} else {
+				perm |= 0x01
+			}
+		}
+		if c.Property&ble.CharWriteNR != 0 {
+			props |= 0x04
+			if c.Secure&ble.CharWriteNR != 0 {
+				perm |= 0x08
+			} else {
+				perm |= 0x02
+			}
+		}
+		if c.Property&ble.CharWrite != 0 {
+			props |= 0x08
+			if c.Secure&ble.CharWrite != 0 {
+				perm |= 0x08
+			} else {
+				perm |= 0x02
+			}
+		}
+		if c.Property&ble.CharNotify != 0 {
+			if c.Secure&ble.CharNotify != 0 {
+				props |= 0x100
+			} else {
+				props |= 0x10
+			}
+		}
+		if c.Property&ble.CharIndicate != 0 {
+			if c.Secure&ble.CharIndicate != 0 {
+				props |= 0x200
+			} else {
+				props |= 0x20
+			}
+		}
+
+		xc := xpc.Dict{
+			"kCBMsgArgAttributeID":              d.base,
+			"kCBMsgArgUUID":                     ble.Reverse(c.UUID),
+			"kCBMsgArgAttributePermissions":     perm,
+			"kCBMsgArgCharacteristicProperties": props,
+			"kCBMsgArgData":                     c.Value,
+		}
+		c.Handle = uint16(d.base)
+		d.chars[d.base] = c
+		d.base++
+
+		xds := xpc.Array{}
+		for _, d := range c.Descriptors {
+			if d.UUID.Equal(ble.ClientCharacteristicConfigUUID) {
+				// skip CCCD
+				continue
+			}
+			xd := xpc.Dict{
+				"kCBMsgArgData": d.Value,
+				"kCBMsgArgUUID": ble.Reverse(d.UUID),
+			}
+			xds = append(xds, xd)
+		}
+		xc["kCBMsgArgDescriptors"] = xds
+		xcs = append(xcs, xc)
+	}
+	xs["kCBMsgArgCharacteristics"] = xcs
+
+	return d.sendReq(d.pm, 10, xs).err()
+}
+
+// SetServices ...
+func (d *Device) SetServices(ss []*ble.Service) error {
+	if err := d.RemoveAllServices(); err != nil {
+		return nil
+	}
+	for _, s := range ss {
+		if err := d.AddService(s); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// Dial ...
+func (d *Device) Dial(ctx context.Context, a ble.Addr) (ble.Client, error) {
+	d.sendCmd(d.cm, 31, xpc.Dict{
+		"kCBMsgArgDeviceUUID": xpc.MakeUUID(a.String()),
+		"kCBMsgArgOptions": xpc.Dict{
+			"kCBConnectOptionNotifyOnDisconnection": 1,
+		},
+	})
+	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	case c := <-d.chConn:
+		c.SetContext(ctx)
+		return NewClient(c)
+	}
+}
+
+// Stop ...
+func (d *Device) Stop() error {
+	return nil
+}
+
+// HandleXpcEvent process Device events and asynchronous errors.
+func (d *Device) HandleXpcEvent(event xpc.Dict, err error) {
+	if err != nil {
+		log.Println("error:", err)
+		return
+	}
+	m := msg(event)
+	args := msg(msg(event).args())
+	logger.Info("recv", "id", m.id(), "args", fmt.Sprintf("%v", m.args()))
+
+	switch m.id() {
+	case // Device event
+		evtStateChanged,
+		evtAdvertisingStarted,
+		evtAdvertisingStopped,
+		evtServiceAdded:
+		d.rspc <- args
+
+	case evtPeripheralDiscovered:
+		if d.advHandler == nil {
+			break
+		}
+		a := &adv{args: m.args(), ad: args.advertisementData()}
+		go d.advHandler(a)
+
+	case evtConfirmation:
+		// log.Printf("confirmed: %d", args.attributeID())
+
+	case evtATTMTU:
+		d.conn(args).SetTxMTU(args.attMTU())
+
+	case evtSleveConnectionComplete:
+		// remote peripheral is connected.
+		fallthrough
+	case evtMasterConnectionComplete:
+		// remote central is connected.
+
+		// Could be LEConnectionComplete or LEConnectionUpdateComplete.
+		c := d.conn(args)
+		c.connInterval = args.connectionInterval()
+		c.connLatency = args.connectionLatency()
+		c.supervisionTimeout = args.supervisionTimeout()
+
+	case evtReadRequest:
+		aid := args.attributeID()
+		char := d.chars[aid]
+		v := char.Value
+		if v == nil {
+			c := d.conn(args)
+			req := ble.NewRequest(c, nil, args.offset())
+			buf := bytes.NewBuffer(make([]byte, 0, c.txMTU-1))
+			rsp := ble.NewResponseWriter(buf)
+			char.ReadHandler.ServeRead(req, rsp)
+			v = buf.Bytes()
+		}
+
+		d.sendCmd(d.pm, 13, xpc.Dict{
+			"kCBMsgArgAttributeID":   aid,
+			"kCBMsgArgData":          v,
+			"kCBMsgArgTransactionID": args.transactionID(),
+			"kCBMsgArgResult":        0,
+		})
+
+	case evtWriteRequest:
+		for _, xxw := range args.attWrites() {
+			xw := msg(xxw.(xpc.Dict))
+			aid := xw.attributeID()
+			char := d.chars[aid]
+			req := ble.NewRequest(d.conn(args), xw.data(), xw.offset())
+			char.WriteHandler.ServeWrite(req, nil)
+			if xw.ignoreResponse() == 1 {
+				continue
+			}
+			d.sendCmd(d.pm, 13, xpc.Dict{
+				"kCBMsgArgAttributeID":   aid,
+				"kCBMsgArgData":          nil,
+				"kCBMsgArgTransactionID": args.transactionID(),
+				"kCBMsgArgResult":        0,
+			})
+		}
+
+	case evtSubscribe:
+		// characteristic is subscribed by remote central.
+		d.conn(args).subscribed(d.chars[args.attributeID()])
+
+	case evtUnubscribe:
+		// characteristic is unsubscribed by remote central.
+		d.conn(args).unsubscribed(d.chars[args.attributeID()])
+
+	case evtPeripheralConnected:
+		d.chConn <- d.conn(args)
+
+	case evtPeripheralDisconnected:
+		c := d.conn(args)
+		select {
+		case c.rspc <- m:
+			// Canceled by local central synchronously
+		default:
+			// Canceled by remote peripheral asynchronously.
+		}
+		delete(d.conns, c.RemoteAddr().String())
+		close(c.done)
+
+	case evtCharacteristicRead:
+		// Notification
+		c := d.conn(args)
+		if args.isNotification() != 0 {
+			sub := c.subs[uint16(args.characteristicHandle())]
+			if sub == nil {
+				log.Printf("notified by unsubscribed handle")
+				// FIXME: should terminate the connection?
+			} else {
+				sub.fn(args.data())
+			}
+			break
+		}
+		c.rspc <- m
+
+	case // Peripheral events
+		evtRSSIRead,
+		evtServiceDiscovered,
+		evtIncludedServicesDiscovered,
+		evtCharacteristicsDiscovered,
+		evtCharacteristicWritten,
+		evtNotificationValueSet,
+		evtDescriptorsDiscovered,
+		evtDescriptorRead,
+		evtDescriptorWritten:
+
+		d.conn(args).rspc <- m
+
+	default:
+		log.Printf("Unhandled event: %#v", event)
+	}
+}
+
+func (d *Device) conn(m msg) *conn {
+	// Convert xpc.UUID to ble.UUID.
+	a := ble.MustParse(m.deviceUUID().String())
+	c, ok := d.conns[a.String()]
+	if !ok {
+		c = newConn(d, a)
+		d.conns[a.String()] = c
+	}
+	return c
+}
+
+// sendReq sends a message and waits for its reply.
+func (d *Device) sendReq(x xpc.XPC, id int, args xpc.Dict) msg {
+	d.sendCmd(x, id, args)
+	return <-d.rspc
+}
+
+func (d *Device) sendCmd(x xpc.XPC, id int, args xpc.Dict) error {
+	logger.Info("send", "id", id, "args", fmt.Sprintf("%v", args))
+	x.Send(xpc.Dict{"kCBMsgId": id, "kCBMsgArgs": args}, false)
+	return nil
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/log.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/log.go
new file mode 100644
index 0000000..40b0411
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/log.go
@@ -0,0 +1,7 @@
+package darwin
+
+import (
+	"github.com/mgutz/logxi/v1"
+)
+
+var logger = log.New("darwin")
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/msg.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/msg.go
new file mode 100644
index 0000000..7ad170b
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/msg.go
@@ -0,0 +1,64 @@
+package darwin
+
+import (
+	"github.com/currantlabs/ble"
+	"github.com/raff/goble/xpc"
+)
+
+type msg xpc.Dict
+
+func (m msg) id() int        { return xpc.Dict(m).MustGetInt("kCBMsgId") }
+func (m msg) args() xpc.Dict { return xpc.Dict(m).MustGetDict("kCBMsgArgs") }
+func (m msg) advertisementData() xpc.Dict {
+	return xpc.Dict(m).MustGetDict("kCBMsgArgAdvertisementData")
+}
+func (m msg) attMTU() int          { return xpc.Dict(m).MustGetInt("kCBMsgArgATTMTU") }
+func (m msg) attWrites() xpc.Array { return xpc.Dict(m).MustGetArray("kCBMsgArgATTWrites") }
+func (m msg) attributeID() int     { return xpc.Dict(m).MustGetInt("kCBMsgArgAttributeID") }
+func (m msg) characteristicHandle() int {
+	return xpc.Dict(m).MustGetInt("kCBMsgArgCharacteristicHandle")
+}
+func (m msg) data() []byte {
+	// return xpc.Dict(m).MustGetBytes("kCBMsgArgData")
+	v := m["kCBMsgArgData"]
+	switch v.(type) {
+	case string:
+		return []byte(v.(string))
+	case []byte:
+		return v.([]byte)
+	default:
+		return nil
+	}
+}
+
+func (m msg) deviceUUID() xpc.UUID       { return xpc.Dict(m).MustGetUUID("kCBMsgArgDeviceUUID") }
+func (m msg) ignoreResponse() int        { return xpc.Dict(m).MustGetInt("kCBMsgArgIgnoreResponse") }
+func (m msg) offset() int                { return xpc.Dict(m).MustGetInt("kCBMsgArgOffset") }
+func (m msg) isNotification() int        { return xpc.Dict(m).GetInt("kCBMsgArgIsNotification", 0) }
+func (m msg) result() int                { return xpc.Dict(m).MustGetInt("kCBMsgArgResult") }
+func (m msg) state() int                 { return xpc.Dict(m).MustGetInt("kCBMsgArgState") }
+func (m msg) rssi() int                  { return xpc.Dict(m).MustGetInt("kCBMsgArgData") }
+func (m msg) transactionID() int         { return xpc.Dict(m).MustGetInt("kCBMsgArgTransactionID") }
+func (m msg) uuid() string               { return xpc.Dict(m).MustGetHexBytes("kCBMsgArgUUID") }
+func (m msg) serviceStartHandle() int    { return xpc.Dict(m).MustGetInt("kCBMsgArgServiceStartHandle") }
+func (m msg) serviceEndHandle() int      { return xpc.Dict(m).MustGetInt("kCBMsgArgServiceEndHandle") }
+func (m msg) services() xpc.Array        { return xpc.Dict(m).MustGetArray("kCBMsgArgServices") }
+func (m msg) characteristics() xpc.Array { return xpc.Dict(m).MustGetArray("kCBMsgArgCharacteristics") }
+func (m msg) characteristicProperties() int {
+	return xpc.Dict(m).MustGetInt("kCBMsgArgCharacteristicProperties")
+}
+func (m msg) characteristicValueHandle() int {
+	return xpc.Dict(m).MustGetInt("kCBMsgArgCharacteristicValueHandle")
+}
+func (m msg) descriptors() xpc.Array  { return xpc.Dict(m).MustGetArray("kCBMsgArgDescriptors") }
+func (m msg) descriptorHandle() int   { return xpc.Dict(m).MustGetInt("kCBMsgArgDescriptorHandle") }
+func (m msg) connectionInterval() int { return xpc.Dict(m).MustGetInt("kCBMsgArgConnectionInterval") }
+func (m msg) connectionLatency() int  { return xpc.Dict(m).MustGetInt("kCBMsgArgConnectionLatency") }
+func (m msg) supervisionTimeout() int { return xpc.Dict(m).MustGetInt("kCBMsgArgSupervisionTimeout") }
+
+func (m msg) err() error {
+	if code := m.result(); code != 0 {
+		return ble.ATTError(code)
+	}
+	return nil
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/option.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/option.go
new file mode 100644
index 0000000..924d1d5
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/option.go
@@ -0,0 +1,20 @@
+package darwin
+
+// An Option is a configuration function, which configures the device.
+type Option func(*Device) error
+
+// OptPeripheralRole configures the device to perform Peripheral tasks.
+func OptPeripheralRole() Option {
+	return func(d *Device) error {
+		d.role = 1
+		return nil
+	}
+}
+
+// OptCentralRole configures the device to perform Central tasks.
+func OptCentralRole() Option {
+	return func(d *Device) error {
+		d.role = 0
+		return nil
+	}
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/state.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/state.go
new file mode 100644
index 0000000..8034e39
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/state.go
@@ -0,0 +1,26 @@
+package darwin
+
+// State ...
+type State int
+
+// State ...
+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)]
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/darwin/util.go b/newtmgr/vendor/github.com/currantlabs/ble/darwin/util.go
new file mode 100644
index 0000000..8fdb251
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/darwin/util.go
@@ -0,0 +1,11 @@
+package darwin
+
+import "github.com/currantlabs/ble"
+
+func uuidSlice(uu []ble.UUID) [][]byte {
+	us := [][]byte{}
+	for _, u := range uu {
+		us = append(us, ble.Reverse(u))
+	}
+	return us
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/dev.go b/newtmgr/vendor/github.com/currantlabs/ble/dev.go
new file mode 100644
index 0000000..8d293cd
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/dev.go
@@ -0,0 +1,42 @@
+package ble
+
+import "golang.org/x/net/context"
+
+// Device ...
+type Device interface {
+	// AddService adds a service to database.
+	AddService(svc *Service) error
+
+	// RemoveAllServices removes all services that are currently in the database.
+	RemoveAllServices() error
+
+	// SetServices set the specified service to the database.
+	// It removes all currently added services, if any.
+	SetServices(svcs []*Service) error
+
+	// Stop detatch the GATT server from a peripheral device.
+	Stop() error
+
+	// AdvertiseNameAndServices advertises device name, and specified service UUIDs.
+	// It tres to fit the UUIDs in the advertising packet as much as possi
+	// If name doesn't fit in the advertising packet, it will be put in scan response.
+	AdvertiseNameAndServices(ctx context.Context, name string, uuids ...UUID) error
+
+	// AdvertiseMfgData avertises the given manufacturer data.
+	AdvertiseMfgData(ctx context.Context, id uint16, b []byte) error
+
+	// AdvertiseServiceData16 advertises data associated with a 16bit service uuid
+	AdvertiseServiceData16(ctx context.Context, id uint16, b []byte) error
+
+	// AdvertiseIBeaconData advertise iBeacon with given manufacturer data.
+	AdvertiseIBeaconData(ctx context.Context, b []byte) error
+
+	// AdvertiseIBeacon advertises iBeacon with specified parameters.
+	AdvertiseIBeacon(ctx context.Context, u UUID, major, minor uint16, pwr int8) error
+
+	// Scan starts scanning. Duplicated advertisements will be filtered out if allowDup is set to false.
+	Scan(ctx context.Context, allowDup bool, h AdvHandler) error
+
+	// Dial ...
+	Dial(ctx context.Context, a Addr) (Client, error)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/error.go b/newtmgr/vendor/github.com/currantlabs/ble/error.go
new file mode 100644
index 0000000..b66295e
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/error.go
@@ -0,0 +1,75 @@
+package ble
+
+import (
+	"errors"
+	"fmt"
+)
+
+// ErrEIRPacketTooLong is the error returned when an AdvertisingPacket
+// or ScanResponsePacket is too long.
+var ErrEIRPacketTooLong = errors.New("max packet length is 31")
+
+// ErrNotImplemented means the functionality is not implemented.
+var ErrNotImplemented = errors.New("not implemented")
+
+// ATTError is the error code of Attribute Protocol [Vol 3, Part F, 3.4.1.1].
+type ATTError byte
+
+// ATTError is the error code of Attribute Protocol [Vol 3, Part F, 3.4.1.1].
+const (
+	ErrSuccess           ATTError = 0x00 // ErrSuccess measn the operation is success.
+	ErrInvalidHandle     ATTError = 0x01 // ErrInvalidHandle means the attribute handle given was not valid on this server.
+	ErrReadNotPerm       ATTError = 0x02 // ErrReadNotPerm eans the attribute cannot be read.
+	ErrWriteNotPerm      ATTError = 0x03 // ErrWriteNotPerm eans the attribute cannot be written.
+	ErrInvalidPDU        ATTError = 0x04 // ErrInvalidPDU means the attribute PDU was invalid.
+	ErrAuthentication    ATTError = 0x05 // ErrAuthentication means the attribute requires authentication before it can be read or written.
+	ErrReqNotSupp        ATTError = 0x06 // ErrReqNotSupp means the attribute server does not support the request received from the client.
+	ErrInvalidOffset     ATTError = 0x07 // ErrInvalidOffset means the specified was past the end of the attribute.
+	ErrAuthorization     ATTError = 0x08 // ErrAuthorization means the attribute requires authorization before it can be read or written.
+	ErrPrepQueueFull     ATTError = 0x09 // ErrPrepQueueFull means too many prepare writes have been queued.
+	ErrAttrNotFound      ATTError = 0x0a // ErrAttrNotFound means no attribute found within the given attribute handle range.
+	ErrAttrNotLong       ATTError = 0x0b // ErrAttrNotLong means the attribute cannot be read or written using the Read Blob Request.
+	ErrInsuffEncrKeySize ATTError = 0x0c // ErrInsuffEncrKeySize means the Encryption Key Size used for encrypting this link is insufficient.
+	ErrInvalAttrValueLen ATTError = 0x0d // ErrInvalAttrValueLen means the attribute value length is invalid for the operation.
+	ErrUnlikely          ATTError = 0x0e // ErrUnlikely means the attribute request that was requested has encountered an error that was unlikely, and therefore could not be completed as requested.
+	ErrInsuffEnc         ATTError = 0x0f // ErrInsuffEnc means the attribute requires encryption before it can be read or written.
+	ErrUnsuppGrpType     ATTError = 0x10 // ErrUnsuppGrpType means the attribute type is not a supported grouping attribute as defined by a higher layer specification.
+	ErrInsuffResources   ATTError = 0x11 // ErrInsuffResources means insufficient resources to complete the request.
+)
+
+func (e ATTError) Error() string {
+	switch i := int(e); {
+	case i < 0x11:
+		return errName[e]
+	case i >= 0x12 && i <= 0x7F: // Reserved for future use.
+		return fmt.Sprintf("reserved error code (0x%02X)", i)
+	case i >= 0x80 && i <= 0x9F: // Application error, defined by higher level.
+		return fmt.Sprintf("application error code (0x%02X)", i)
+	case i >= 0xA0 && i <= 0xDF: // Reserved for future use.
+		return fmt.Sprintf("reserved error code (0x%02X)", i)
+	case i >= 0xE0 && i <= 0xFF: // Common profile and service error codes.
+		return "profile or service error"
+	}
+	return "unkown error"
+}
+
+var errName = map[ATTError]string{
+	ErrSuccess:           "success",
+	ErrInvalidHandle:     "invalid handle",
+	ErrReadNotPerm:       "read not permitted",
+	ErrWriteNotPerm:      "write not permitted",
+	ErrInvalidPDU:        "invalid PDU",
+	ErrAuthentication:    "insufficient authentication",
+	ErrReqNotSupp:        "request not supported",
+	ErrInvalidOffset:     "invalid offset",
+	ErrAuthorization:     "insufficient authorization",
+	ErrPrepQueueFull:     "prepare queue full",
+	ErrAttrNotFound:      "attribute not found",
+	ErrAttrNotLong:       "attribute not long",
+	ErrInsuffEncrKeySize: "insufficient encryption key size",
+	ErrInvalAttrValueLen: "invalid attribute value length",
+	ErrUnlikely:          "unlikely error",
+	ErrInsuffEnc:         "insufficient encryption",
+	ErrUnsuppGrpType:     "unsupported group type",
+	ErrInsuffResources:   "insufficient resources",
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/default_darwin.go b/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/default_darwin.go
new file mode 100644
index 0000000..5200989
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/default_darwin.go
@@ -0,0 +1,11 @@
+package dev
+
+import (
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/darwin"
+)
+
+// DefaultDevice ...
+func DefaultDevice() (d ble.Device, err error) {
+	return darwin.NewDevice()
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/default_linux.go b/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/default_linux.go
new file mode 100644
index 0000000..7d31388
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/default_linux.go
@@ -0,0 +1,11 @@
+package dev
+
+import (
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/linux"
+)
+
+// DefaultDevice ...
+func DefaultDevice() (d ble.Device, err error) {
+	return linux.NewDevice()
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/dev.go b/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/dev.go
new file mode 100644
index 0000000..6ff46c3
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/examples/lib/dev/dev.go
@@ -0,0 +1,8 @@
+package dev
+
+import "github.com/currantlabs/ble"
+
+// NewDevice ...
+func NewDevice(impl string) (d ble.Device, err error) {
+	return DefaultDevice()
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/gatt.go b/newtmgr/vendor/github.com/currantlabs/ble/gatt.go
new file mode 100644
index 0000000..e157d29
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/gatt.go
@@ -0,0 +1,188 @@
+package ble
+
+import (
+	"os"
+	"os/signal"
+	"syscall"
+
+	"github.com/pkg/errors"
+
+	"golang.org/x/net/context"
+)
+
+// ErrDefaultDevice ...
+var ErrDefaultDevice = errors.New("default device is not set")
+
+var defaultDevice Device
+
+// SetDefaultDevice returns the default HCI device.
+func SetDefaultDevice(d Device) {
+	defaultDevice = d
+}
+
+// AddService adds a service to database.
+func AddService(svc *Service) error {
+	if defaultDevice == nil {
+		return ErrDefaultDevice
+	}
+	return defaultDevice.AddService(svc)
+}
+
+// RemoveAllServices removes all services that are currently in the database.
+func RemoveAllServices() error {
+	if defaultDevice == nil {
+		return ErrDefaultDevice
+	}
+	return defaultDevice.RemoveAllServices()
+}
+
+// SetServices set the specified service to the database.
+// It removes all currently added services, if any.
+func SetServices(svcs []*Service) error {
+	if defaultDevice == nil {
+		return ErrDefaultDevice
+	}
+	return defaultDevice.SetServices(svcs)
+}
+
+// Stop detatch the GATT server from a peripheral device.
+func Stop() error {
+	if defaultDevice == nil {
+		return ErrDefaultDevice
+	}
+	return defaultDevice.Stop()
+}
+
+// AdvertiseNameAndServices advertises device name, and specified service UUIDs.
+// It tres to fit the UUIDs in the advertising packet as much as possi
+// If name doesn't fit in the advertising packet, it will be put in scan response.
+func AdvertiseNameAndServices(ctx context.Context, name string, uuids ...UUID) error {
+	if defaultDevice == nil {
+		return ErrDefaultDevice
+	}
+	defer untrap(trap(ctx))
+	return defaultDevice.AdvertiseNameAndServices(ctx, name, uuids...)
+}
+
+// AdvertiseIBeaconData advertise iBeacon with given manufacturer data.
+func AdvertiseIBeaconData(ctx context.Context, b []byte) error {
+	if defaultDevice == nil {
+		return ErrDefaultDevice
+	}
+	defer untrap(trap(ctx))
+	return defaultDevice.AdvertiseIBeaconData(ctx, b)
+}
+
+// AdvertiseIBeacon advertises iBeacon with specified parameters.
+func AdvertiseIBeacon(ctx context.Context, u UUID, major, minor uint16, pwr int8) error {
+	if defaultDevice == nil {
+		return ErrDefaultDevice
+	}
+	defer untrap(trap(ctx))
+	return defaultDevice.AdvertiseIBeacon(ctx, u, major, minor, pwr)
+}
+
+// Scan starts scanning. Duplicated advertisements will be filtered out if allowDup is set to false.
+func Scan(ctx context.Context, allowDup bool, h AdvHandler, f AdvFilter) error {
+	if defaultDevice == nil {
+		return ErrDefaultDevice
+	}
+	defer untrap(trap(ctx))
+
+	if f == nil {
+		return defaultDevice.Scan(ctx, allowDup, h)
+	}
+
+	h2 := func(a Advertisement) {
+		if f(a) {
+			h(a)
+		}
+	}
+	return defaultDevice.Scan(ctx, allowDup, h2)
+}
+
+// Find ...
+func Find(ctx context.Context, allowDup bool, f AdvFilter) ([]Advertisement, error) {
+	if defaultDevice == nil {
+		return nil, ErrDefaultDevice
+	}
+	var advs []Advertisement
+	h := func(a Advertisement) {
+		advs = append(advs, a)
+	}
+	defer untrap(trap(ctx))
+	return advs, Scan(ctx, allowDup, h, f)
+}
+
+// Dial ...
+func Dial(ctx context.Context, a Addr) (Client, error) {
+	if defaultDevice == nil {
+		return nil, ErrDefaultDevice
+	}
+	defer untrap(trap(ctx))
+	return defaultDevice.Dial(ctx, a)
+}
+
+// Connect searches for and connects to a Peripheral which matches specified condition.
+func Connect(ctx context.Context, f AdvFilter) (Client, error) {
+	ctx2, cancel := context.WithCancel(ctx)
+	go func() {
+		select {
+		case <-ctx.Done():
+			cancel()
+		case <-ctx2.Done():
+		}
+	}()
+
+	ch := make(chan Advertisement)
+	fn := func(a Advertisement) {
+		cancel()
+		ch <- a
+	}
+	if err := Scan(ctx2, false, fn, f); err != nil {
+		if err != context.Canceled {
+			return nil, errors.Wrap(err, "can't scan")
+		}
+	}
+
+	cln, err := Dial(ctx, (<-ch).Address())
+	return cln, errors.Wrap(err, "can't dial")
+}
+
+// A NotificationHandler handles notification or indication from a server.
+type NotificationHandler func(req []byte)
+
+// WithSigHandler ...
+func WithSigHandler(ctx context.Context, cancel func()) context.Context {
+	return context.WithValue(ctx, "sig", cancel)
+}
+
+// Cleanup for the interrupted case.
+func trap(ctx context.Context) chan<- os.Signal {
+	v := ctx.Value("sig")
+	if v == nil {
+		return nil
+	}
+	cancel, ok := v.(func())
+	if cancel == nil || !ok {
+		return nil
+	}
+
+	sigs := make(chan os.Signal, 1)
+	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
+	go func() {
+		select {
+		case <-sigs:
+			cancel()
+		case <-ctx.Done():
+		}
+	}()
+	return sigs
+}
+
+func untrap(sigs chan<- os.Signal) {
+	if sigs == nil {
+		return
+	}
+	signal.Stop(sigs)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/handler.go b/newtmgr/vendor/github.com/currantlabs/ble/handler.go
new file mode 100644
index 0000000..b3673fb
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/handler.go
@@ -0,0 +1,188 @@
+package ble
+
+import (
+	"bytes"
+	"io"
+
+	"golang.org/x/net/context"
+)
+
+// A ReadHandler handles GATT requests.
+type ReadHandler interface {
+	ServeRead(req Request, rsp ResponseWriter)
+}
+
+// ReadHandlerFunc is an adapter to allow the use of ordinary functions as Handlers.
+type ReadHandlerFunc func(req Request, rsp ResponseWriter)
+
+// ServeRead returns f(r, maxlen, offset).
+func (f ReadHandlerFunc) ServeRead(req Request, rsp ResponseWriter) {
+	f(req, rsp)
+}
+
+// A WriteHandler handles GATT requests.
+type WriteHandler interface {
+	ServeWrite(req Request, rsp ResponseWriter)
+}
+
+// WriteHandlerFunc is an adapter to allow the use of ordinary functions as Handlers.
+type WriteHandlerFunc func(req Request, rsp ResponseWriter)
+
+// ServeWrite returns f(r, maxlen, offset).
+func (f WriteHandlerFunc) ServeWrite(req Request, rsp ResponseWriter) {
+	f(req, rsp)
+}
+
+// A NotifyHandler handles GATT requests.
+type NotifyHandler interface {
+	ServeNotify(req Request, n Notifier)
+}
+
+// NotifyHandlerFunc is an adapter to allow the use of ordinary functions as Handlers.
+type NotifyHandlerFunc func(req Request, n Notifier)
+
+// ServeNotify returns f(r, maxlen, offset).
+func (f NotifyHandlerFunc) ServeNotify(req Request, n Notifier) {
+	f(req, n)
+}
+
+// Request ...
+type Request interface {
+	Conn() Conn
+	Data() []byte
+	Offset() int
+}
+
+// NewRequest returns a default implementation of Request.
+func NewRequest(conn Conn, data []byte, offset int) Request {
+	return &request{conn: conn, data: data, offset: offset}
+}
+
+// Default implementation of request.
+type request struct {
+	conn   Conn
+	data   []byte
+	offset int
+}
+
+func (r *request) Conn() Conn   { return r.conn }
+func (r *request) Data() []byte { return r.data }
+func (r *request) Offset() int  { return r.offset }
+
+// ResponseWriter ...
+type ResponseWriter interface {
+	// Write writes data to return as the characteristic value.
+	Write(b []byte) (int, error)
+
+	// Status reports the result of the request.
+	Status() ATTError
+
+	// SetStatus reports the result of the request.
+	SetStatus(status ATTError)
+
+	// Len ...
+	Len() int
+
+	// Cap ...
+	Cap() int
+}
+
+// NewResponseWriter ...
+func NewResponseWriter(buf *bytes.Buffer) ResponseWriter {
+	return &responseWriter{buf: buf}
+}
+
+// responseWriter implements Response
+type responseWriter struct {
+	buf    *bytes.Buffer
+	status ATTError
+}
+
+// Status reports the result of the request.
+func (r *responseWriter) Status() ATTError {
+	return r.status
+}
+
+// SetStatus reports the result of the request.
+func (r *responseWriter) SetStatus(status ATTError) {
+	r.status = status
+}
+
+// Len returns length of the buffer.
+// Len returns 0 if it is a dummy write response for WriteCommand.
+func (r *responseWriter) Len() int {
+	if r.buf == nil {
+		return 0
+	}
+	return r.buf.Len()
+}
+
+// Cap returns capacity of the buffer.
+// Cap returns 0 if it is a dummy write response for WriteCommand.
+func (r *responseWriter) Cap() int {
+	if r.buf == nil {
+		return 0
+	}
+	return r.buf.Cap()
+}
+
+// Write writes data to return as the characteristic value.
+// Cap returns 0 with error set to ErrReqNotSupp if it is a dummy write response for WriteCommand.
+func (r *responseWriter) Write(b []byte) (int, error) {
+	if r.buf == nil {
+		return 0, ErrReqNotSupp
+	}
+	if len(b) > r.buf.Cap()-r.buf.Len() {
+		return 0, io.ErrShortWrite
+	}
+
+	return r.buf.Write(b)
+}
+
+// Notifier ...
+type Notifier interface {
+	// Context sends data to the central.
+	Context() context.Context
+
+	// Write sends data to the central.
+	Write(b []byte) (int, error)
+
+	// Close ...
+	Close() error
+
+	// Cap returns the maximum number of bytes that may be sent in a single notification.
+	Cap() int
+}
+
+type notifier struct {
+	ctx    context.Context
+	maxlen int
+	cancel func()
+	send   func([]byte) (int, error)
+}
+
+// NewNotifier ...
+func NewNotifier(send func([]byte) (int, error)) Notifier {
+	n := &notifier{}
+	n.ctx, n.cancel = context.WithCancel(context.Background())
+	n.send = send
+	// n.maxlen = cap
+	return n
+}
+
+func (n *notifier) Context() context.Context {
+	return n.ctx
+}
+
+func (n *notifier) Write(b []byte) (int, error) {
+	return n.send(b)
+}
+
+func (n *notifier) Close() error {
+	n.cancel()
+	return nil
+}
+
+func (n *notifier) Cap() int {
+	return n.maxlen
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/adv/const.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/adv/const.go
new file mode 100644
index 0000000..284934a
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/adv/const.go
@@ -0,0 +1,57 @@
+package adv
+
+import "errors"
+
+// MaxEIRPacketLength is the maximum allowed AdvertisingPacket
+// and ScanResponsePacket length.
+const MaxEIRPacketLength = 31
+
+// ErrNotFit ...
+var (
+	ErrInvalid = errors.New("invalid argument")
+	ErrNotFit  = errors.New("data not fit")
+)
+
+// Advertising 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).
+)
+
+// Advertising data field s
+const (
+	flags             = 0x01 // Flags
+	someUUID16        = 0x02 // Incomplete List of 16-bit Service Class UUIDs
+	allUUID16         = 0x03 // Complete List of 16-bit Service Class UUIDs
+	someUUID32        = 0x04 // Incomplete List of 32-bit Service Class UUIDs
+	allUUID32         = 0x05 // Complete List of 32-bit Service Class UUIDs
+	someUUID128       = 0x06 // Incomplete List of 128-bit Service Class UUIDs
+	allUUID128        = 0x07 // Complete List of 128-bit Service Class UUIDs
+	shortName         = 0x08 // Shortened Local Name
+	completeName      = 0x09 // Complete Local Name
+	txPower           = 0x0A // Tx Power Level
+	classOfDevice     = 0x0D // Class of Device
+	simplePairingC192 = 0x0E // Simple Pairing Hash C-192
+	simplePairingR192 = 0x0F // Simple Pairing Randomizer R-192
+	secManagerTK      = 0x10 // Security Manager TK Value
+	secManagerOOB     = 0x11 // Security Manager Out of Band Flags
+	slaveConnInt      = 0x12 // Slave Connection Interval Range
+	serviceSol16      = 0x14 // List of 16-bit Service Solicitation UUIDs
+	serviceSol128     = 0x15 // List of 128-bit Service Solicitation UUIDs
+	serviceData16     = 0x16 // Service Data - 16-bit UUID
+	pubTargetAddr     = 0x17 // Public Target Address
+	randTargetAddr    = 0x18 // Random Target Address
+	appearance        = 0x19 // Appearance
+	advInterval       = 0x1A // Advertising Interval
+	leDeviceAddr      = 0x1B // LE Bluetooth Device Address
+	leRole            = 0x1C // LE Role
+	serviceSol32      = 0x1F // List of 32-bit Service Solicitation UUIDs
+	serviceData32     = 0x20 // Service Data - 32-bit UUID
+	serviceData128    = 0x21 // Service Data - 128-bit UUID
+	leSecConfirm      = 0x22 // LE Secure Connections Confirmation Value
+	leSecRandom       = 0x23 // LE Secure Connections Random Value
+	manufacturerData  = 0xFF // Manufacturer Specific Data
+)
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/adv/packet.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/adv/packet.go
new file mode 100644
index 0000000..9f38e4b
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/adv/packet.go
@@ -0,0 +1,289 @@
+package adv
+
+import (
+	"encoding/binary"
+
+	"github.com/currantlabs/ble"
+)
+
+// Packet is an implemntation of ble.AdvPacket for crafting or parsing an advertising packet or scan response.
+// Refer to Supplement to Bluetooth Core Specification | CSSv6, Part A.
+type Packet struct {
+	b []byte
+}
+
+// Bytes returns the bytes of the packet.
+func (p *Packet) Bytes() []byte {
+	return p.b
+}
+
+// Len returns the length of the packet.
+func (p *Packet) Len() int {
+	return len(p.b)
+}
+
+// NewPacket returns a new advertising Packet.
+func NewPacket(fields ...Field) (*Packet, error) {
+	p := &Packet{b: make([]byte, 0, MaxEIRPacketLength)}
+	for _, f := range fields {
+		if err := f(p); err != nil {
+			return nil, err
+		}
+	}
+	return p, nil
+}
+
+// NewRawPacket returns a new advertising Packet.
+func NewRawPacket(bytes ...[]byte) *Packet {
+	p := &Packet{b: make([]byte, 0, MaxEIRPacketLength)}
+	for _, b := range bytes {
+		p.b = append(p.b, b...)
+	}
+	return p
+}
+
+// Field is an advertising field which can be appended to a packet.
+type Field func(p *Packet) error
+
+// Append appends a field to the packet. It returns ErrNotFit if the field
+// doesn't fit into the packet, and leaves the packet intact.
+func (p *Packet) Append(f Field) error {
+	return f(p)
+}
+
+// appends appends a field to the packet. It returns ErrNotFit if the field
+// doesn't fit into the packet, and leaves the packet intact.
+func (p *Packet) append(typ byte, b []byte) error {
+	if p.Len()+1+1+len(b) > MaxEIRPacketLength {
+		return ErrNotFit
+	}
+	p.b = append(p.b, byte(len(b)+1))
+	p.b = append(p.b, typ)
+	p.b = append(p.b, b...)
+	return nil
+}
+
+// Raw appends the bytes to the current packet.
+// This is helpful for creating new packet from existing packets.
+func Raw(b []byte) Field {
+	return func(p *Packet) error {
+		if p.Len()+len(b) > MaxEIRPacketLength {
+			return ErrNotFit
+		}
+		p.b = append(p.b, b...)
+		return nil
+	}
+}
+
+// IBeaconData returns an iBeacon advertising packet with specified parameters.
+func IBeaconData(md []byte) Field {
+	return func(p *Packet) error {
+		return ManufacturerData(0x004C, md)(p)
+	}
+}
+
+// IBeacon returns an iBeacon advertising packet with specified parameters.
+func IBeacon(u ble.UUID, major, minor uint16, pwr int8) Field {
+	return func(p *Packet) error {
+		if u.Len() != 16 {
+			return ErrInvalid
+		}
+		md := make([]byte, 23)
+		md[0] = 0x02                               // Data type: iBeacon
+		md[1] = 0x15                               // Data length: 21 bytes
+		copy(md[2:], ble.Reverse(u))               // Big endian
+		binary.BigEndian.PutUint16(md[18:], major) // Big endian
+		binary.BigEndian.PutUint16(md[20:], minor) // Big endian
+		md[22] = uint8(pwr)                        // Measured Tx Power
+		return ManufacturerData(0x004C, md)(p)
+	}
+}
+
+// Flags is a flags.
+func Flags(f byte) Field {
+	return func(p *Packet) error {
+		return p.append(flags, []byte{f})
+	}
+}
+
+// ShortName is a short local name.
+func ShortName(n string) Field {
+	return func(p *Packet) error {
+		return p.append(shortName, []byte(n))
+	}
+}
+
+// CompleteName is a compelete local name.
+func CompleteName(n string) Field {
+	return func(p *Packet) error {
+		return p.append(completeName, []byte(n))
+	}
+}
+
+// ManufacturerData is manufacturer specific data.
+func ManufacturerData(id uint16, b []byte) Field {
+	return func(p *Packet) error {
+		d := append([]byte{uint8(id), uint8(id >> 8)}, b...)
+		return p.append(manufacturerData, d)
+	}
+}
+
+// AllUUID is one of the complete service UUID list.
+func AllUUID(u ble.UUID) Field {
+	return func(p *Packet) error {
+		if u.Len() == 2 {
+			return p.append(allUUID16, u)
+		}
+		if u.Len() == 4 {
+			return p.append(allUUID32, u)
+		}
+		return p.append(allUUID128, u)
+	}
+}
+
+// SomeUUID is one of the incomplete service UUID list.
+func SomeUUID(u ble.UUID) Field {
+	return func(p *Packet) error {
+		if u.Len() == 2 {
+			return p.append(someUUID16, u)
+		}
+		if u.Len() == 4 {
+			return p.append(someUUID32, u)
+		}
+		return p.append(someUUID128, u)
+	}
+}
+
+// ServiceData16 is service data for a 16bit service uuid
+func ServiceData16(id uint16, b []byte) Field {
+	return func(p *Packet) error {
+		uuid := ble.UUID16(id)
+		if err := p.append(allUUID16, uuid); err != nil {
+			return err
+		}
+		return p.append(serviceData16, append(uuid, b...))
+	}
+}
+
+// Field returns the field data (excluding the initial length and typ byte).
+// It returns nil, if the specified field is not found.
+func (p *Packet) Field(typ byte) []byte {
+	b := p.b
+	for len(b) > 0 {
+		if len(b) < 2 {
+			return nil
+		}
+		l, t := b[0], b[1]
+		if int(l) < 1 || len(b) < int(1+l) {
+			return nil
+		}
+		if t == typ {
+			return b[2 : 2+l-1]
+		}
+		b = b[1+l:]
+	}
+	return nil
+}
+
+// Flags returns the flags of the packet.
+func (p *Packet) Flags() (flags byte, present bool) {
+	b := p.Field(flags)
+	if len(b) < 2 {
+		return 0, false
+	}
+	return b[2], true
+}
+
+// LocalName returns the ShortName or CompleteName if it presents.
+func (p *Packet) LocalName() string {
+	if b := p.Field(shortName); b != nil {
+		return string(b)
+	}
+	return string(p.Field(completeName))
+}
+
+// TxPower returns the TxPower, if it presents.
+func (p *Packet) TxPower() (power int, present bool) {
+	b := p.Field(txPower)
+	if len(b) < 3 {
+		return 0, false
+	}
+	return int(int8(b[2])), true
+}
+
+// UUIDs returns a list of service UUIDs.
+func (p *Packet) UUIDs() []ble.UUID {
+	var u []ble.UUID
+	if b := p.Field(someUUID16); b != nil {
+		u = uuidList(u, b, 2)
+	}
+	if b := p.Field(allUUID16); b != nil {
+		u = uuidList(u, b, 2)
+	}
+	if b := p.Field(someUUID32); b != nil {
+		u = uuidList(u, b, 4)
+	}
+	if b := p.Field(allUUID32); b != nil {
+		u = uuidList(u, b, 4)
+	}
+	if b := p.Field(someUUID128); b != nil {
+		u = uuidList(u, b, 16)
+	}
+	if b := p.Field(allUUID128); b != nil {
+		u = uuidList(u, b, 16)
+	}
+	return u
+}
+
+// ServiceSol ...
+func (p *Packet) ServiceSol() []ble.UUID {
+	var u []ble.UUID
+	if b := p.Field(serviceSol16); b != nil {
+		u = uuidList(u, b, 2)
+	}
+	if b := p.Field(serviceSol32); b != nil {
+		u = uuidList(u, b, 16)
+	}
+	if b := p.Field(serviceSol128); b != nil {
+		u = uuidList(u, b, 16)
+	}
+	return u
+}
+
+// ServiceData ...
+func (p *Packet) ServiceData() []ble.ServiceData {
+	var s []ble.ServiceData
+	if b := p.Field(serviceData16); b != nil {
+		s = serviceDataList(s, b, 2)
+	}
+	if b := p.Field(serviceData32); b != nil {
+		s = serviceDataList(s, b, 4)
+	}
+	if b := p.Field(serviceData128); b != nil {
+		s = serviceDataList(s, b, 16)
+	}
+	return s
+}
+
+// ManufacturerData returns the ManufacturerData field if it presents.
+func (p *Packet) ManufacturerData() []byte {
+	return p.Field(manufacturerData)
+}
+
+// Utility function for creating a list of uuids.
+func uuidList(u []ble.UUID, d []byte, w int) []ble.UUID {
+	for len(d) > 0 {
+		u = append(u, ble.UUID(d[:w]))
+		d = d[w:]
+	}
+	return u
+}
+
+func serviceDataList(sd []ble.ServiceData, d []byte, w int) []ble.ServiceData {
+	serviceData := ble.ServiceData{
+		UUID: ble.UUID(d[:w]),
+		Data: make([]byte, len(d)-w),
+	}
+	copy(serviceData.Data, d[2:])
+	return append(sd, serviceData)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/att/README.md b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/README.md
new file mode 100644
index 0000000..25024f8
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/README.md
@@ -0,0 +1,40 @@
+## Attribute Protocol (ATT)
+
+This package implement Attribute Protocol (ATT) [Vol 3, Part F]
+
+#### Check list for ATT Server implementation.
+  - [x] Error Response [3.4.1.1]
+  - [x] Exchange MTU Request [3.4.2.1 & 3.4.2.2]
+  - [x] Find Information Request [3.4.3.1 & 3.4.3.2]
+  - [x] Find By Type Value Request [3.4.3.3 & 3.4.3.4]
+  - [x] Read By Type Request [3.4.4.1 & 3.4.4.2]
+  - [x] Read Request [3.4.4.3 & 3.4.4.4]
+  - [x] Read Blob Request [3.4.4.5 & 3.4.4.6]
+  - [ ] Read Multiple Request [3.4.4.7 & 3.4.4.8]
+  - [x] Read By Group Type Request [3.4.4.9 & 3.4.4.10]
+  - [x] Write Request [3.4.5.1 & 3.4.5.2]
+  - [x] Write Command [3.4.5.3]
+  - [ ] Signed Write Command [3.4.5.4]
+  - [ ] Prepare Write Request [3.4.6.1 & 3.4.6.2]
+  - [ ] Execute Write Request [3.4.6.3]
+  - [x] Handle Value Notification [3.4.7.1]
+  - [x] Handle Value Indication [3.4.7.2 & 3.4.7.3]
+
+#### Check list for ATT Client implementation.
+
+  - [x] Error Response [3.4.1.1]
+  - [x] Exchange MTU Request [3.4.2.1 & 3.4.2.2]
+  - [x] Find Information Request [3.4.3.1 & 3.4.3.2]
+  - [ ] Find By Type Value Request [3.4.3.3 & 3.4.3.4]
+  - [x] Read By Type Request [3.4.4.1 & 3.4.4.2]
+  - [x] Read Request [3.4.4.3 & 3.4.4.4]
+  - [x] Read Blob Request [3.4.4.5 & 3.4.4.6]
+  - [ ] Read Multiple Request [3.4.4.7 & 3.4.4.8]
+  - [x] Read By Group Type Request [3.4.4.9 & 3.4.4.10]
+  - [x] Write Request [3.4.5.1 & 3.4.5.2]
+  - [x] Write Command [3.4.5.3]
+  - [ ] Signed Write Command [3.4.5.4]
+  - [ ] Prepare Write Request [3.4.6.1 & 3.4.6.2]
+  - [ ] Execute Write Request [3.4.6.3]
+  - [x] Handle Value Notification [3.4.7.1]
+  - [x] Handle Value Indication [3.4.7.2 & 3.4.7.3]
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/att/att.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/att.go
new file mode 100644
index 0000000..584acbf
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/att.go
@@ -0,0 +1,30 @@
+package att
+
+import "errors"
+
+var (
+	// ErrInvalidArgument means one or more of the arguments are invalid.
+	ErrInvalidArgument = errors.New("invalid argument")
+
+	// ErrInvalidResponse means one or more of the response fields are invalid.
+	ErrInvalidResponse = errors.New("invalid response")
+
+	// ErrSeqProtoTimeout means the request hasn't been acknowledged in 30 seconds.
+	// [Vol 3, Part F, 3.3.3]
+	ErrSeqProtoTimeout = errors.New("req timeout")
+)
+
+var rspOfReq = map[byte]byte{
+	ExchangeMTURequestCode:     ExchangeMTUResponseCode,
+	FindInformationRequestCode: FindInformationResponseCode,
+	FindByTypeValueRequestCode: FindByTypeValueResponseCode,
+	ReadByTypeRequestCode:      ReadByTypeResponseCode,
+	ReadRequestCode:            ReadResponseCode,
+	ReadBlobRequestCode:        ReadBlobResponseCode,
+	ReadMultipleRequestCode:    ReadMultipleResponseCode,
+	ReadByGroupTypeRequestCode: ReadByGroupTypeResponseCode,
+	WriteRequestCode:           WriteResponseCode,
+	PrepareWriteRequestCode:    PrepareWriteResponseCode,
+	ExecuteWriteRequestCode:    ExecuteWriteResponseCode,
+	HandleValueIndicationCode:  HandleValueConfirmationCode,
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/att/att_gen.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/att_gen.go
new file mode 100644
index 0000000..df29642
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/att_gen.go
@@ -0,0 +1,639 @@
+package att
+
+import "encoding/binary"
+
+// ErrorResponseCode ...
+const ErrorResponseCode = 0x01
+
+// ErrorResponse implements Error Response (0x01) [Vol 3, Part E, 3.4.1.1].
+type ErrorResponse []byte
+
+// AttributeOpcode ...
+func (r ErrorResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ErrorResponse) SetAttributeOpcode() { r[0] = 0x01 }
+
+// RequestOpcodeInError ...
+func (r ErrorResponse) RequestOpcodeInError() uint8 { return r[1] }
+
+// SetRequestOpcodeInError ...
+func (r ErrorResponse) SetRequestOpcodeInError(v uint8) { r[1] = v }
+
+// AttributeInError ...
+func (r ErrorResponse) AttributeInError() uint16 { return binary.LittleEndian.Uint16(r[2:]) }
+
+// SetAttributeInError ...
+func (r ErrorResponse) SetAttributeInError(v uint16) { binary.LittleEndian.PutUint16(r[2:], v) }
+
+// ErrorCode ...
+func (r ErrorResponse) ErrorCode() uint8 { return r[4] }
+
+// SetErrorCode ...
+func (r ErrorResponse) SetErrorCode(v uint8) { r[4] = v }
+
+// ExchangeMTURequestCode ...
+const ExchangeMTURequestCode = 0x02
+
+// ExchangeMTURequest implements Exchange MTU Request (0x02) [Vol 3, Part E, 3.4.2.1].
+type ExchangeMTURequest []byte
+
+// AttributeOpcode ...
+func (r ExchangeMTURequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ExchangeMTURequest) SetAttributeOpcode() { r[0] = 0x02 }
+
+// ClientRxMTU ...
+func (r ExchangeMTURequest) ClientRxMTU() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetClientRxMTU ...
+func (r ExchangeMTURequest) SetClientRxMTU(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// ExchangeMTUResponseCode ...
+const ExchangeMTUResponseCode = 0x03
+
+// ExchangeMTUResponse implements Exchange MTU Response (0x03) [Vol 3, Part E, 3.4.2.2].
+type ExchangeMTUResponse []byte
+
+// AttributeOpcode ...
+func (r ExchangeMTUResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ExchangeMTUResponse) SetAttributeOpcode() { r[0] = 0x03 }
+
+// ServerRxMTU ...
+func (r ExchangeMTUResponse) ServerRxMTU() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetServerRxMTU ...
+func (r ExchangeMTUResponse) SetServerRxMTU(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// FindInformationRequestCode ...
+const FindInformationRequestCode = 0x04
+
+// FindInformationRequest implements Find Information Request (0x04) [Vol 3, Part E, 3.4.3.1].
+type FindInformationRequest []byte
+
+// AttributeOpcode ...
+func (r FindInformationRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r FindInformationRequest) SetAttributeOpcode() { r[0] = 0x04 }
+
+// StartingHandle ...
+func (r FindInformationRequest) StartingHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetStartingHandle ...
+func (r FindInformationRequest) SetStartingHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// EndingHandle ...
+func (r FindInformationRequest) EndingHandle() uint16 { return binary.LittleEndian.Uint16(r[3:]) }
+
+// SetEndingHandle ...
+func (r FindInformationRequest) SetEndingHandle(v uint16) { binary.LittleEndian.PutUint16(r[3:], v) }
+
+// FindInformationResponseCode ...
+const FindInformationResponseCode = 0x05
+
+// FindInformationResponse implements Find Information Response (0x05) [Vol 3, Part E, 3.4.3.2].
+type FindInformationResponse []byte
+
+// AttributeOpcode ...
+func (r FindInformationResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r FindInformationResponse) SetAttributeOpcode() { r[0] = 0x05 }
+
+// Format ...
+func (r FindInformationResponse) Format() uint8 { return r[1] }
+
+// SetFormat ...
+func (r FindInformationResponse) SetFormat(v uint8) { r[1] = v }
+
+// InformationData ...
+func (r FindInformationResponse) InformationData() []byte { return r[2:] }
+
+// SetInformationData ...
+func (r FindInformationResponse) SetInformationData(v []byte) { copy(r[2:], v) }
+
+// FindByTypeValueRequestCode ...
+const FindByTypeValueRequestCode = 0x06
+
+// FindByTypeValueRequest implements Find By Type Value Request (0x06) [Vol 3, Part E, 3.4.3.3].
+type FindByTypeValueRequest []byte
+
+// AttributeOpcode ...
+func (r FindByTypeValueRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r FindByTypeValueRequest) SetAttributeOpcode() { r[0] = 0x06 }
+
+// StartingHandle ...
+func (r FindByTypeValueRequest) StartingHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetStartingHandle ...
+func (r FindByTypeValueRequest) SetStartingHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// EndingHandle ...
+func (r FindByTypeValueRequest) EndingHandle() uint16 { return binary.LittleEndian.Uint16(r[3:]) }
+
+// SetEndingHandle ...
+func (r FindByTypeValueRequest) SetEndingHandle(v uint16) { binary.LittleEndian.PutUint16(r[3:], v) }
+
+// AttributeType ...
+func (r FindByTypeValueRequest) AttributeType() uint16 { return binary.LittleEndian.Uint16(r[5:]) }
+
+// SetAttributeType ...
+func (r FindByTypeValueRequest) SetAttributeType(v uint16) { binary.LittleEndian.PutUint16(r[5:], v) }
+
+// AttributeValue ...
+func (r FindByTypeValueRequest) AttributeValue() []byte { return r[7:] }
+
+// SetAttributeValue ...
+func (r FindByTypeValueRequest) SetAttributeValue(v []byte) { copy(r[7:], v) }
+
+// FindByTypeValueResponseCode ...
+const FindByTypeValueResponseCode = 0x07
+
+// FindByTypeValueResponse implements Find By Type Value Response (0x07) [Vol 3, Part E, 3.4.3.4].
+type FindByTypeValueResponse []byte
+
+// AttributeOpcode ...
+func (r FindByTypeValueResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r FindByTypeValueResponse) SetAttributeOpcode() { r[0] = 0x07 }
+
+// HandleInformationList ...
+func (r FindByTypeValueResponse) HandleInformationList() []byte { return r[1:] }
+
+// SetHandleInformationList ...
+func (r FindByTypeValueResponse) SetHandleInformationList(v []byte) { copy(r[1:], v) }
+
+// ReadByTypeRequestCode ...
+const ReadByTypeRequestCode = 0x08
+
+// ReadByTypeRequest implements Read By Type Request (0x08) [Vol 3, Part E, 3.4.4.1].
+type ReadByTypeRequest []byte
+
+// AttributeOpcode ...
+func (r ReadByTypeRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadByTypeRequest) SetAttributeOpcode() { r[0] = 0x08 }
+
+// StartingHandle ...
+func (r ReadByTypeRequest) StartingHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetStartingHandle ...
+func (r ReadByTypeRequest) SetStartingHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// EndingHandle ...
+func (r ReadByTypeRequest) EndingHandle() uint16 { return binary.LittleEndian.Uint16(r[3:]) }
+
+// SetEndingHandle ...
+func (r ReadByTypeRequest) SetEndingHandle(v uint16) { binary.LittleEndian.PutUint16(r[3:], v) }
+
+// AttributeType ...
+func (r ReadByTypeRequest) AttributeType() []byte { return r[5:] }
+
+// SetAttributeType ...
+func (r ReadByTypeRequest) SetAttributeType(v []byte) { copy(r[5:], v) }
+
+// ReadByTypeResponseCode ...
+const ReadByTypeResponseCode = 0x09
+
+// ReadByTypeResponse implements Read By Type Response (0x09) [Vol 3, Part E, 3.4.4.2].
+type ReadByTypeResponse []byte
+
+// AttributeOpcode ...
+func (r ReadByTypeResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadByTypeResponse) SetAttributeOpcode() { r[0] = 0x09 }
+
+// Length ...
+func (r ReadByTypeResponse) Length() uint8 { return r[1] }
+
+// SetLength ...
+func (r ReadByTypeResponse) SetLength(v uint8) { r[1] = v }
+
+// AttributeDataList ...
+func (r ReadByTypeResponse) AttributeDataList() []byte { return r[2:] }
+
+// SetAttributeDataList ...
+func (r ReadByTypeResponse) SetAttributeDataList(v []byte) { copy(r[2:], v) }
+
+// ReadRequestCode ...
+const ReadRequestCode = 0x0A
+
+// ReadRequest implements Read Request (0x0A) [Vol 3, Part E, 3.4.4.3].
+type ReadRequest []byte
+
+// AttributeOpcode ...
+func (r ReadRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadRequest) SetAttributeOpcode() { r[0] = 0x0A }
+
+// AttributeHandle ...
+func (r ReadRequest) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r ReadRequest) SetAttributeHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// ReadResponseCode ...
+const ReadResponseCode = 0x0B
+
+// ReadResponse implements Read Response (0x0B) [Vol 3, Part E, 3.4.4.4].
+type ReadResponse []byte
+
+// AttributeOpcode ...
+func (r ReadResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadResponse) SetAttributeOpcode() { r[0] = 0x0B }
+
+// AttributeValue ...
+func (r ReadResponse) AttributeValue() []byte { return r[1:] }
+
+// SetAttributeValue ...
+func (r ReadResponse) SetAttributeValue(v []byte) { copy(r[1:], v) }
+
+// ReadBlobRequestCode ...
+const ReadBlobRequestCode = 0x0C
+
+// ReadBlobRequest implements Read Blob Request (0x0C) [Vol 3, Part E, 3.4.4.5].
+type ReadBlobRequest []byte
+
+// AttributeOpcode ...
+func (r ReadBlobRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadBlobRequest) SetAttributeOpcode() { r[0] = 0x0C }
+
+// AttributeHandle ...
+func (r ReadBlobRequest) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r ReadBlobRequest) SetAttributeHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// ValueOffset ...
+func (r ReadBlobRequest) ValueOffset() uint16 { return binary.LittleEndian.Uint16(r[3:]) }
+
+// SetValueOffset ...
+func (r ReadBlobRequest) SetValueOffset(v uint16) { binary.LittleEndian.PutUint16(r[3:], v) }
+
+// ReadBlobResponseCode ...
+const ReadBlobResponseCode = 0x0D
+
+// ReadBlobResponse implements Read Blob Response (0x0D) [Vol 3, Part E, 3.4.4.6].
+type ReadBlobResponse []byte
+
+// AttributeOpcode ...
+func (r ReadBlobResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadBlobResponse) SetAttributeOpcode() { r[0] = 0x0D }
+
+// PartAttributeValue ...
+func (r ReadBlobResponse) PartAttributeValue() []byte { return r[1:] }
+
+// SetPartAttributeValue ...
+func (r ReadBlobResponse) SetPartAttributeValue(v []byte) { copy(r[1:], v) }
+
+// ReadMultipleRequestCode ...
+const ReadMultipleRequestCode = 0x0E
+
+// ReadMultipleRequest implements Read Multiple Request (0x0E) [Vol 3, Part E, 3.4.4.7].
+type ReadMultipleRequest []byte
+
+// AttributeOpcode ...
+func (r ReadMultipleRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadMultipleRequest) SetAttributeOpcode() { r[0] = 0x0E }
+
+// SetOfHandles ...
+func (r ReadMultipleRequest) SetOfHandles() []byte { return r[1:] }
+
+// SetSetOfHandles ...
+func (r ReadMultipleRequest) SetSetOfHandles(v []byte) { copy(r[1:], v) }
+
+// ReadMultipleResponseCode ...
+const ReadMultipleResponseCode = 0x0F
+
+// ReadMultipleResponse implements Read Multiple Response (0x0F) [Vol 3, Part E, 3.4.4.8].
+type ReadMultipleResponse []byte
+
+// AttributeOpcode ...
+func (r ReadMultipleResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadMultipleResponse) SetAttributeOpcode() { r[0] = 0x0F }
+
+// SetOfValues ...
+func (r ReadMultipleResponse) SetOfValues() []byte { return r[1:] }
+
+// SetSetOfValues ...
+func (r ReadMultipleResponse) SetSetOfValues(v []byte) { copy(r[1:], v) }
+
+// ReadByGroupTypeRequestCode ...
+const ReadByGroupTypeRequestCode = 0x10
+
+// ReadByGroupTypeRequest implements Read By Group Type Request (0x10) [Vol 3, Part E, 3.4.4.9].
+type ReadByGroupTypeRequest []byte
+
+// AttributeOpcode ...
+func (r ReadByGroupTypeRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadByGroupTypeRequest) SetAttributeOpcode() { r[0] = 0x10 }
+
+// StartingHandle ...
+func (r ReadByGroupTypeRequest) StartingHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetStartingHandle ...
+func (r ReadByGroupTypeRequest) SetStartingHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// EndingHandle ...
+func (r ReadByGroupTypeRequest) EndingHandle() uint16 { return binary.LittleEndian.Uint16(r[3:]) }
+
+// SetEndingHandle ...
+func (r ReadByGroupTypeRequest) SetEndingHandle(v uint16) { binary.LittleEndian.PutUint16(r[3:], v) }
+
+// AttributeGroupType ...
+func (r ReadByGroupTypeRequest) AttributeGroupType() []byte { return r[5:] }
+
+// SetAttributeGroupType ...
+func (r ReadByGroupTypeRequest) SetAttributeGroupType(v []byte) { copy(r[5:], v) }
+
+// ReadByGroupTypeResponseCode ...
+const ReadByGroupTypeResponseCode = 0x11
+
+// ReadByGroupTypeResponse implements Read By Group Type Response (0x11) [Vol 3, Part E, 3.4.4.10].
+type ReadByGroupTypeResponse []byte
+
+// AttributeOpcode ...
+func (r ReadByGroupTypeResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ReadByGroupTypeResponse) SetAttributeOpcode() { r[0] = 0x11 }
+
+// Length ...
+func (r ReadByGroupTypeResponse) Length() uint8 { return r[1] }
+
+// SetLength ...
+func (r ReadByGroupTypeResponse) SetLength(v uint8) { r[1] = v }
+
+// AttributeDataList ...
+func (r ReadByGroupTypeResponse) AttributeDataList() []byte { return r[2:] }
+
+// SetAttributeDataList ...
+func (r ReadByGroupTypeResponse) SetAttributeDataList(v []byte) { copy(r[2:], v) }
+
+// WriteRequestCode ...
+const WriteRequestCode = 0x12
+
+// WriteRequest implements Write Request (0x12) [Vol 3, Part E, 3.4.5.1].
+type WriteRequest []byte
+
+// AttributeOpcode ...
+func (r WriteRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r WriteRequest) SetAttributeOpcode() { r[0] = 0x12 }
+
+// AttributeHandle ...
+func (r WriteRequest) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r WriteRequest) SetAttributeHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// AttributeValue ...
+func (r WriteRequest) AttributeValue() []byte { return r[3:] }
+
+// SetAttributeValue ...
+func (r WriteRequest) SetAttributeValue(v []byte) { copy(r[3:], v) }
+
+// WriteResponseCode ...
+const WriteResponseCode = 0x13
+
+// WriteResponse implements Write Response (0x13) [Vol 3, Part E, 3.4.5.2].
+type WriteResponse []byte
+
+// AttributeOpcode ...
+func (r WriteResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r WriteResponse) SetAttributeOpcode() { r[0] = 0x13 }
+
+// WriteCommandCode ...
+const WriteCommandCode = 0x52
+
+// WriteCommand implements Write Command (0x52) [Vol 3, Part E, 3.4.5.3].
+type WriteCommand []byte
+
+// AttributeOpcode ...
+func (r WriteCommand) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r WriteCommand) SetAttributeOpcode() { r[0] = 0x52 }
+
+// AttributeHandle ...
+func (r WriteCommand) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r WriteCommand) SetAttributeHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// AttributeValue ...
+func (r WriteCommand) AttributeValue() []byte { return r[3:] }
+
+// SetAttributeValue ...
+func (r WriteCommand) SetAttributeValue(v []byte) { copy(r[3:], v) }
+
+// SignedWriteCommandCode ...
+const SignedWriteCommandCode = 0xD2
+
+// SignedWriteCommand implements Signed Write Command (0xD2) [Vol 3, Part E, 3.4.5.4].
+type SignedWriteCommand []byte
+
+// AttributeOpcode ...
+func (r SignedWriteCommand) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r SignedWriteCommand) SetAttributeOpcode() { r[0] = 0xD2 }
+
+// AttributeHandle ...
+func (r SignedWriteCommand) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r SignedWriteCommand) SetAttributeHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// AttributeValue ...
+func (r SignedWriteCommand) AttributeValue() []byte { return r[3:] }
+
+// SetAttributeValue ...
+func (r SignedWriteCommand) SetAttributeValue(v []byte) { copy(r[3:], v) }
+
+// AuthenticationSignature ...
+func (r SignedWriteCommand) AuthenticationSignature() [12]byte {
+	b := [12]byte{}
+	copy(b[:], r[3:])
+	return b
+}
+
+// SetAuthenticationSignature ...
+func (r SignedWriteCommand) SetAuthenticationSignature(v [12]byte) { copy(r[3:3+12], v[:]) }
+
+// PrepareWriteRequestCode ...
+const PrepareWriteRequestCode = 0x16
+
+// PrepareWriteRequest implements Prepare Write Request (0x16) [Vol 3, Part E, 3.4.6.1].
+type PrepareWriteRequest []byte
+
+// AttributeOpcode ...
+func (r PrepareWriteRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r PrepareWriteRequest) SetAttributeOpcode() { r[0] = 0x16 }
+
+// AttributeHandle ...
+func (r PrepareWriteRequest) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r PrepareWriteRequest) SetAttributeHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// ValueOffset ...
+func (r PrepareWriteRequest) ValueOffset() uint16 { return binary.LittleEndian.Uint16(r[3:]) }
+
+// SetValueOffset ...
+func (r PrepareWriteRequest) SetValueOffset(v uint16) { binary.LittleEndian.PutUint16(r[3:], v) }
+
+// PartAttributeValue ...
+func (r PrepareWriteRequest) PartAttributeValue() []byte { return r[5:] }
+
+// SetPartAttributeValue ...
+func (r PrepareWriteRequest) SetPartAttributeValue(v []byte) { copy(r[5:], v) }
+
+// PrepareWriteResponseCode ...
+const PrepareWriteResponseCode = 0x17
+
+// PrepareWriteResponse implements Prepare Write Response (0x17) [Vol 3, Part E, 3.4.6.2].
+type PrepareWriteResponse []byte
+
+// AttributeOpcode ...
+func (r PrepareWriteResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r PrepareWriteResponse) SetAttributeOpcode() { r[0] = 0x17 }
+
+// AttributeHandle ...
+func (r PrepareWriteResponse) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r PrepareWriteResponse) SetAttributeHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// ValueOffset ...
+func (r PrepareWriteResponse) ValueOffset() uint16 { return binary.LittleEndian.Uint16(r[3:]) }
+
+// SetValueOffset ...
+func (r PrepareWriteResponse) SetValueOffset(v uint16) { binary.LittleEndian.PutUint16(r[3:], v) }
+
+// PartAttributeValue ...
+func (r PrepareWriteResponse) PartAttributeValue() []byte { return r[5:] }
+
+// SetPartAttributeValue ...
+func (r PrepareWriteResponse) SetPartAttributeValue(v []byte) { copy(r[5:], v) }
+
+// ExecuteWriteRequestCode ...
+const ExecuteWriteRequestCode = 0x18
+
+// ExecuteWriteRequest implements Execute Write Request (0x18) [Vol 3, Part E, 3.4.6.3].
+type ExecuteWriteRequest []byte
+
+// AttributeOpcode ...
+func (r ExecuteWriteRequest) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ExecuteWriteRequest) SetAttributeOpcode() { r[0] = 0x18 }
+
+// Flags ...
+func (r ExecuteWriteRequest) Flags() uint8 { return r[1] }
+
+// SetFlags ...
+func (r ExecuteWriteRequest) SetFlags(v uint8) { r[1] = v }
+
+// ExecuteWriteResponseCode ...
+const ExecuteWriteResponseCode = 0x19
+
+// ExecuteWriteResponse implements Execute Write Response (0x19) [Vol 3, Part E, 3.4.6.4].
+type ExecuteWriteResponse []byte
+
+// AttributeOpcode ...
+func (r ExecuteWriteResponse) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r ExecuteWriteResponse) SetAttributeOpcode() { r[0] = 0x19 }
+
+// HandleValueNotificationCode ...
+const HandleValueNotificationCode = 0x1B
+
+// HandleValueNotification implements Handle Value Notification (0x1B) [Vol 3, Part E, 3.4.7.1].
+type HandleValueNotification []byte
+
+// AttributeOpcode ...
+func (r HandleValueNotification) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r HandleValueNotification) SetAttributeOpcode() { r[0] = 0x1B }
+
+// AttributeHandle ...
+func (r HandleValueNotification) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r HandleValueNotification) SetAttributeHandle(v uint16) {
+	binary.LittleEndian.PutUint16(r[1:], v)
+}
+
+// AttributeValue ...
+func (r HandleValueNotification) AttributeValue() []byte { return r[3:] }
+
+// SetAttributeValue ...
+func (r HandleValueNotification) SetAttributeValue(v []byte) { copy(r[3:], v) }
+
+// HandleValueIndicationCode ...
+const HandleValueIndicationCode = 0x1D
+
+// HandleValueIndication implements Handle Value Indication (0x1D) [Vol 3, Part E, 3.4.7.2].
+type HandleValueIndication []byte
+
+// AttributeOpcode ...
+func (r HandleValueIndication) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r HandleValueIndication) SetAttributeOpcode() { r[0] = 0x1D }
+
+// AttributeHandle ...
+func (r HandleValueIndication) AttributeHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+// SetAttributeHandle ...
+func (r HandleValueIndication) SetAttributeHandle(v uint16) { binary.LittleEndian.PutUint16(r[1:], v) }
+
+// AttributeValue ...
+func (r HandleValueIndication) AttributeValue() []byte { return r[3:] }
+
+// SetAttributeValue ...
+func (r HandleValueIndication) SetAttributeValue(v []byte) { copy(r[3:], v) }
+
+// HandleValueConfirmationCode ...
+const HandleValueConfirmationCode = 0x1E
+
+// HandleValueConfirmation implements Handle Value Confirmation (0x1E) [Vol 3, Part E, 3.4.7.3].
+type HandleValueConfirmation []byte
+
+// AttributeOpcode ...
+func (r HandleValueConfirmation) AttributeOpcode() uint8 { return r[0] }
+
+// SetAttributeOpcode ...
+func (r HandleValueConfirmation) SetAttributeOpcode() { r[0] = 0x1E }
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/att/attr.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/attr.go
new file mode 100644
index 0000000..94b0fe2
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/attr.go
@@ -0,0 +1,14 @@
+package att
+
+import "github.com/currantlabs/ble"
+
+// attr is a BLE attribute.
+type attr struct {
+	h    uint16
+	endh uint16
+	typ  ble.UUID
+
+	v  []byte
+	rh ble.ReadHandler
+	wh ble.WriteHandler
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/att/client.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/client.go
new file mode 100644
index 0000000..fa6c9c4
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/client.go
@@ -0,0 +1,560 @@
+package att
+
+import (
+	"encoding/binary"
+	"fmt"
+	"time"
+
+	"github.com/currantlabs/ble"
+	"github.com/pkg/errors"
+)
+
+// NotificationHandler handles notification or indication.
+type NotificationHandler interface {
+	HandleNotification(req []byte)
+}
+
+// Client implementa an Attribute Protocol Client.
+type Client struct {
+	l2c  ble.Conn
+	rspc chan []byte
+
+	rxBuf   []byte
+	chTxBuf chan []byte
+	chErr   chan error
+	handler NotificationHandler
+}
+
+// NewClient returns an Attribute Protocol Client.
+func NewClient(l2c ble.Conn, h NotificationHandler) *Client {
+	c := &Client{
+		l2c:     l2c,
+		rspc:    make(chan []byte),
+		chTxBuf: make(chan []byte, 1),
+		rxBuf:   make([]byte, ble.MaxMTU),
+		chErr:   make(chan error, 1),
+		handler: h,
+	}
+	c.chTxBuf <- make([]byte, l2c.TxMTU(), l2c.TxMTU())
+	return c
+}
+
+// ExchangeMTU informs the server of the client’s maximum receive MTU size and
+// request the server to respond with its maximum receive MTU size. [Vol 3, Part F, 3.4.2.1]
+func (c *Client) ExchangeMTU(clientRxMTU int) (serverRxMTU int, err error) {
+	if clientRxMTU < ble.DefaultMTU || clientRxMTU > ble.MaxMTU {
+		return 0, ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	// The same txBuf, or a newly allocate one, if the txMTU is changed,
+	// will be released back to the channel.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	// Let L2CAP know the MTU we can handle.
+	c.l2c.SetRxMTU(clientRxMTU)
+
+	req := ExchangeMTURequest(txBuf[:3])
+	req.SetAttributeOpcode()
+	req.SetClientRxMTU(uint16(clientRxMTU))
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return 0, err
+	}
+
+	// Convert and validate the response.
+	rsp := ExchangeMTUResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return 0, ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		fallthrough
+	case len(rsp) != 3:
+		return 0, ErrInvalidResponse
+	}
+
+	txMTU := int(rsp.ServerRxMTU())
+	if len(txBuf) != txMTU {
+		// Let L2CAP know the MTU that the remote device can handle.
+		c.l2c.SetTxMTU(txMTU)
+		// Put a re-allocated txBuf back to the channel.
+		// The txBuf has been captured in deferred function.
+		txBuf = make([]byte, txMTU, txMTU)
+	}
+
+	return txMTU, nil
+}
+
+// FindInformation obtains the mapping of attribute handles with their associated types.
+// This allows a Client to discover the list of attributes and their types on a server.
+// [Vol 3, Part F, 3.4.3.1 & 3.4.3.2]
+func (c *Client) FindInformation(starth, endh uint16) (fmt int, data []byte, err error) {
+	if starth == 0 || starth > endh {
+		return 0x00, nil, ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := FindInformationRequest(txBuf[:5])
+	req.SetAttributeOpcode()
+	req.SetStartingHandle(starth)
+	req.SetEndingHandle(endh)
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return 0x00, nil, err
+	}
+
+	// Convert and validate the response.
+	rsp := FindInformationResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return 0x00, nil, ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		fallthrough
+	case len(rsp) < 6:
+		fallthrough
+	case rsp.Format() == 0x01 && ((len(rsp)-2)%4) != 0:
+		fallthrough
+	case rsp.Format() == 0x02 && ((len(rsp)-2)%18) != 0:
+		return 0x00, nil, ErrInvalidResponse
+	}
+	return int(rsp.Format()), rsp.InformationData(), nil
+}
+
+// // HandleInformationList ...
+// type HandleInformationList []byte
+//
+// // FoundAttributeHandle ...
+// func (l HandleInformationList) FoundAttributeHandle() []byte { return l[:2] }
+//
+// // GroupEndHandle ...
+// func (l HandleInformationList) GroupEndHandle() []byte { return l[2:4] }
+//
+// // FindByTypeValue ...
+// func (c *Client) FindByTypeValue(starth, endh, attrType uint16, value []byte) ([]HandleInformationList, error) {
+// 	return nil, nil
+// }
+
+// ReadByType obtains the values of attributes where the attribute type is known
+// but the handle is not known. [Vol 3, Part F, 3.4.4.1 & 3.4.4.2]
+func (c *Client) ReadByType(starth, endh uint16, uuid ble.UUID) (int, []byte, error) {
+	if starth > endh || (len(uuid) != 2 && len(uuid) != 16) {
+		return 0, nil, ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := ReadByTypeRequest(txBuf[:5+len(uuid)])
+	req.SetAttributeOpcode()
+	req.SetStartingHandle(starth)
+	req.SetEndingHandle(endh)
+	req.SetAttributeType(uuid)
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return 0, nil, err
+	}
+
+	// Convert and validate the response.
+	rsp := ReadByTypeResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return 0, nil, ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		fallthrough
+	case len(rsp) < 4 || len(rsp.AttributeDataList())%int(rsp.Length()) != 0:
+		return 0, nil, ErrInvalidResponse
+	}
+	return int(rsp.Length()), rsp.AttributeDataList(), nil
+}
+
+// Read requests the server to read the value of an attribute and return its
+// value in a Read Response. [Vol 3, Part F, 3.4.4.3 & 3.4.4.4]
+func (c *Client) Read(handle uint16) ([]byte, error) {
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := ReadRequest(txBuf[:3])
+	req.SetAttributeOpcode()
+	req.SetAttributeHandle(handle)
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return nil, err
+	}
+
+	// Convert and validate the response.
+	rsp := ReadResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return nil, ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		fallthrough
+	case len(rsp) < 1:
+		return nil, ErrInvalidResponse
+	}
+	return rsp.AttributeValue(), nil
+}
+
+// ReadBlob requests the server to read part of the value of an attribute at a
+// given offset and return a specific part of the value in a Read Blob Response.
+// [Vol 3, Part F, 3.4.4.5 & 3.4.4.6]
+func (c *Client) ReadBlob(handle, offset uint16) ([]byte, error) {
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := ReadBlobRequest(txBuf[:5])
+	req.SetAttributeOpcode()
+	req.SetAttributeHandle(handle)
+	req.SetValueOffset(offset)
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return nil, err
+	}
+
+	// Convert and validate the response.
+	rsp := ReadBlobResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return nil, ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		fallthrough
+	case len(rsp) < 1:
+		return nil, ErrInvalidResponse
+	}
+	return rsp.PartAttributeValue(), nil
+}
+
+// ReadMultiple requests the server to read two or more values of a set of
+// attributes and return their values in a Read Multiple Response.
+// Only values that have a known fixed size can be read, with the exception of
+// the last value that can have a variable length. The knowledge of whether
+// attributes have a known fixed size is defined in a higher layer specification.
+// [Vol 3, Part F, 3.4.4.7 & 3.4.4.8]
+func (c *Client) ReadMultiple(handles []uint16) ([]byte, error) {
+	// Should request to read two or more values.
+	if len(handles) < 2 || len(handles)*2 > c.l2c.TxMTU()-1 {
+		return nil, ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := ReadMultipleRequest(txBuf[:1+len(handles)*2])
+	req.SetAttributeOpcode()
+	p := req.SetOfHandles()
+	for _, h := range handles {
+		binary.LittleEndian.PutUint16(p, h)
+		p = p[2:]
+	}
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return nil, err
+	}
+
+	// Convert and validate the response.
+	rsp := ReadMultipleResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return nil, ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		fallthrough
+	case len(rsp) < 1:
+		return nil, ErrInvalidResponse
+	}
+	return rsp.SetOfValues(), nil
+}
+
+// ReadByGroupType obtains the values of attributes where the attribute type is known,
+// the type of a grouping attribute as defined by a higher layer specification, but
+// the handle is not known. [Vol 3, Part F, 3.4.4.9 & 3.4.4.10]
+func (c *Client) ReadByGroupType(starth, endh uint16, uuid ble.UUID) (int, []byte, error) {
+	if starth > endh || (len(uuid) != 2 && len(uuid) != 16) {
+		return 0, nil, ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := ReadByGroupTypeRequest(txBuf[:5+len(uuid)])
+	req.SetAttributeOpcode()
+	req.SetStartingHandle(starth)
+	req.SetEndingHandle(endh)
+	req.SetAttributeGroupType(uuid)
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return 0, nil, err
+	}
+
+	// Convert and validate the response.
+	rsp := ReadByGroupTypeResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return 0, nil, ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		fallthrough
+	case len(rsp) < 4:
+		fallthrough
+	case len(rsp.AttributeDataList())%int(rsp.Length()) != 0:
+		return 0, nil, ErrInvalidResponse
+	}
+
+	return int(rsp.Length()), rsp.AttributeDataList(), nil
+}
+
+// Write requests the server to write the value of an attribute and acknowledge that
+// this has been achieved in a Write Response. [Vol 3, Part F, 3.4.5.1 & 3.4.5.2]
+func (c *Client) Write(handle uint16, value []byte) error {
+	if len(value) > c.l2c.TxMTU()-3 {
+		return ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := WriteRequest(txBuf[:3+len(value)])
+	req.SetAttributeOpcode()
+	req.SetAttributeHandle(handle)
+	req.SetAttributeValue(value)
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return err
+	}
+
+	// Convert and validate the response.
+	rsp := WriteResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		return ErrInvalidResponse
+	}
+	return nil
+}
+
+// WriteCommand requests the server to write the value of an attribute, typically
+// into a control-point attribute. [Vol 3, Part F, 3.4.5.3]
+func (c *Client) WriteCommand(handle uint16, value []byte) error {
+	if len(value) > c.l2c.TxMTU()-3 {
+		return ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := WriteCommand(txBuf[:3+len(value)])
+	req.SetAttributeOpcode()
+	req.SetAttributeHandle(handle)
+	req.SetAttributeValue(value)
+
+	return c.sendCmd(req)
+}
+
+// SignedWrite requests the server to write the value of an attribute with an authentication
+// signature, typically into a control-point attribute. [Vol 3, Part F, 3.4.5.4]
+func (c *Client) SignedWrite(handle uint16, value []byte, signature [12]byte) error {
+	if len(value) > c.l2c.TxMTU()-15 {
+		return ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := SignedWriteCommand(txBuf[:15+len(value)])
+	req.SetAttributeOpcode()
+	req.SetAttributeHandle(handle)
+	req.SetAttributeValue(value)
+	req.SetAuthenticationSignature(signature)
+
+	return c.sendCmd(req)
+}
+
+// PrepareWrite requests the server to prepare to write the value of an attribute.
+// The server will respond to this request with a Prepare Write Response, so that
+// the Client can verify that the value was received correctly.
+// [Vol 3, Part F, 3.4.6.1 & 3.4.6.2]
+func (c *Client) PrepareWrite(handle uint16, offset uint16, value []byte) (uint16, uint16, []byte, error) {
+	if len(value) > c.l2c.TxMTU()-5 {
+		return 0, 0, nil, ErrInvalidArgument
+	}
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := PrepareWriteRequest(txBuf[:5+len(value)])
+	req.SetAttributeOpcode()
+	req.SetAttributeHandle(handle)
+	req.SetValueOffset(offset)
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return 0, 0, nil, err
+	}
+
+	// Convert and validate the response.
+	rsp := PrepareWriteResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return 0, 0, nil, ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		fallthrough
+	case len(rsp) < 5:
+		return 0, 0, nil, ErrInvalidResponse
+	}
+	return rsp.AttributeHandle(), rsp.ValueOffset(), rsp.PartAttributeValue(), nil
+}
+
+// ExecuteWrite requests the server to write or cancel the write of all the prepared
+// values currently held in the prepare queue from this Client. This request shall be
+// handled by the server as an atomic operation. [Vol 3, Part F, 3.4.6.3 & 3.4.6.4]
+func (c *Client) ExecuteWrite(flags uint8) error {
+
+	// Acquire and reuse the txBuf, and release it after usage.
+	txBuf := <-c.chTxBuf
+	defer func() { c.chTxBuf <- txBuf }()
+
+	req := ExecuteWriteRequest(txBuf[:1])
+	req.SetAttributeOpcode()
+	req.SetFlags(flags)
+
+	b, err := c.sendReq(req)
+	if err != nil {
+		return err
+	}
+
+	// Convert and validate the response.
+	rsp := ExecuteWriteResponse(b)
+	switch {
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		return ble.ATTError(rsp[4])
+	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
+		fallthrough
+	case rsp[0] != rsp.AttributeOpcode():
+		return ErrInvalidResponse
+	}
+	return nil
+}
+
+func (c *Client) sendCmd(b []byte) error {
+	_, err := c.l2c.Write(b)
+	return err
+}
+
+func (c *Client) sendReq(b []byte) (rsp []byte, err error) {
+	logger.Debug("client", "req", fmt.Sprintf("% X", b))
+	if _, err := c.l2c.Write(b); err != nil {
+		return nil, errors.Wrap(err, "send ATT request failed")
+	}
+	for {
+		select {
+		case rsp := <-c.rspc:
+			if rsp[0] == ErrorResponseCode || rsp[0] == rspOfReq[b[0]] {
+				return rsp, nil
+			}
+			// Sometimes when we connect to an Apple device, it sends
+			// ATT requests asynchronously to us. // In this case, we
+			// returns an ErrReqNotSupp response, and continue to wait
+			// the response to our request.
+			errRsp := newErrorResponse(rsp[0], 0x0000, ble.ErrReqNotSupp)
+			logger.Debug("client", "req", fmt.Sprintf("% X", b))
+			_, err := c.l2c.Write(errRsp)
+			if err != nil {
+				return nil, errors.Wrap(err, "unexpected ATT response recieved")
+			}
+		case err := <-c.chErr:
+			return nil, errors.Wrap(err, "ATT request failed")
+		case <-time.After(30 * time.Second):
+			return nil, errors.Wrap(ErrSeqProtoTimeout, "ATT request timeout")
+		}
+	}
+}
+
+// Loop ...
+func (c *Client) Loop() {
+
+	type asyncWork struct {
+		handle func([]byte)
+		data   []byte
+	}
+
+	ch := make(chan asyncWork, 16)
+	defer close(ch)
+	go func() {
+		for w := range ch {
+			w.handle(w.data)
+		}
+	}()
+
+	confirmation := []byte{HandleValueConfirmationCode}
+	for {
+		n, err := c.l2c.Read(c.rxBuf)
+		logger.Debug("client", "rsp", fmt.Sprintf("% X", c.rxBuf[:n]))
+		if err != nil {
+			// We don't expect any error from the bearer (L2CAP ACL-U)
+			// Pass it along to the pending request, if any, and escape.
+			c.chErr <- err
+			return
+		}
+
+		b := make([]byte, n)
+		copy(b, c.rxBuf)
+
+		if (b[0] != HandleValueNotificationCode) && (b[0] != HandleValueIndicationCode) {
+			c.rspc <- b
+			continue
+		}
+
+		// Deliver the full request to upper layer.
+		select {
+		case ch <- asyncWork{handle: c.handler.HandleNotification, data: b}:
+		default:
+			// If this really happens, especially on a slow machine, enlarge the channel buffer.
+			logger.Error("client", "req", "can't enqueue incoming notification.")
+		}
+
+		// Always write aknowledgement for an indication, even it was an invalid request.
+		if b[0] == HandleValueIndicationCode {
+			logger.Debug("client", "req", fmt.Sprintf("% X", b))
+			c.l2c.Write(confirmation)
+		}
+	}
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/att/db.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/db.go
new file mode 100644
index 0000000..6ddb55d
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/db.go
@@ -0,0 +1,210 @@
+package att
+
+import (
+	"encoding/binary"
+	"fmt"
+
+	"github.com/currantlabs/ble"
+)
+
+// A DB is a contiguous range of attributes.
+type DB struct {
+	attrs []*attr
+	base  uint16 // handle for first attr in attrs
+}
+
+const (
+	tooSmall = -1
+	tooLarge = -2
+)
+
+// idx returns the idx into attrs corresponding to attr a.
+// If h is too small, idx returns tooSmall (-1).
+// If h is too large, idx returns tooLarge (-2).
+func (r *DB) idx(h int) int {
+	if h < int(r.base) {
+		return tooSmall
+	}
+	if int(h) >= int(r.base)+len(r.attrs) {
+		return tooLarge
+	}
+	return h - int(r.base)
+}
+
+// at returns attr a.
+func (r *DB) at(h uint16) (a *attr, ok bool) {
+	i := r.idx(int(h))
+	if i < 0 {
+		return nil, false
+	}
+	return r.attrs[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 *DB) 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.attrs)
+	}
+	return r.attrs[startidx:endidx]
+}
+
+// NewDB ...
+func NewDB(ss []*ble.Service, base uint16) *DB {
+	h := base
+	var attrs []*attr
+	var aa []*attr
+	for i, s := range ss {
+		h, aa = genSvcAttr(s, h)
+		if i == len(ss)-1 {
+			aa[0].endh = 0xFFFF
+		}
+		attrs = append(attrs, aa...)
+	}
+	DumpAttributes(attrs)
+	return &DB{attrs: attrs, base: base}
+}
+
+func genSvcAttr(s *ble.Service, h uint16) (uint16, []*attr) {
+	a := &attr{
+		h:   h,
+		typ: ble.PrimaryServiceUUID,
+		v:   s.UUID,
+	}
+	h++
+	attrs := []*attr{a}
+	var aa []*attr
+
+	for _, c := range s.Characteristics {
+		h, aa = genCharAttr(c, h)
+		attrs = append(attrs, aa...)
+	}
+
+	a.endh = h - 1
+	return h, attrs
+}
+
+func genCharAttr(c *ble.Characteristic, h uint16) (uint16, []*attr) {
+	vh := h + 1
+
+	a := &attr{
+		h:   h,
+		typ: ble.CharacteristicUUID,
+		v:   append([]byte{byte(c.Property), byte(vh), byte((vh) >> 8)}, c.UUID...),
+	}
+
+	va := &attr{
+		h:   vh,
+		typ: c.UUID,
+		v:   c.Value,
+		rh:  c.ReadHandler,
+		wh:  c.WriteHandler,
+	}
+
+	c.Handle = h
+	c.ValueHandle = vh
+	if c.NotifyHandler != nil || c.IndicateHandler != nil {
+		c.CCCD = newCCCD(c)
+		c.Descriptors = append(c.Descriptors, c.CCCD)
+	}
+
+	h += 2
+
+	attrs := []*attr{a, va}
+	for _, d := range c.Descriptors {
+		attrs = append(attrs, genDescAttr(d, h))
+		h++
+	}
+
+	a.endh = h - 1
+	return h, attrs
+}
+
+func genDescAttr(d *ble.Descriptor, h uint16) *attr {
+	return &attr{
+		h:   h,
+		typ: d.UUID,
+		v:   d.Value,
+		rh:  d.ReadHandler,
+		wh:  d.WriteHandler,
+	}
+}
+
+// DumpAttributes ...
+func DumpAttributes(aa []*attr) {
+	logger.Debug("server", "db", "Generating attribute table:")
+	logger.Debug("server", "db", "handle   endh   type")
+	for _, a := range aa {
+		if a.v != nil {
+			logger.Debug("server", "db", fmt.Sprintf("0x%04X 0x%04X 0x%s [% X]", a.h, a.endh, a.typ, a.v))
+			continue
+		}
+		logger.Debug("server", "db", fmt.Sprintf("0x%04X 0x%04X 0x%s", a.h, a.endh, a.typ))
+	}
+}
+
+const (
+	cccNotify   = 0x0001
+	cccIndicate = 0x0002
+)
+
+func newCCCD(c *ble.Characteristic) *ble.Descriptor {
+	d := ble.NewDescriptor(ble.ClientCharacteristicConfigUUID)
+
+	d.HandleRead(ble.ReadHandlerFunc(func(req ble.Request, rsp ble.ResponseWriter) {
+		cccs := req.Conn().(*conn).cccs
+		ccc := cccs[c.Handle]
+		binary.Write(rsp, binary.LittleEndian, ccc)
+	}))
+
+	d.HandleWrite(ble.WriteHandlerFunc(func(req ble.Request, rsp ble.ResponseWriter) {
+		cn := req.Conn().(*conn)
+		old := cn.cccs[c.Handle]
+		ccc := binary.LittleEndian.Uint16(req.Data())
+
+		oldNotify := old&cccNotify != 0
+		oldIndicate := old&cccIndicate != 0
+		newNotify := ccc&cccNotify != 0
+		newIndicate := ccc&cccIndicate != 0
+
+		if newNotify && !oldNotify {
+			if c.Property&ble.CharNotify == 0 {
+				rsp.SetStatus(ble.ErrUnlikely)
+				return
+			}
+			send := func(b []byte) (int, error) { return cn.svr.notify(c.ValueHandle, b) }
+			cn.nn[c.Handle] = ble.NewNotifier(send)
+			go c.NotifyHandler.ServeNotify(req, cn.nn[c.Handle])
+		}
+		if !newNotify && oldNotify {
+			cn.nn[c.Handle].Close()
+		}
+
+		if newIndicate && !oldIndicate {
+			if c.Property&ble.CharIndicate == 0 {
+				rsp.SetStatus(ble.ErrUnlikely)
+				return
+			}
+			send := func(b []byte) (int, error) { return cn.svr.indicate(c.ValueHandle, b) }
+			cn.in[c.Handle] = ble.NewNotifier(send)
+			go c.IndicateHandler.ServeNotify(req, cn.in[c.Handle])
+		}
+		if !newIndicate && oldIndicate {
+			cn.in[c.Handle].Close()
+		}
+		cn.cccs[c.Handle] = ccc
+	}))
+	return d
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/att/log.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/log.go
new file mode 100644
index 0000000..61d7f60
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/log.go
@@ -0,0 +1,7 @@
+package att
+
+import (
+	"github.com/mgutz/logxi/v1"
+)
+
+var logger = log.New("att")
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/att/server.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/server.go
new file mode 100644
index 0000000..387a121
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/att/server.go
@@ -0,0 +1,594 @@
+package att
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"time"
+
+	"github.com/currantlabs/ble"
+)
+
+type conn struct {
+	ble.Conn
+	svr  *Server
+	cccs map[uint16]uint16
+	nn   map[uint16]ble.Notifier
+	in   map[uint16]ble.Notifier
+}
+
+// Server implementas an ATT (Attribute Protocol) server.
+type Server struct {
+	conn *conn
+	db   *DB
+
+	// Refer to [Vol 3, Part F, 3.3.2 & 3.3.3] for the requirement of
+	// sequential request-response protocol, and transactions.
+	rxMTU     int
+	txBuf     []byte
+	chNotBuf  chan []byte
+	chIndBuf  chan []byte
+	chConfirm chan bool
+
+	dummyRspWriter ble.ResponseWriter
+}
+
+// NewServer returns an ATT (Attribute Protocol) server.
+func NewServer(db *DB, l2c ble.Conn) (*Server, error) {
+	mtu := l2c.RxMTU()
+	if mtu < ble.DefaultMTU || mtu > ble.MaxMTU {
+		return nil, fmt.Errorf("invalid MTU")
+	}
+	// Although the rxBuf is initialized with the capacity of rxMTU, it is
+	// not discovered, and only the default ATT_MTU (23 bytes) of it shall
+	// be used until remote central request ExchangeMTU.
+	s := &Server{
+		conn: &conn{
+			Conn: l2c,
+			cccs: make(map[uint16]uint16),
+			in:   make(map[uint16]ble.Notifier),
+			nn:   make(map[uint16]ble.Notifier),
+		},
+		db: db,
+
+		rxMTU:     mtu,
+		txBuf:     make([]byte, ble.DefaultMTU, ble.DefaultMTU),
+		chNotBuf:  make(chan []byte, 1),
+		chIndBuf:  make(chan []byte, 1),
+		chConfirm: make(chan bool),
+
+		dummyRspWriter: ble.NewResponseWriter(nil),
+	}
+	s.conn.svr = s
+	s.chNotBuf <- make([]byte, ble.DefaultMTU, ble.DefaultMTU)
+	s.chIndBuf <- make([]byte, ble.DefaultMTU, ble.DefaultMTU)
+	return s, nil
+}
+
+// notify sends notification to remote central.
+func (s *Server) notify(h uint16, data []byte) (int, error) {
+	// Acquire and reuse notifyBuffer. Release it after usage.
+	nBuf := <-s.chNotBuf
+	defer func() { s.chNotBuf <- nBuf }()
+
+	rsp := HandleValueNotification(nBuf)
+	rsp.SetAttributeOpcode()
+	rsp.SetAttributeHandle(h)
+	buf := bytes.NewBuffer(rsp.AttributeValue())
+	buf.Reset()
+	if len(data) > buf.Cap() {
+		data = data[:buf.Cap()]
+	}
+	buf.Write(data)
+	return s.conn.Write(rsp[:3+buf.Len()])
+}
+
+// indicate sends indication to remote central.
+func (s *Server) indicate(h uint16, data []byte) (int, error) {
+	// Acquire and reuse indicateBuffer. Release it after usage.
+	iBuf := <-s.chIndBuf
+	defer func() { s.chIndBuf <- iBuf }()
+
+	rsp := HandleValueIndication(iBuf)
+	rsp.SetAttributeOpcode()
+	rsp.SetAttributeHandle(h)
+	buf := bytes.NewBuffer(rsp.AttributeValue())
+	buf.Reset()
+	if len(data) > buf.Cap() {
+		data = data[:buf.Cap()]
+	}
+	buf.Write(data)
+	n, err := s.conn.Write(rsp[:3+buf.Len()])
+	if err != nil {
+		return n, err
+	}
+	select {
+	case _, ok := <-s.chConfirm:
+		if !ok {
+			return 0, io.ErrClosedPipe
+		}
+		return n, nil
+	case <-time.After(time.Second * 30):
+		return 0, ErrSeqProtoTimeout
+	}
+}
+
+// Loop accepts incoming ATT request, and respond response.
+func (s *Server) Loop() {
+	type sbuf struct {
+		buf []byte
+		len int
+	}
+	pool := make(chan *sbuf, 2)
+	pool <- &sbuf{buf: make([]byte, s.rxMTU)}
+	pool <- &sbuf{buf: make([]byte, s.rxMTU)}
+
+	seq := make(chan *sbuf)
+	go func() {
+		b := <-pool
+		for {
+			n, err := s.conn.Read(b.buf)
+			if n == 0 || err != nil {
+				close(seq)
+				close(s.chConfirm)
+				_ = s.conn.Close()
+				return
+			}
+			if b.buf[0] == HandleValueConfirmationCode {
+				select {
+				case s.chConfirm <- true:
+				default:
+					logger.Error("server", "recieved a spurious confirmation", nil)
+				}
+				continue
+			}
+			b.len = n
+			seq <- b   // Send the current request for handling
+			b = <-pool // Swap the buffer for next incoming request.
+		}
+	}()
+	for req := range seq {
+		if rsp := s.handleRequest(req.buf[:req.len]); rsp != nil {
+			if len(rsp) != 0 {
+				s.conn.Write(rsp)
+			}
+		}
+		pool <- req
+	}
+	for h, ccc := range s.conn.cccs {
+		if ccc != 0 {
+			logger.Info("cleanup", "ccc", fmt.Sprintf("0x%02X", ccc))
+		}
+		if ccc&cccIndicate != 0 {
+			s.conn.in[h].Close()
+		}
+		if ccc&cccNotify != 0 {
+			s.conn.nn[h].Close()
+		}
+	}
+}
+
+func (s *Server) handleRequest(b []byte) []byte {
+	var resp []byte
+	logger.Debug("server", "req", fmt.Sprintf("% X", b))
+	switch reqType := b[0]; reqType {
+	case ExchangeMTURequestCode:
+		resp = s.handleExchangeMTURequest(b)
+	case FindInformationRequestCode:
+		resp = s.handleFindInformationRequest(b)
+	case FindByTypeValueRequestCode:
+		resp = s.handleFindByTypeValueRequest(b)
+	case ReadByTypeRequestCode:
+		resp = s.handleReadByTypeRequest(b)
+	case ReadRequestCode:
+		resp = s.handleReadRequest(b)
+	case ReadBlobRequestCode:
+		resp = s.handleReadBlobRequest(b)
+	case ReadByGroupTypeRequestCode:
+		resp = s.handleReadByGroupRequest(b)
+	case WriteRequestCode:
+		resp = s.handleWriteRequest(b)
+	case WriteCommandCode:
+		s.handleWriteCommand(b)
+	case ReadMultipleRequestCode,
+		PrepareWriteRequestCode,
+		ExecuteWriteRequestCode,
+		SignedWriteCommandCode:
+		fallthrough
+	default:
+		resp = newErrorResponse(reqType, 0x0000, ble.ErrReqNotSupp)
+	}
+	logger.Debug("server", "rsp", fmt.Sprintf("% X", resp))
+	return resp
+}
+
+// handle MTU Exchange request. [Vol 3, Part F, 3.4.2]
+func (s *Server) handleExchangeMTURequest(r ExchangeMTURequest) []byte {
+	// Validate the request.
+	switch {
+	case len(r) != 3:
+		fallthrough
+	case r.ClientRxMTU() < 23:
+		return newErrorResponse(r.AttributeOpcode(), 0x0000, ble.ErrInvalidPDU)
+	}
+
+	txMTU := int(r.ClientRxMTU())
+	s.conn.SetTxMTU(txMTU)
+
+	if txMTU != len(s.txBuf) {
+		// Apply the txMTU afer this response has been sent and before
+		// any other attribute protocol PDU is sent.
+		defer func() {
+			s.txBuf = make([]byte, txMTU, txMTU)
+			<-s.chNotBuf
+			s.chNotBuf <- make([]byte, txMTU, txMTU)
+			<-s.chIndBuf
+			s.chIndBuf <- make([]byte, txMTU, txMTU)
+		}()
+	}
+
+	rsp := ExchangeMTUResponse(s.txBuf)
+	rsp.SetAttributeOpcode()
+	rsp.SetServerRxMTU(uint16(s.rxMTU))
+	return rsp[:3]
+}
+
+// handle Find Information request. [Vol 3, Part F, 3.4.3.1 & 3.4.3.2]
+func (s *Server) handleFindInformationRequest(r FindInformationRequest) []byte {
+	// Validate the request.
+	switch {
+	case len(r) != 5:
+		return newErrorResponse(r.AttributeOpcode(), 0x0000, ble.ErrInvalidPDU)
+	case r.StartingHandle() == 0 || r.StartingHandle() > r.EndingHandle():
+		return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrInvalidHandle)
+	}
+
+	rsp := FindInformationResponse(s.txBuf)
+	rsp.SetAttributeOpcode()
+	rsp.SetFormat(0x00)
+	buf := bytes.NewBuffer(rsp.InformationData())
+	buf.Reset()
+
+	// Each response shall contain Types of the same format.
+	for _, a := range s.db.subrange(r.StartingHandle(), r.EndingHandle()) {
+		if rsp.Format() == 0 {
+			rsp.SetFormat(0x01)
+			if a.typ.Len() == 16 {
+				rsp.SetFormat(0x02)
+			}
+		}
+		if rsp.Format() == 0x01 && a.typ.Len() != 2 {
+			break
+		}
+		if rsp.Format() == 0x02 && a.typ.Len() != 16 {
+			break
+		}
+
+		if buf.Len()+2+a.typ.Len() > buf.Cap() {
+			break
+		}
+		binary.Write(buf, binary.LittleEndian, a.h)
+		binary.Write(buf, binary.LittleEndian, a.typ)
+	}
+
+	// Nothing has been found.
+	if rsp.Format() == 0 {
+		return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrAttrNotFound)
+	}
+	return rsp[:2+buf.Len()]
+}
+
+// handle Find By Type Value request. [Vol 3, Part F, 3.4.3.3 & 3.4.3.4]
+func (s *Server) handleFindByTypeValueRequest(r FindByTypeValueRequest) []byte {
+	// Validate the request.
+	switch {
+	case len(r) < 7:
+		return newErrorResponse(r.AttributeOpcode(), 0x0000, ble.ErrInvalidPDU)
+	case r.StartingHandle() == 0 || r.StartingHandle() > r.EndingHandle():
+		return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrInvalidHandle)
+	}
+
+	rsp := FindByTypeValueResponse(s.txBuf)
+	rsp.SetAttributeOpcode()
+	buf := bytes.NewBuffer(rsp.HandleInformationList())
+	buf.Reset()
+
+	for _, a := range s.db.subrange(r.StartingHandle(), r.EndingHandle()) {
+		v, starth, endh := a.v, a.h, a.endh
+		if v == nil {
+			// The value shall not exceed ATT_MTU - 7 bytes.
+			// Since ResponseWriter caps the value at the capacity,
+			// we allocate one extra byte, and the written length.
+			buf2 := bytes.NewBuffer(make([]byte, 0, len(s.txBuf)-7+1))
+			e := handleATT(a, s.conn, r, ble.NewResponseWriter(buf2))
+			if e != ble.ErrSuccess || buf2.Len() > len(s.txBuf)-7 {
+				return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrInvalidHandle)
+			}
+			endh = a.h
+		}
+		if !(ble.UUID(v).Equal(ble.UUID(r.AttributeValue()))) {
+			continue
+		}
+
+		if buf.Len()+4 > buf.Cap() {
+			break
+		}
+		binary.Write(buf, binary.LittleEndian, starth)
+		binary.Write(buf, binary.LittleEndian, endh)
+	}
+	if buf.Len() == 0 {
+		return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrAttrNotFound)
+	}
+
+	return rsp[:1+buf.Len()]
+}
+
+// handle Read By Type request. [Vol 3, Part F, 3.4.4.1 & 3.4.4.2]
+func (s *Server) handleReadByTypeRequest(r ReadByTypeRequest) []byte {
+	// Validate the request.
+	switch {
+	case len(r) != 7 && len(r) != 21:
+		return newErrorResponse(r.AttributeOpcode(), 0x0000, ble.ErrInvalidPDU)
+	case r.StartingHandle() == 0 || r.StartingHandle() > r.EndingHandle():
+		return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrInvalidHandle)
+	}
+
+	rsp := ReadByTypeResponse(s.txBuf)
+	rsp.SetAttributeOpcode()
+	buf := bytes.NewBuffer(rsp.AttributeDataList())
+	buf.Reset()
+
+	// handle length (2 bytes) + value length.
+	// Each response shall only contains values with the same size.
+	dlen := 0
+	for _, a := range s.db.subrange(r.StartingHandle(), r.EndingHandle()) {
+		if !a.typ.Equal(ble.UUID(r.AttributeType())) {
+			continue
+		}
+		v := a.v
+		if v == nil {
+			buf2 := bytes.NewBuffer(make([]byte, 0, len(s.txBuf)-2))
+			if e := handleATT(a, s.conn, r, ble.NewResponseWriter(buf2)); e != ble.ErrSuccess {
+				// Return if the first value read cause an error.
+				if dlen == 0 {
+					return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), e)
+				}
+				// Otherwise, skip to the next one.
+				break
+			}
+			v = buf2.Bytes()
+		}
+		if dlen == 0 {
+			// Found the first value.
+			dlen = 2 + len(v)
+			if dlen > 255 {
+				dlen = 255
+			}
+			if dlen > buf.Cap() {
+				dlen = buf.Cap()
+			}
+			rsp.SetLength(uint8(dlen))
+		} else if 2+len(v) != dlen {
+			break
+		}
+
+		if buf.Len()+dlen > buf.Cap() {
+			break
+		}
+		binary.Write(buf, binary.LittleEndian, a.h)
+		binary.Write(buf, binary.LittleEndian, v[:dlen-2])
+	}
+	if dlen == 0 {
+		return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrAttrNotFound)
+	}
+	return rsp[:2+buf.Len()]
+}
+
+// handle Read request. [Vol 3, Part F, 3.4.4.3 & 3.4.4.4]
+func (s *Server) handleReadRequest(r ReadRequest) []byte {
+	// Validate the request.
+	switch {
+	case len(r) != 3:
+		return newErrorResponse(r.AttributeOpcode(), 0x0000, ble.ErrInvalidPDU)
+	}
+
+	rsp := ReadResponse(s.txBuf)
+	rsp.SetAttributeOpcode()
+	buf := bytes.NewBuffer(rsp.AttributeValue())
+	buf.Reset()
+
+	a, ok := s.db.at(r.AttributeHandle())
+	if !ok {
+		return newErrorResponse(r.AttributeOpcode(), r.AttributeHandle(), ble.ErrInvalidHandle)
+	}
+
+	// Simple case. Read-only, no-authorization, no-authentication.
+	if a.v != nil {
+		binary.Write(buf, binary.LittleEndian, a.v)
+		return rsp[:1+buf.Len()]
+	}
+
+	// Pass the request to upper layer with the ResponseWriter, which caps
+	// the buffer to a valid length of payload.
+	if e := handleATT(a, s.conn, r, ble.NewResponseWriter(buf)); e != ble.ErrSuccess {
+		return newErrorResponse(r.AttributeOpcode(), r.AttributeHandle(), e)
+	}
+	return rsp[:1+buf.Len()]
+}
+
+// handle Read Blob request. [Vol 3, Part F, 3.4.4.5 & 3.4.4.6]
+func (s *Server) handleReadBlobRequest(r ReadBlobRequest) []byte {
+	// Validate the request.
+	switch {
+	case len(r) != 5:
+		return newErrorResponse(r.AttributeOpcode(), 0x0000, ble.ErrInvalidPDU)
+	}
+
+	a, ok := s.db.at(r.AttributeHandle())
+	if !ok {
+		return newErrorResponse(r.AttributeOpcode(), r.AttributeHandle(), ble.ErrInvalidHandle)
+	}
+
+	rsp := ReadBlobResponse(s.txBuf)
+	rsp.SetAttributeOpcode()
+	buf := bytes.NewBuffer(rsp.PartAttributeValue())
+	buf.Reset()
+
+	// Simple case. Read-only, no-authorization, no-authentication.
+	if a.v != nil {
+		binary.Write(buf, binary.LittleEndian, a.v)
+		return rsp[:1+buf.Len()]
+	}
+
+	// Pass the request to upper layer with the ResponseWriter, which caps
+	// the buffer to a valid length of payload.
+	if e := handleATT(a, s.conn, r, ble.NewResponseWriter(buf)); e != ble.ErrSuccess {
+		return newErrorResponse(r.AttributeOpcode(), r.AttributeHandle(), e)
+	}
+	return rsp[:1+buf.Len()]
+}
+
+// handle Read Blob request. [Vol 3, Part F, 3.4.4.9 & 3.4.4.10]
+func (s *Server) handleReadByGroupRequest(r ReadByGroupTypeRequest) []byte {
+	// Validate the request.
+	switch {
+	case len(r) != 7 && len(r) != 21:
+		return newErrorResponse(r.AttributeOpcode(), 0x0000, ble.ErrInvalidPDU)
+	case r.StartingHandle() == 0 || r.StartingHandle() > r.EndingHandle():
+		return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrInvalidHandle)
+	}
+
+	rsp := ReadByGroupTypeResponse(s.txBuf)
+	rsp.SetAttributeOpcode()
+	buf := bytes.NewBuffer(rsp.AttributeDataList())
+	buf.Reset()
+
+	dlen := 0
+	for _, a := range s.db.subrange(r.StartingHandle(), r.EndingHandle()) {
+		v := a.v
+		if v == nil {
+			buf2 := bytes.NewBuffer(make([]byte, buf.Cap()-buf.Len()-4))
+			if e := handleATT(a, s.conn, r, ble.NewResponseWriter(buf2)); e != ble.ErrSuccess {
+				return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), e)
+			}
+			v = buf2.Bytes()
+		}
+		if dlen == 0 {
+			dlen = 4 + len(v)
+			if dlen > 255 {
+				dlen = 255
+			}
+			if dlen > buf.Cap() {
+				dlen = buf.Cap()
+			}
+			rsp.SetLength(uint8(dlen))
+		} else if 4+len(v) != dlen {
+			break
+		}
+
+		if buf.Len()+dlen > buf.Cap() {
+			break
+		}
+		binary.Write(buf, binary.LittleEndian, a.h)
+		binary.Write(buf, binary.LittleEndian, a.endh)
+		binary.Write(buf, binary.LittleEndian, v[:dlen-4])
+	}
+	if dlen == 0 {
+		return newErrorResponse(r.AttributeOpcode(), r.StartingHandle(), ble.ErrAttrNotFound)
+	}
+	return rsp[:2+buf.Len()]
+}
+
+// handle Write request. [Vol 3, Part F, 3.4.5.1 & 3.4.5.2]
+func (s *Server) handleWriteRequest(r WriteRequest) []byte {
+	// Validate the request.
+	switch {
+	case len(r) < 3:
+		return newErrorResponse(r.AttributeOpcode(), 0x0000, ble.ErrInvalidPDU)
+	}
+
+	a, ok := s.db.at(r.AttributeHandle())
+	if !ok {
+		return newErrorResponse(r.AttributeOpcode(), r.AttributeHandle(), ble.ErrInvalidHandle)
+	}
+
+	// We don't support write to static value. Pass the request to upper layer.
+	if a == nil {
+		return newErrorResponse(r.AttributeOpcode(), r.AttributeHandle(), ble.ErrWriteNotPerm)
+	}
+	if e := handleATT(a, s.conn, r, ble.NewResponseWriter(nil)); e != ble.ErrSuccess {
+		return newErrorResponse(r.AttributeOpcode(), r.AttributeHandle(), e)
+	}
+	return []byte{WriteResponseCode}
+}
+
+// handle Write command. [Vol 3, Part F, 3.4.5.3]
+func (s *Server) handleWriteCommand(r WriteCommand) []byte {
+	// Validate the request.
+	switch {
+	case len(r) <= 3:
+		return nil
+	}
+
+	a, ok := s.db.at(r.AttributeHandle())
+	if !ok {
+		return nil
+	}
+
+	// We don't support write to static value. Pass the request to upper layer.
+	if a == nil {
+		return nil
+	}
+	if e := handleATT(a, s.conn, r, s.dummyRspWriter); e != ble.ErrSuccess {
+		return nil
+	}
+	return nil
+}
+
+func newErrorResponse(op byte, h uint16, s ble.ATTError) []byte {
+	r := ErrorResponse(make([]byte, 5))
+	r.SetAttributeOpcode()
+	r.SetRequestOpcodeInError(op)
+	r.SetAttributeInError(h)
+	r.SetErrorCode(uint8(s))
+	return r
+}
+
+func handleATT(a *attr, conn ble.Conn, req []byte, rsp ble.ResponseWriter) ble.ATTError {
+	rsp.SetStatus(ble.ErrSuccess)
+	var offset int
+	var data []byte
+	switch req[0] {
+	case ReadByTypeRequestCode:
+		fallthrough
+	case ReadRequestCode:
+		if a.rh == nil {
+			return ble.ErrReadNotPerm
+		}
+		a.rh.ServeRead(ble.NewRequest(conn, data, offset), rsp)
+	case ReadBlobRequestCode:
+		if a.rh == nil {
+			return ble.ErrReadNotPerm
+		}
+		offset = int(ReadBlobRequest(req).ValueOffset())
+		a.rh.ServeRead(ble.NewRequest(conn, data, offset), rsp)
+	case WriteRequestCode:
+		fallthrough
+	case WriteCommandCode:
+		if a.wh == nil {
+			return ble.ErrWriteNotPerm
+		}
+		data = WriteRequest(req).AttributeValue()
+		a.wh.ServeWrite(ble.NewRequest(conn, data, offset), rsp)
+	// case PrepareWriteRequestCode:
+	// case ExecuteWriteRequestCode:
+	// case SignedWriteCommandCode:
+	// case ReadByGroupTypeRequestCode:
+	// case ReadMultipleRequestCode:
+	default:
+		return ble.ErrReqNotSupp
+	}
+
+	return rsp.Status()
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/device.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/device.go
new file mode 100644
index 0000000..52a6fbd
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/device.go
@@ -0,0 +1,165 @@
+package linux
+
+import (
+	"log"
+
+	"github.com/pkg/errors"
+	"golang.org/x/net/context"
+
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/linux/att"
+	"github.com/currantlabs/ble/linux/gatt"
+	"github.com/currantlabs/ble/linux/hci"
+)
+
+// NewDevice returns the default HCI device.
+func NewDevice() (*Device, error) {
+	dev, err := hci.NewHCI()
+	if err != nil {
+		return nil, errors.Wrap(err, "can't create hci")
+	}
+	if err = dev.Init(); err != nil {
+		return nil, errors.Wrap(err, "can't init hci")
+	}
+
+	s, err := gatt.NewServer()
+	if err != nil {
+		return nil, errors.Wrap(err, "can't create server")
+	}
+
+	mtu := ble.DefaultMTU
+	mtu = ble.MaxMTU // TODO: get this from user using Option.
+	if mtu > ble.MaxMTU {
+		return nil, errors.Wrapf(err, "maximum ATT_MTU is %d", ble.MaxMTU)
+	}
+
+	go func() {
+		for {
+			l2c, err := dev.Accept()
+			if err != nil {
+				log.Printf("can't accept: %s", err)
+				return
+			}
+
+			// Initialize the per-connection cccd values.
+			l2c.SetContext(context.WithValue(l2c.Context(), "ccc", make(map[uint16]uint16)))
+			l2c.SetRxMTU(mtu)
+
+			s.Lock()
+			as, err := att.NewServer(s.DB(), l2c)
+			s.Unlock()
+			if err != nil {
+				log.Printf("can't create ATT server: %s", err)
+				continue
+
+			}
+			go as.Loop()
+		}
+	}()
+	return &Device{HCI: dev, Server: s}, nil
+}
+
+// Device ...
+type Device struct {
+	HCI    *hci.HCI
+	Server *gatt.Server
+}
+
+// AddService adds a service to database.
+func (d *Device) AddService(svc *ble.Service) error {
+	return d.Server.AddService(svc)
+}
+
+// RemoveAllServices removes all services that are currently in the database.
+func (d *Device) RemoveAllServices() error {
+	return d.Server.RemoveAllServices()
+}
+
+// SetServices set the specified service to the database.
+// It removes all currently added services, if any.
+func (d *Device) SetServices(svcs []*ble.Service) error {
+	return d.Server.SetServices(svcs)
+}
+
+// Stop stops gatt server.
+func (d *Device) Stop() error {
+	return d.HCI.Close()
+}
+
+// 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.
+func (d *Device) AdvertiseNameAndServices(ctx context.Context, name string, uuids ...ble.UUID) error {
+	if err := d.HCI.AdvertiseNameAndServices(name, uuids...); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	d.HCI.StopAdvertising()
+	return ctx.Err()
+}
+
+// AdvertiseMfgData avertises the given manufacturer data.
+func (d *Device) AdvertiseMfgData(ctx context.Context, id uint16, b []byte) error {
+	if err := d.HCI.AdvertiseMfgData(id, b); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	d.HCI.StopAdvertising()
+	return ctx.Err()
+}
+
+// AdvertiseServiceData16 advertises data associated with a 16bit service uuid
+func (d *Device) AdvertiseServiceData16(ctx context.Context, id uint16, b []byte) error {
+	if err := d.HCI.AdvertiseServiceData16(id, b); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	d.HCI.StopAdvertising()
+	return ctx.Err()
+}
+
+// AdvertiseIBeaconData advertise iBeacon with given manufacturer data.
+func (d *Device) AdvertiseIBeaconData(ctx context.Context, b []byte) error {
+	if err := d.HCI.AdvertiseIBeaconData(b); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	d.HCI.StopAdvertising()
+	return ctx.Err()
+}
+
+// AdvertiseIBeacon advertises iBeacon with specified parameters.
+func (d *Device) AdvertiseIBeacon(ctx context.Context, u ble.UUID, major, minor uint16, pwr int8) error {
+	if err := d.HCI.AdvertiseIBeacon(u, major, minor, pwr); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	d.HCI.StopAdvertising()
+	return ctx.Err()
+}
+
+// Scan starts scanning. Duplicated advertisements will be filtered out if allowDup is set to false.
+func (d *Device) Scan(ctx context.Context, allowDup bool, h ble.AdvHandler) error {
+	if err := d.HCI.SetAdvHandler(h); err != nil {
+		return err
+	}
+	if err := d.HCI.Scan(allowDup); err != nil {
+		return err
+	}
+	<-ctx.Done()
+	d.HCI.StopScanning()
+	return ctx.Err()
+}
+
+// Dial ...
+func (d *Device) Dial(ctx context.Context, a ble.Addr) (ble.Client, error) {
+	// d.HCI.Dial is a blocking call, although most of time it should return immediately.
+	// But in case passing wrong device address or the device went non-connectable, it blocks.
+	cln, err := d.HCI.Dial(ctx, a)
+	return cln, errors.Wrap(err, "can't dial")
+}
+
+// Address returns the listener's device address.
+func (d *Device) Address() ble.Addr {
+	return d.HCI.Addr()
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/README.md b/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/README.md
new file mode 100644
index 0000000..b3a3fed
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/README.md
@@ -0,0 +1,47 @@
+## Generic Attribute Profile (GATT)
+
+This package implement Generic Attribute Profile (GATT) [Vol 3, Part G]
+
+### Check list for ATT Client implementation.
+
+#### Server Configuration [4.3]
+  - [x] Exchange MTU [4.3.1]
+
+#### Primary Service Discovery [4.4]
+  - [x] Discover All Primary Service [4.4.1]
+  - [ ] Discover Primary Service by Service UUID [4.4.2]
+
+#### Relationship Discovery [4.5]
+  - [ ] Find Included Services [4.5.1]
+
+#### Characteristic Discovery [4.6]
+  - [x] Discover All Characteristics of a Service [4.6.1]
+  - [ ] Discover Characteristics by UUID [4.6.2]
+
+#### Characteristic Descriptors Discovery [4.7]
+  - [x] Discover All Characteristic Descriptors [4.7.1]
+
+#### Characteristic Value Read [4.8]
+  - [ ] Read Characteristic Value [4.8.1]
+  - [ ] Read Using Characteristic UUID [4.8.2]
+  - [x] Read Long Characteristic Values [4.8.3]
+  - [ ] Read Multiple Characteristic Values [4.8.4]
+
+#### Characteristic Value Write [4.9]
+  - [x] Write Without Response [4.9.1]
+  - [ ] Signed Write Without Response [4.9.2]
+  - [x] Write Characteristic Value [4.9.3]
+  - [ ] Write Long Characteristic Values [4.9.4]
+  - [x] Reliable Writes [4.9.5]
+
+#### Characteristic Value Notifications [4.10]
+  - [x] Notifications [4.10.1]
+
+#### Characteristic Indications [4.11]
+  - [x] Indications [4.11.1]
+
+#### Characteristic Descriptors [4.12]
+  - [ ] Read Characteristic Descriptors [4.12.1]
+  - [ ] Read Long Characteristic Descriptors [4.12.2]
+  - [ ] Write Characteristic Descriptors [4.12.3]
+  - [ ] Write Long Characteristic Descriptors [4.12.4]
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/client.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/client.go
new file mode 100644
index 0000000..a5c4e15
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/client.go
@@ -0,0 +1,385 @@
+package gatt
+
+import (
+	"encoding/binary"
+	"fmt"
+	"log"
+	"sync"
+
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/linux/att"
+)
+
+const (
+	cccNotify   = 0x0001
+	cccIndicate = 0x0002
+)
+
+// NewClient returns a GATT Client.
+func NewClient(conn ble.Conn) (*Client, error) {
+	p := &Client{
+		subs: make(map[uint16]*sub),
+		conn: conn,
+	}
+	p.ac = att.NewClient(conn, p)
+	go p.ac.Loop()
+	return p, nil
+}
+
+// A Client is a GATT Client.
+type Client struct {
+	sync.RWMutex
+
+	profile *ble.Profile
+	name    string
+	subs    map[uint16]*sub
+
+	ac   *att.Client
+	conn ble.Conn
+}
+
+// Address returns the address of the client.
+func (p *Client) Address() ble.Addr {
+	p.RLock()
+	defer p.RUnlock()
+	return p.conn.RemoteAddr()
+}
+
+// Name returns the name of the client.
+func (p *Client) Name() string {
+	p.RLock()
+	defer p.RUnlock()
+	return p.name
+}
+
+// Profile returns the discovered profile.
+func (p *Client) Profile() *ble.Profile {
+	p.RLock()
+	defer p.RUnlock()
+	return p.profile
+}
+
+// DiscoverProfile discovers the whole hierachy of a server.
+func (p *Client) DiscoverProfile(force bool) (*ble.Profile, error) {
+	if p.profile != nil && !force {
+		return p.profile, nil
+	}
+	ss, err := p.DiscoverServices(nil)
+	if err != nil {
+		return nil, fmt.Errorf("can't discover services: %s\n", err)
+	}
+	for _, s := range ss {
+		cs, err := p.DiscoverCharacteristics(nil, s)
+		if err != nil {
+			return nil, fmt.Errorf("can't discover characteristics: %s\n", err)
+		}
+		for _, c := range cs {
+			_, err := p.DiscoverDescriptors(nil, c)
+			if err != nil {
+				return nil, fmt.Errorf("can't discover descriptors: %s\n", err)
+			}
+		}
+	}
+	p.profile = &ble.Profile{Services: ss}
+	return p.profile, nil
+}
+
+// DiscoverServices finds all the primary services on a server. [Vol 3, Part G, 4.4.1]
+// If filter is specified, only filtered services are returned.
+func (p *Client) DiscoverServices(filter []ble.UUID) ([]*ble.Service, error) {
+	p.Lock()
+	defer p.Unlock()
+	if p.profile == nil {
+		p.profile = &ble.Profile{}
+	}
+	start := uint16(0x0001)
+	for {
+		length, b, err := p.ac.ReadByGroupType(start, 0xFFFF, ble.PrimaryServiceUUID)
+		if err == ble.ErrAttrNotFound {
+			return p.profile.Services, nil
+		}
+		if err != nil {
+			return nil, err
+		}
+		for len(b) != 0 {
+			h := binary.LittleEndian.Uint16(b[:2])
+			endh := binary.LittleEndian.Uint16(b[2:4])
+			u := ble.UUID(b[4:length])
+			if filter == nil || ble.Contains(filter, u) {
+				s := &ble.Service{
+					UUID:      u,
+					Handle:    h,
+					EndHandle: endh,
+				}
+				p.profile.Services = append(p.profile.Services, s)
+			}
+			if endh == 0xFFFF {
+				return p.profile.Services, nil
+			}
+			start = endh + 1
+			b = b[length:]
+		}
+	}
+}
+
+// DiscoverIncludedServices finds the included services of a service. [Vol 3, Part G, 4.5.1]
+// If filter is specified, only filtered services are returned.
+func (p *Client) DiscoverIncludedServices(ss []ble.UUID, s *ble.Service) ([]*ble.Service, error) {
+	p.Lock()
+	defer p.Unlock()
+	return nil, nil
+}
+
+// DiscoverCharacteristics finds all the characteristics within a service. [Vol 3, Part G, 4.6.1]
+// If filter is specified, only filtered characteristics are returned.
+func (p *Client) DiscoverCharacteristics(filter []ble.UUID, s *ble.Service) ([]*ble.Characteristic, error) {
+	p.Lock()
+	defer p.Unlock()
+	start := s.Handle
+	var lastChar *ble.Characteristic
+	for start <= s.EndHandle {
+		length, b, err := p.ac.ReadByType(start, s.EndHandle, ble.CharacteristicUUID)
+		if err == ble.ErrAttrNotFound {
+			break
+		} else if err != nil {
+			return nil, err
+		}
+		for len(b) != 0 {
+			h := binary.LittleEndian.Uint16(b[:2])
+			p := ble.Property(b[2])
+			vh := binary.LittleEndian.Uint16(b[3:5])
+			u := ble.UUID(b[5:length])
+			c := &ble.Characteristic{
+				UUID:        u,
+				Property:    p,
+				Handle:      h,
+				ValueHandle: vh,
+				EndHandle:   s.EndHandle,
+			}
+			if filter == nil || ble.Contains(filter, u) {
+				s.Characteristics = append(s.Characteristics, c)
+			}
+			if lastChar != nil {
+				lastChar.EndHandle = c.Handle - 1
+			}
+			lastChar = c
+			start = vh + 1
+			b = b[length:]
+		}
+	}
+	return s.Characteristics, nil
+}
+
+// DiscoverDescriptors finds all the descriptors within a characteristic. [Vol 3, Part G, 4.7.1]
+// If filter is specified, only filtered descriptors are returned.
+func (p *Client) DiscoverDescriptors(filter []ble.UUID, c *ble.Characteristic) ([]*ble.Descriptor, error) {
+	p.Lock()
+	defer p.Unlock()
+	start := c.ValueHandle + 1
+	for start <= c.EndHandle {
+		fmt, b, err := p.ac.FindInformation(start, c.EndHandle)
+		if err == ble.ErrAttrNotFound {
+			break
+		} else if err != nil {
+			return nil, err
+		}
+		length := 2 + 2
+		if fmt == 0x02 {
+			length = 2 + 16
+		}
+		for len(b) != 0 {
+			h := binary.LittleEndian.Uint16(b[:2])
+			u := ble.UUID(b[2:length])
+			d := &ble.Descriptor{UUID: u, Handle: h}
+			if filter == nil || ble.Contains(filter, u) {
+				c.Descriptors = append(c.Descriptors, d)
+			}
+			if u.Equal(ble.ClientCharacteristicConfigUUID) {
+				c.CCCD = d
+			}
+			start = h + 1
+			b = b[length:]
+		}
+	}
+	return c.Descriptors, nil
+}
+
+// ReadCharacteristic reads a characteristic value from a server. [Vol 3, Part G, 4.8.1]
+func (p *Client) ReadCharacteristic(c *ble.Characteristic) ([]byte, error) {
+	p.Lock()
+	defer p.Unlock()
+	return p.ac.Read(c.ValueHandle)
+}
+
+// ReadLongCharacteristic reads a characteristic value which is longer than the MTU. [Vol 3, Part G, 4.8.3]
+func (p *Client) ReadLongCharacteristic(c *ble.Characteristic) ([]byte, error) {
+	p.Lock()
+	defer p.Unlock()
+
+	// The maximum length of an attribute value shall be 512 octects [Vol 3, 3.2.9]
+	buffer := make([]byte, 0, 512)
+
+	read, err := p.ac.Read(c.ValueHandle)
+	if err != nil {
+		return nil, err
+	}
+	buffer = append(buffer, read...)
+
+	for len(read) >= p.conn.TxMTU()-1 {
+		if read, err = p.ac.ReadBlob(c.ValueHandle, uint16(len(buffer))); err != nil {
+			return nil, err
+		}
+		buffer = append(buffer, read...)
+	}
+	return buffer, nil
+}
+
+// WriteCharacteristic writes a characteristic value to a server. [Vol 3, Part G, 4.9.3]
+func (p *Client) WriteCharacteristic(c *ble.Characteristic, v []byte, noRsp bool) error {
+	p.Lock()
+	defer p.Unlock()
+	if noRsp {
+		return p.ac.WriteCommand(c.ValueHandle, v)
+	}
+	return p.ac.Write(c.ValueHandle, v)
+}
+
+// ReadDescriptor reads a characteristic descriptor from a server. [Vol 3, Part G, 4.12.1]
+func (p *Client) ReadDescriptor(d *ble.Descriptor) ([]byte, error) {
+	p.Lock()
+	defer p.Unlock()
+	return p.ac.Read(d.Handle)
+}
+
+// WriteDescriptor writes a characteristic descriptor to a server. [Vol 3, Part G, 4.12.3]
+func (p *Client) WriteDescriptor(d *ble.Descriptor, v []byte) error {
+	p.Lock()
+	defer p.Unlock()
+	return p.ac.Write(d.Handle, v)
+}
+
+// ReadRSSI retrieves the current RSSI value of remote peripheral. [Vol 2, Part E, 7.5.4]
+func (p *Client) ReadRSSI() int {
+	p.Lock()
+	defer p.Unlock()
+	// TODO:
+	return 0
+}
+
+// ExchangeMTU informs the server of the client’s maximum receive MTU size and
+// request the server to respond with its maximum receive MTU size. [Vol 3, Part F, 3.4.2.1]
+func (p *Client) ExchangeMTU(mtu int) (int, error) {
+	p.Lock()
+	defer p.Unlock()
+	return p.ac.ExchangeMTU(mtu)
+}
+
+// Subscribe subscribes to indication (if ind is set true), or notification of a
+// characteristic value. [Vol 3, Part G, 4.10 & 4.11]
+func (p *Client) Subscribe(c *ble.Characteristic, ind bool, h ble.NotificationHandler) error {
+	p.Lock()
+	defer p.Unlock()
+	if c.CCCD == nil {
+		return fmt.Errorf("CCCD not found")
+	}
+	if ind {
+		return p.setHandlers(c.CCCD.Handle, c.ValueHandle, cccIndicate, h)
+	}
+	return p.setHandlers(c.CCCD.Handle, c.ValueHandle, cccNotify, h)
+}
+
+// Unsubscribe unsubscribes to indication (if ind is set true), or notification
+// of a specified characteristic value. [Vol 3, Part G, 4.10 & 4.11]
+func (p *Client) Unsubscribe(c *ble.Characteristic, ind bool) error {
+	p.Lock()
+	defer p.Unlock()
+	if c.CCCD == nil {
+		return fmt.Errorf("CCCD not found")
+	}
+	if ind {
+		return p.setHandlers(c.CCCD.Handle, c.ValueHandle, cccIndicate, nil)
+	}
+	return p.setHandlers(c.CCCD.Handle, c.ValueHandle, cccNotify, nil)
+}
+
+func (p *Client) setHandlers(cccdh, vh, flag uint16, h ble.NotificationHandler) error {
+	s, ok := p.subs[vh]
+	if !ok {
+		s = &sub{cccdh, 0x0000, nil, nil}
+		p.subs[vh] = s
+	}
+	switch {
+	case h == nil && (s.ccc&flag) == 0:
+		return nil
+	case h != nil && (s.ccc&flag) != 0:
+		return nil
+	case h == nil && (s.ccc&flag) != 0:
+		s.ccc &= ^uint16(flag)
+	case h != nil && (s.ccc&flag) == 0:
+		s.ccc |= flag
+	}
+
+	v := make([]byte, 2)
+	binary.LittleEndian.PutUint16(v, s.ccc)
+	if flag == cccNotify {
+		s.nHandler = h
+	} else {
+		s.iHandler = h
+	}
+	return p.ac.Write(s.cccdh, v)
+}
+
+// ClearSubscriptions clears all subscriptions to notifications and indications.
+func (p *Client) ClearSubscriptions() error {
+	p.Lock()
+	defer p.Unlock()
+	zero := make([]byte, 2)
+	for vh, s := range p.subs {
+		if err := p.ac.Write(s.cccdh, zero); err != nil {
+			return err
+		}
+		delete(p.subs, vh)
+	}
+	return nil
+}
+
+// CancelConnection disconnects the connection.
+func (p *Client) CancelConnection() error {
+	p.Lock()
+	defer p.Unlock()
+	return p.conn.Close()
+}
+
+// Disconnected returns a receiving channel, which is closed when the client disconnects.
+func (p *Client) Disconnected() <-chan struct{} {
+	p.Lock()
+	defer p.Unlock()
+	return p.conn.Disconnected()
+}
+
+// HandleNotification ...
+func (p *Client) HandleNotification(req []byte) {
+	p.Lock()
+	defer p.Unlock()
+	vh := att.HandleValueIndication(req).AttributeHandle()
+	sub, ok := p.subs[vh]
+	if !ok {
+		// FIXME: disconnects and propagate an error to the user.
+		log.Printf("Got an unregistered notification")
+		return
+	}
+	fn := sub.nHandler
+	if req[0] == att.HandleValueIndicationCode {
+		fn = sub.iHandler
+	}
+	if fn != nil {
+		fn(req[3:])
+	}
+}
+
+type sub struct {
+	cccdh    uint16
+	ccc      uint16
+	nHandler ble.NotificationHandler
+	iHandler ble.NotificationHandler
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/server.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/server.go
new file mode 100644
index 0000000..1d90825
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/gatt/server.go
@@ -0,0 +1,83 @@
+package gatt
+
+import (
+	"log"
+	"sync"
+
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/linux/att"
+)
+
+// NewServer ...
+func NewServer() (*Server, error) {
+	return &Server{
+		svcs: defaultServices("Gopher"),
+		db:   att.NewDB(defaultServices("Gopher"), uint16(1)),
+	}, nil
+}
+
+// Server ...
+type Server struct {
+	sync.Mutex
+
+	svcs []*ble.Service
+	db   *att.DB
+}
+
+// AddService ...
+func (s *Server) AddService(svc *ble.Service) error {
+	s.Lock()
+	defer s.Unlock()
+	s.svcs = append(s.svcs, svc)
+	s.db = att.NewDB(s.svcs, uint16(1)) // ble attrs start at 1
+	return nil
+}
+
+// RemoveAllServices ...
+func (s *Server) RemoveAllServices() error {
+	s.Lock()
+	defer s.Unlock()
+	s.svcs = defaultServices("Gopher")
+	s.db = att.NewDB(s.svcs, uint16(1)) // ble attrs start at 1
+	return nil
+}
+
+// SetServices ...
+func (s *Server) SetServices(svcs []*ble.Service) error {
+	s.Lock()
+	defer s.Unlock()
+	s.svcs = append(defaultServices("Gopher"), svcs...)
+	s.db = att.NewDB(s.svcs, uint16(1)) // ble attrs start at 1
+	return nil
+}
+
+// DB ...
+func (s *Server) DB() *att.DB {
+	return s.db
+}
+
+func defaultServices(name string) []*ble.Service {
+	// https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.ble.appearance.xml
+	var gapCharAppearanceGenericComputer = []byte{0x00, 0x80}
+
+	gapSvc := ble.NewService(ble.GAPUUID)
+	gapSvc.NewCharacteristic(ble.DeviceNameUUID).SetValue([]byte(name))
+	gapSvc.NewCharacteristic(ble.AppearanceUUID).SetValue(gapCharAppearanceGenericComputer)
+	gapSvc.NewCharacteristic(ble.PeripheralPrivacyUUID).SetValue([]byte{0x00})
+	gapSvc.NewCharacteristic(ble.ReconnectionAddrUUID).SetValue([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
+	gapSvc.NewCharacteristic(ble.PeferredParamsUUID).SetValue([]byte{0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd0, 0x07})
+
+	gattSvc := ble.NewService(ble.GATTUUID)
+	gattSvc.NewCharacteristic(ble.ServiceChangedUUID).HandleIndicate(
+		ble.NotifyHandlerFunc(func(r ble.Request, n ble.Notifier) {
+			log.Printf("TODO: indicate client when the services are changed")
+			for {
+				select {
+				case <-n.Context().Done():
+					log.Printf("count: Notification unsubscribed")
+					return
+				}
+			}
+		}))
+	return []*ble.Service{gapSvc, gattSvc}
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/README.md b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/README.md
new file mode 100644
index 0000000..48eecdb
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/README.md
@@ -0,0 +1,116 @@
+## LE Command Requirements
+
+List of the commands and events that a Controller supporting LE shall implement.  [Vol 2 Part A.3.19]
+
+- Mandatory
+
+  - [ ] Vol 2, Part E, 7.7.14 - Command Complete Event (0x0E)
+  - [ ] Vol 2, Part E, 7.7.15 - Command Status Event (0x0F)
+  - [ ] Vol 2, Part E, 7.8.16 - LE Add Device To White List Command (0x08|0x0011)
+  - [ ] Vol 2, Part E, 7.8.15 - LE Clear White List Command (0x08|0x0010)
+  - [ ] Vol 2, Part E, 7.8.2 - LE Read Buffer Size Command (0x08|0x0002)
+  - [ ] Vol 2, Part E, 7.4.3 - Read Local Supported Features Command (0x04|0x0003)
+  - [ ] Vol 2, Part E, 7.8.27 - LE Read Supported States Command (0x08|0x001C)
+  - [ ] Vol 2, Part E, 7.8.14 - LE Read White List Size Command (0x08|0x000F)
+  - [ ] Vol 2, Part E, 7.8.17 - LE Remove Device From White List Command (0x08|0x0012)
+  - [ ] Vol 2, Part E, 7.8.1 - LE Set Event Mask Command (0x08|0x0001)
+  - [ ] Vol 2, Part E, 7.8.30 - LE Test End Command (0x08|0x001F)
+  - [ ] Vol 2, Part E, 7.4.6 - Read BD_ADDR Command (0x04|0x0009)
+  - [ ] Vol 2, Part E, 7.8.3 - LE Read Local Supported Features Command (0x08|0x0003)
+  - [ ] Vol 2, Part E, 7.4.1 - Read Local Version Information Command (0x04|0x0001)
+  - [ ] Vol 2, Part E, 7.3.2 - Reset Command (0x03|0x003)
+  - [ ] Vol 2, Part E, 7.4.2 - Read Local Supported Commands Command (0x04|0x0002)
+  - [ ] Vol 2, Part E, 7.3.1 - Set Event Mask Command (0x03|0x0001)
+
+
+- C1: Mandatory if Controller supports transmitting packets, otherwise optional.
+
+  - [ ] Vol 2, Part E, 7.8.6 - LE Read Advertising Channel Tx Power Command (0x08|0x0007)
+  - [ ] Vol 2, Part E, 7.8.29 - LE Transmitter Test Command (0x08|0x001E)
+  - [ ] Vol 2, Part E, 7.8.9 - LE Set Advertise Enable Command (0x08|0x000A)
+  - [ ] Vol 2, Part E, 7.8.7 - LE Set Advertising Data Command (0x08|0x0008)
+  - [ ] Vol 2, Part E, 7.8.5 - LE Set Advertising Parameters Command (0x08|0x0006)
+  - [ ] Vol 2, Part E, 7.8.4 - LE Set Random Address Command (0x08|0x0005)
+
+
+- C2: Mandatory if Controller supports receiving packets, otherwise optional.
+
+  - [ ] Vol 2, Part E, 7.7.65.2 - LE Advertising Report Event (0x3E)
+  - [ ] Vol 2, Part E, 7.8.28 - LE Receiver Test Command (0x08|0x001D)
+  - [ ] Vol 2, Part E, 7.8.11 - LE Set Scan Enable Command (0x08|0x000C)
+  - [ ] Vol 2, Part E, 7.8.10 - LE Set Scan Parameters Command (0x08|0x000B)
+
+
+- C3: Mandatory if Controller supports transmitting and receiving packets, otherwise optional.
+
+  - [ ] Vol 2, Part E, 7.1.6 - Disconnect Command (0x01|0x0006)
+  - [ ] Vol 2, Part E, 7.7.5 - Disconnection Complete Event (0x05)
+  - [ ] Vol 2, Part E, 7.7.65.1 - LE Connection Complete Event (0x3E)
+  - [ ] Vol 2, Part E, 7.8.18 - LE Connection Update Command (0x08|0x0013)
+  - [ ] Vol 2, Part E, 7.7.65.3 - LE Connection Update Complete Event (0x0E)
+  - [ ] Vol 2, Part E, 7.8.12 - LE Create Connection Command (0x08|0x000D)
+  - [ ] Vol 2, Part E, 7.8.13 - LE Create Connection Cancel Command (0x08|0x000E)
+  - [ ] Vol 2, Part E, 7.8.20 - LE Read Channel Map Command (0x08|0x0015)
+  - [ ] Vol 2, Part E, 7.8.21 - LE Read Remote Used Features Command (0x08|0x0016)
+  - [ ] Vol 2, Part E, 7.7.65.4 - LE Read Remote Used Features Complete Event (0x3E)
+  - [ ] Vol 2, Part E, 7.8.19 - LE Set Host Channel Classification Command (0x08|0x0014)
+  - [ ] Vol 2, Part E, 7.8.8 - LE Set Scan Response Data Command (0x08|0x0009)
+  - [ ] Vol 2, Part E, 7.3.40 - Host Number Of Completed Packets Command (0x03|0x0035)
+  - [ ] Vol 2, Part E, 7.3.35 - Read Transmit Power Level Command (0x03|0x002D)
+  - [ ] Vol 2, Part E, 7.1.23 - Read Remote Version Information Command (0x01|0x001D)
+  - [ ] Vol 2, Part E, 7.7.12 - Read Remote Version Information Complete Event (0x0C)
+  - [ ] Vol 2, Part E, 7.5.4 - Read RSSI Command (0x05|0x0005)
+
+
+- C4: Mandatory if LE Feature (LL Encryption) is supported otherwise optional.
+
+  - [ ] Vol 2, Part E, 7.7.8 - Encryption Change Event (0x08)
+  - [ ] Vol 2, Part E, 7.7.39 - Encryption Key Refresh Complete Event (0x30)
+  - [ ] Vol 2, Part E, 7.8.22 - LE Encrypt Command (0x08|0x0017)
+  - [ ] Vol 2, Part E, 7.7.65.5 - LE Long Term Key Request Event (0x3E)
+  - [ ] Vol 2, Part E, 7.8.25 - LE Long Term Key Request Reply Command (0x08|0x001A)
+  - [ ] Vol 2, Part E, 7.8.26 - LE Long Term Key Request Negative Reply Command (0x08|0x001B)
+  - [ ] Vol 2, Part E, 7.8.23 - LE Rand Command (0x08|0x0018)
+  - [ ] Vol 2, Part E, 7.8.24 - LE Start Encryption Command (0x08|0x0019)
+
+
+- C5: Mandatory if BR/EDR is supported otherwise optional. [Won't supported]
+
+  - [ ] Vol 2, Part E, 7.4.5 - Read Buffer Size Command
+  - [ ] Vol 2, Part E, 7.3.78 - Read LE Host Support
+  - [ ] Vol 2, Part E, 7.3.79 - Write LE Host Support Command (0x03|0x006D)
+
+
+- C6: Mandatory if LE Feature (Connection Parameters Request procedure) is supported, otherwise optional.
+
+  - [ ] Vol 2, Part E, 7.8.31 - LE Remote Connection Parameter Request Reply Command (0x08|0x0020)
+  - [ ] Vol 2, Part E, 7.8.32 - LE Remote Connection Parameter Request Negative Reply Command (0x08|0x0021)
+  - [ ] Vol 2, Part E, 7.7.65.6 - LE Remote Connection Parameter Request Event (0x3E)
+
+
+- C7: Mandatory if LE Ping is supported otherwise excluded
+
+  - [ ] Vol 2, Part E, 7.3.94 - Write Authenticated Payload Timeout Command (0x01|0x007C)
+  - [ ] Vol 2, Part E, 7.3.93 - Read Authenticated Payload Timeout Command (0x03|0x007B)
+  - [ ] Vol 2, Part E, 7.7.75 - Authenticated Payload Timeout Expired Event (0x57)
+  - [ ] Vol 2, Part E, 7.3.69 - Set Event Mask Page 2 Command (0x03|0x0063)
+
+
+- Optional support
+
+  - [ ] Vol 2, Part E, 7.7.26 - Data Buffer Overflow Event (0x1A)
+  - [ ] Vol 2, Part E, 7.7.16 - Hardware Error Event (0x10)
+  - [ ] Vol 2, Part E, 7.3.39 - Host Buffer Size Command (0x03|0x0033)
+  - [ ] Vol 2, Part E, 7.7.19 - Number Of Completed Packets Event (0x13)
+  - [ ] Vol 2, Part E, 7.3.38 - Set Controller To Host Flow Control Command
+
+  ##  Vol 3, Part A, 4 L2CAP Signaling mandatory for LE-U
+
+  - [ ] Vol 3, Part A, 4.1 - Command Reject (0x01)
+  - [ ] Vol 3, Part A, 4.6 - Disconnect Request (0x06)
+  - [ ] Vol 3, Part A, 4.7 - Disconnect Response (0x07)
+  - [ ] Vol 3, Part A, 4.20 - Connection Parameter Update Request (0x12)
+  - [ ] Vol 3, Part A, 4.21 - Connection Parameter Update Response (0x13)
+  - [ ] Vol 3, Part A, 4.22 - LE Credit Based Connection Request (0x14)
+  - [ ] Vol 3, Part A, 4.23 - LE Credit Based Connection Response (0x15)
+  - [ ] Vol 3, Part A, 4.24 - LE Flow Control Credit (0x16)
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/adv.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/adv.go
new file mode 100644
index 0000000..eb0f7f7
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/adv.go
@@ -0,0 +1,135 @@
+package hci
+
+import (
+	"net"
+
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/linux/adv"
+	"github.com/currantlabs/ble/linux/hci/evt"
+)
+
+// RandomAddress is a Random Device Address.
+type RandomAddress struct {
+	ble.Addr
+}
+
+// [Vol 6, Part B, 4.4.2] [Vol 3, Part C, 11]
+const (
+	evtTypAdvInd        = 0x00 // Connectable undirected advertising (ADV_IND).
+	evtTypAdvDirectInd  = 0x01 // Connectable directed advertising (ADV_DIRECT_IND).
+	evtTypAdvScanInd    = 0x02 // Scannable undirected advertising (ADV_SCAN_IND).
+	evtTypAdvNonconnInd = 0x03 // Non connectable undirected advertising (ADV_NONCONN_IND).
+	evtTypScanRsp       = 0x04 // Scan Response (SCAN_RSP).
+)
+
+func newAdvertisement(e evt.LEAdvertisingReport, i int) *Advertisement {
+	return &Advertisement{e: e, i: i}
+}
+
+// Advertisement implements ble.Advertisement and other functions that are only
+// available on Linux.
+type Advertisement struct {
+	e  evt.LEAdvertisingReport
+	i  int
+	sr *Advertisement
+
+	// cached packets.
+	p *adv.Packet
+}
+
+// setScanResponse ssociate sca response to the existing advertisement.
+func (a *Advertisement) setScanResponse(sr *Advertisement) {
+	a.sr = sr
+	a.p = nil // clear the cached.
+}
+
+// packets returns the combined advertising packet and scan response (if presents)
+func (a *Advertisement) packets() *adv.Packet {
+	if a.p != nil {
+		return a.p
+	}
+	return adv.NewRawPacket(a.Data(), a.ScanResponse())
+}
+
+// LocalName returns the LocalName of the remote peripheral.
+func (a *Advertisement) LocalName() string {
+	return a.packets().LocalName()
+}
+
+// ManufacturerData returns the ManufacturerData of the advertisement.
+func (a *Advertisement) ManufacturerData() []byte {
+	return a.packets().ManufacturerData()
+}
+
+// ServiceData returns the service data of the advertisement.
+func (a *Advertisement) ServiceData() []ble.ServiceData {
+	return a.packets().ServiceData()
+}
+
+// Services returns the service UUIDs of the advertisement.
+func (a *Advertisement) Services() []ble.UUID {
+	return a.packets().UUIDs()
+}
+
+// OverflowService returns the UUIDs of overflowed service.
+func (a *Advertisement) OverflowService() []ble.UUID {
+	return a.packets().UUIDs()
+}
+
+// TxPowerLevel returns the tx power level of the remote peripheral.
+func (a *Advertisement) TxPowerLevel() int {
+	pwr, _ := a.packets().TxPower()
+	return pwr
+}
+
+// SolicitedService returns UUIDs of solicited services.
+func (a *Advertisement) SolicitedService() []ble.UUID {
+	return a.packets().ServiceSol()
+}
+
+// Connectable indicates weather the remote peripheral is connectable.
+func (a *Advertisement) Connectable() bool {
+	return a.EventType() == evtTypAdvDirectInd || a.EventType() == evtTypAdvInd
+}
+
+// RSSI returns RSSI signal strength.
+func (a *Advertisement) RSSI() int {
+	return int(a.e.RSSI(a.i))
+}
+
+// Address returns the address of the remote peripheral.
+func (a *Advertisement) Address() ble.Addr {
+	b := a.e.Address(a.i)
+	addr := net.HardwareAddr([]byte{b[5], b[4], b[3], b[2], b[1], b[0]})
+	if a.e.AddressType(a.i) == 1 {
+		return RandomAddress{addr}
+	}
+	return addr
+}
+
+// EventType returns the event type of Advertisement.
+// This is linux sepcific.
+func (a *Advertisement) EventType() uint8 {
+	return a.e.EventType(a.i)
+}
+
+// AddressType returns the address type of the Advertisement.
+// This is linux sepcific.
+func (a *Advertisement) AddressType() uint8 {
+	return a.e.AddressType(a.i)
+}
+
+// Data returns the advertising data of the packet.
+// This is linux sepcific.
+func (a *Advertisement) Data() []byte {
+	return a.e.Data(a.i)
+}
+
+// ScanResponse returns the scan response of the packet, if it presents.
+// This is linux sepcific.
+func (a *Advertisement) ScanResponse() []byte {
+	if a.sr == nil {
+		return nil
+	}
+	return a.sr.Data()
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/buffer.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/buffer.go
new file mode 100644
index 0000000..93162a7
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/buffer.go
@@ -0,0 +1,74 @@
+package hci
+
+import (
+	"bytes"
+	"sync"
+)
+
+// Pool ...
+type Pool struct {
+	sync.Mutex
+
+	sz  int
+	cnt int
+	ch  chan *bytes.Buffer
+}
+
+// NewPool ...
+func NewPool(sz int, cnt int) *Pool {
+	ch := make(chan *bytes.Buffer, cnt)
+	for len(ch) < cnt {
+		ch <- bytes.NewBuffer(make([]byte, sz))
+	}
+	return &Pool{sz: sz, cnt: cnt, ch: ch}
+}
+
+// Client ...
+type Client struct {
+	p    *Pool
+	sent chan *bytes.Buffer
+}
+
+// NewClient ...
+func NewClient(p *Pool) *Client {
+	return &Client{p: p, sent: make(chan *bytes.Buffer, p.cnt)}
+}
+
+// LockPool ...
+func (c *Client) LockPool() {
+	c.p.Lock()
+}
+
+// UnlockPool ...
+func (c *Client) UnlockPool() {
+	c.p.Unlock()
+}
+
+// Get returns a buffer from the shared buffer pool.
+func (c *Client) Get() *bytes.Buffer {
+	b := <-c.p.ch
+	b.Reset()
+	c.sent <- b
+	return b
+}
+
+// Put puts the oldest sent buffer back to the shared pool.
+func (c *Client) Put() {
+	select {
+	case b := <-c.sent:
+		c.p.ch <- b
+	default:
+	}
+}
+
+// PutAll puts all the sent buffers back to the shared pool.
+func (c *Client) PutAll() {
+	for {
+		select {
+		case b := <-c.sent:
+			c.p.ch <- b
+		default:
+			return
+		}
+	}
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/cmd/cmd.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/cmd/cmd.go
new file mode 100644
index 0000000..7c5c639
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/cmd/cmd.go
@@ -0,0 +1,31 @@
+package cmd
+
+import (
+	"bytes"
+	"encoding/binary"
+	"io"
+)
+
+type command interface {
+	OpCode() int
+	Len() int
+	Marshal([]byte) error
+}
+
+type commandRP interface {
+	Unmarshal(b []byte) error
+}
+
+func marshal(c command, b []byte) error {
+	buf := bytes.NewBuffer(b)
+	buf.Reset()
+	if buf.Cap() < c.Len() {
+		return io.ErrShortBuffer
+	}
+	return binary.Write(buf, binary.LittleEndian, c)
+}
+
+func unmarshal(c commandRP, b []byte) error {
+	buf := bytes.NewBuffer(b)
+	return binary.Read(buf, binary.LittleEndian, c)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/cmd/cmd_gen.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/cmd/cmd_gen.go
new file mode 100644
index 0000000..8b10a15
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/cmd/cmd_gen.go
@@ -0,0 +1,1562 @@
+package cmd
+
+// Disconnect implements Disconnect (0x01|0x0006) [Vol 2, Part E, 7.1.6]
+type Disconnect struct {
+	ConnectionHandle uint16
+	Reason           uint8
+}
+
+func (c *Disconnect) String() string {
+	return "Disconnect (0x01|0x0006)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *Disconnect) OpCode() int { return 0x01<<10 | 0x0006 }
+
+// Len returns the length of the command.
+func (c *Disconnect) Len() int { return 3 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *Disconnect) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadRemoteVersionInformation implements Read Remote Version Information (0x01|0x001D) [Vol 2, Part E, 7.1.23]
+type ReadRemoteVersionInformation struct {
+	ConnectionHandle uint16
+}
+
+func (c *ReadRemoteVersionInformation) String() string {
+	return "Read Remote Version Information (0x01|0x001D)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadRemoteVersionInformation) OpCode() int { return 0x01<<10 | 0x001D }
+
+// Len returns the length of the command.
+func (c *ReadRemoteVersionInformation) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadRemoteVersionInformation) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// WriteDefaultLinkPolicySettings implements Write Default Link Policy Settings (0x02|0x000D) [Vol 2, Part E, 7.2.12]
+type WriteDefaultLinkPolicySettings struct {
+	DefaultLinkPolicySettings uint16
+}
+
+func (c *WriteDefaultLinkPolicySettings) String() string {
+	return "Write Default Link Policy Settings (0x02|0x000D)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *WriteDefaultLinkPolicySettings) OpCode() int { return 0x02<<10 | 0x000D }
+
+// Len returns the length of the command.
+func (c *WriteDefaultLinkPolicySettings) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *WriteDefaultLinkPolicySettings) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// WriteDefaultLinkPolicySettingsRP returns the return parameter of Write Default Link Policy Settings
+type WriteDefaultLinkPolicySettingsRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *WriteDefaultLinkPolicySettingsRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// SetEventMask implements Set Event Mask (0x03|0x0001) [Vol 2, Part E, 7.3.1]
+type SetEventMask struct {
+	EventMask uint64
+}
+
+func (c *SetEventMask) String() string {
+	return "Set Event Mask (0x03|0x0001)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *SetEventMask) OpCode() int { return 0x03<<10 | 0x0001 }
+
+// Len returns the length of the command.
+func (c *SetEventMask) Len() int { return 8 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *SetEventMask) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// SetEventMaskRP returns the return parameter of Set Event Mask
+type SetEventMaskRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *SetEventMaskRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// Reset implements Reset (0x03|0x003) [Vol 2, Part E, 7.3.2]
+type Reset struct {
+}
+
+func (c *Reset) String() string {
+	return "Reset (0x03|0x003)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *Reset) OpCode() int { return 0x03<<10 | 0x003 }
+
+// Len returns the length of the command.
+func (c *Reset) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *Reset) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ResetRP returns the return parameter of Reset
+type ResetRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ResetRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// WritePageTimeout implements Write Page Timeout (0x03|0x0018) [Vol 2, Part E, 7.3.16]
+type WritePageTimeout struct {
+	PageTimeout uint16
+}
+
+func (c *WritePageTimeout) String() string {
+	return "Write Page Timeout (0x03|0x0018)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *WritePageTimeout) OpCode() int { return 0x03<<10 | 0x0018 }
+
+// Len returns the length of the command.
+func (c *WritePageTimeout) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *WritePageTimeout) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// WritePageTimeoutRP returns the return parameter of Write Page Timeout
+type WritePageTimeoutRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *WritePageTimeoutRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// WriteClassOfDevice implements Write Class Of Device (0x03|0x0024) [Vol 2, Part E, 7.3.26]
+type WriteClassOfDevice struct {
+	ClassOfDevice [3]byte
+}
+
+func (c *WriteClassOfDevice) String() string {
+	return "Write Class Of Device (0x03|0x0024)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *WriteClassOfDevice) OpCode() int { return 0x03<<10 | 0x0024 }
+
+// Len returns the length of the command.
+func (c *WriteClassOfDevice) Len() int { return 3 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *WriteClassOfDevice) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// WriteClassOfDeviceRP returns the return parameter of Write Class Of Device
+type WriteClassOfDeviceRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *WriteClassOfDeviceRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// ReadTransmitPowerLevel implements Read Transmit Power Level (0x03|0x002D) [Vol 2, Part E, 7.3.35]
+type ReadTransmitPowerLevel struct {
+	ConnectionHandle uint16
+	Type             uint8
+}
+
+func (c *ReadTransmitPowerLevel) String() string {
+	return "Read Transmit Power Level (0x03|0x002D)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadTransmitPowerLevel) OpCode() int { return 0x03<<10 | 0x002D }
+
+// Len returns the length of the command.
+func (c *ReadTransmitPowerLevel) Len() int { return 3 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadTransmitPowerLevel) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadTransmitPowerLevelRP returns the return parameter of Read Transmit Power Level
+type ReadTransmitPowerLevelRP struct {
+	Status           uint8
+	ConnectionHandle uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ReadTransmitPowerLevelRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// HostBufferSize implements Host Buffer Size (0x03|0x0033) [Vol 2, Part E, 7.3.39]
+type HostBufferSize struct {
+	HostACLDataPacketLength            uint16
+	HostSynchronousDataPacketLength    uint8
+	HostTotalNumACLDataPackets         uint16
+	HostTotalNumSynchronousDataPackets uint16
+}
+
+func (c *HostBufferSize) String() string {
+	return "Host Buffer Size (0x03|0x0033)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *HostBufferSize) OpCode() int { return 0x03<<10 | 0x0033 }
+
+// Len returns the length of the command.
+func (c *HostBufferSize) Len() int { return 7 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *HostBufferSize) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// HostBufferSizeRP returns the return parameter of Host Buffer Size
+type HostBufferSizeRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *HostBufferSizeRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// HostNumberOfCompletedPackets implements Host Number Of Completed Packets (0x03|0x0035) [Vol 2, Part E, 7.3.40]
+type HostNumberOfCompletedPackets struct {
+	NumberOfHandles           uint8
+	ConnectionHandle          []uint16
+	HostNumOfCompletedPackets []uint16
+}
+
+func (c *HostNumberOfCompletedPackets) String() string {
+	return "Host Number Of Completed Packets (0x03|0x0035)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *HostNumberOfCompletedPackets) OpCode() int { return 0x03<<10 | 0x0035 }
+
+// Len returns the length of the command.
+func (c *HostNumberOfCompletedPackets) Len() int { return -1 }
+
+// SetEventMaskPage2 implements Set Event Mask Page 2 (0x03|0x0063) [Vol 2, Part E, 7.3.69]
+type SetEventMaskPage2 struct {
+	EventMaskPage2 uint64
+}
+
+func (c *SetEventMaskPage2) String() string {
+	return "Set Event Mask Page 2 (0x03|0x0063)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *SetEventMaskPage2) OpCode() int { return 0x03<<10 | 0x0063 }
+
+// Len returns the length of the command.
+func (c *SetEventMaskPage2) Len() int { return 8 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *SetEventMaskPage2) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// SetEventMaskPage2RP returns the return parameter of Set Event Mask Page 2
+type SetEventMaskPage2RP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *SetEventMaskPage2RP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// WriteLEHostSupport implements Write LE Host Support (0x03|0x006D) [Vol 2, Part E, 7.3.79]
+type WriteLEHostSupport struct {
+	LESupportedHost    uint8
+	SimultaneousLEHost uint8
+}
+
+func (c *WriteLEHostSupport) String() string {
+	return "Write LE Host Support (0x03|0x006D)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *WriteLEHostSupport) OpCode() int { return 0x03<<10 | 0x006D }
+
+// Len returns the length of the command.
+func (c *WriteLEHostSupport) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *WriteLEHostSupport) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// WriteLEHostSupportRP returns the return parameter of Write LE Host Support
+type WriteLEHostSupportRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *WriteLEHostSupportRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// ReadAuthenticatedPayloadTimeout implements Read Authenticated Payload Timeout (0x03|0x007B) [Vol 2, Part E, 7.3.93]
+type ReadAuthenticatedPayloadTimeout struct {
+	ConnectionHandle uint16
+}
+
+func (c *ReadAuthenticatedPayloadTimeout) String() string {
+	return "Read Authenticated Payload Timeout (0x03|0x007B)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadAuthenticatedPayloadTimeout) OpCode() int { return 0x03<<10 | 0x007B }
+
+// Len returns the length of the command.
+func (c *ReadAuthenticatedPayloadTimeout) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadAuthenticatedPayloadTimeout) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadAuthenticatedPayloadTimeoutRP returns the return parameter of Read Authenticated Payload Timeout
+type ReadAuthenticatedPayloadTimeoutRP struct {
+	Status                      uint8
+	ConnectionHandle            uint16
+	AuthenticatedPayloadTimeout uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ReadAuthenticatedPayloadTimeoutRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// WriteAuthenticatedPayloadTimeout implements Write Authenticated Payload Timeout (0x01|0x007C) [Vol 2, Part E, 7.3.94]
+type WriteAuthenticatedPayloadTimeout struct {
+	ConnectionHandle            uint16
+	AuthenticatedPayloadTimeout uint16
+}
+
+func (c *WriteAuthenticatedPayloadTimeout) String() string {
+	return "Write Authenticated Payload Timeout (0x01|0x007C)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *WriteAuthenticatedPayloadTimeout) OpCode() int { return 0x01<<10 | 0x007C }
+
+// Len returns the length of the command.
+func (c *WriteAuthenticatedPayloadTimeout) Len() int { return 4 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *WriteAuthenticatedPayloadTimeout) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// WriteAuthenticatedPayloadTimeoutRP returns the return parameter of Write Authenticated Payload Timeout
+type WriteAuthenticatedPayloadTimeoutRP struct {
+	Status           uint8
+	ConnectionHandle uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *WriteAuthenticatedPayloadTimeoutRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// ReadLocalVersionInformation implements Read Local Version Information (0x04|0x0001) [Vol 2, Part E, 7.4.1]
+type ReadLocalVersionInformation struct {
+}
+
+func (c *ReadLocalVersionInformation) String() string {
+	return "Read Local Version Information (0x04|0x0001)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadLocalVersionInformation) OpCode() int { return 0x04<<10 | 0x0001 }
+
+// Len returns the length of the command.
+func (c *ReadLocalVersionInformation) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadLocalVersionInformation) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadLocalVersionInformationRP returns the return parameter of Read Local Version Information
+type ReadLocalVersionInformationRP struct {
+	Status           uint8
+	HCIVersion       uint8
+	HCIRevision      uint16
+	LMPPAMVersion    uint8
+	ManufacturerName uint16
+	LMPPAMSubversion uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ReadLocalVersionInformationRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// ReadLocalSupportedCommands implements Read Local Supported Commands (0x04|0x0002) [Vol 2, Part E, 7.4.2]
+type ReadLocalSupportedCommands struct {
+}
+
+func (c *ReadLocalSupportedCommands) String() string {
+	return "Read Local Supported Commands (0x04|0x0002)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadLocalSupportedCommands) OpCode() int { return 0x04<<10 | 0x0002 }
+
+// Len returns the length of the command.
+func (c *ReadLocalSupportedCommands) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadLocalSupportedCommands) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadLocalSupportedCommandsRP returns the return parameter of Read Local Supported Commands
+type ReadLocalSupportedCommandsRP struct {
+	Status     uint8
+	Supporteds uint64
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ReadLocalSupportedCommandsRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// ReadLocalSupportedFeatures implements Read Local Supported Features (0x04|0x0003) [Vol 2, Part E, 7.4.3]
+type ReadLocalSupportedFeatures struct {
+}
+
+func (c *ReadLocalSupportedFeatures) String() string {
+	return "Read Local Supported Features (0x04|0x0003)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadLocalSupportedFeatures) OpCode() int { return 0x04<<10 | 0x0003 }
+
+// Len returns the length of the command.
+func (c *ReadLocalSupportedFeatures) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadLocalSupportedFeatures) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadLocalSupportedFeaturesRP returns the return parameter of Read Local Supported Features
+type ReadLocalSupportedFeaturesRP struct {
+	Status      uint8
+	LMPFeatures uint64
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ReadLocalSupportedFeaturesRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// ReadBufferSize implements Read Buffer Size (0x04|0x0005) [Vol 2, Part E, 7.4.5]
+type ReadBufferSize struct {
+}
+
+func (c *ReadBufferSize) String() string {
+	return "Read Buffer Size (0x04|0x0005)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadBufferSize) OpCode() int { return 0x04<<10 | 0x0005 }
+
+// Len returns the length of the command.
+func (c *ReadBufferSize) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadBufferSize) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadBufferSizeRP returns the return parameter of Read Buffer Size
+type ReadBufferSizeRP struct {
+	Status                           uint8
+	HCACLDataPacketLength            uint16
+	HCSynchronousDataPacketLength    uint8
+	HCTotalNumACLDataPackets         uint16
+	HCTotalNumSynchronousDataPackets uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ReadBufferSizeRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// ReadBDADDR implements Read BD_ADDR (0x04|0x0009) [Vol 2, Part E, 7.4.6]
+type ReadBDADDR struct {
+}
+
+func (c *ReadBDADDR) String() string {
+	return "Read BD_ADDR (0x04|0x0009)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadBDADDR) OpCode() int { return 0x04<<10 | 0x0009 }
+
+// Len returns the length of the command.
+func (c *ReadBDADDR) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadBDADDR) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadBDADDRRP returns the return parameter of Read BD_ADDR
+type ReadBDADDRRP struct {
+	Status uint8
+	BDADDR [6]byte
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ReadBDADDRRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// ReadRSSI implements Read RSSI (0x05|0x0005) [Vol 2, Part E, 7.5.4]
+type ReadRSSI struct {
+	Handle uint16
+}
+
+func (c *ReadRSSI) String() string {
+	return "Read RSSI (0x05|0x0005)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *ReadRSSI) OpCode() int { return 0x05<<10 | 0x0005 }
+
+// Len returns the length of the command.
+func (c *ReadRSSI) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *ReadRSSI) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// ReadRSSIRP returns the return parameter of Read RSSI
+type ReadRSSIRP struct {
+	Status           uint8
+	ConnectionHandle uint16
+	RSSI             int8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *ReadRSSIRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LESetEventMask implements LE Set Event Mask (0x08|0x0001) [Vol 2, Part E, 7.8.1]
+type LESetEventMask struct {
+	LEEventMask uint64
+}
+
+func (c *LESetEventMask) String() string {
+	return "LE Set Event Mask (0x08|0x0001)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetEventMask) OpCode() int { return 0x08<<10 | 0x0001 }
+
+// Len returns the length of the command.
+func (c *LESetEventMask) Len() int { return 8 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetEventMask) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetEventMaskRP returns the return parameter of LE Set Event Mask
+type LESetEventMaskRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetEventMaskRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEReadBufferSize implements LE Read Buffer Size (0x08|0x0002) [Vol 2, Part E, 7.8.2]
+type LEReadBufferSize struct {
+}
+
+func (c *LEReadBufferSize) String() string {
+	return "LE Read Buffer Size (0x08|0x0002)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEReadBufferSize) OpCode() int { return 0x08<<10 | 0x0002 }
+
+// Len returns the length of the command.
+func (c *LEReadBufferSize) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEReadBufferSize) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEReadBufferSizeRP returns the return parameter of LE Read Buffer Size
+type LEReadBufferSizeRP struct {
+	Status                  uint8
+	HCLEDataPacketLength    uint16
+	HCTotalNumLEDataPackets uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEReadBufferSizeRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEReadLocalSupportedFeatures implements LE Read Local Supported Features (0x08|0x0003) [Vol 2, Part E, 7.8.3]
+type LEReadLocalSupportedFeatures struct {
+}
+
+func (c *LEReadLocalSupportedFeatures) String() string {
+	return "LE Read Local Supported Features (0x08|0x0003)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEReadLocalSupportedFeatures) OpCode() int { return 0x08<<10 | 0x0003 }
+
+// Len returns the length of the command.
+func (c *LEReadLocalSupportedFeatures) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEReadLocalSupportedFeatures) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEReadLocalSupportedFeaturesRP returns the return parameter of LE Read Local Supported Features
+type LEReadLocalSupportedFeaturesRP struct {
+	Status     uint8
+	LEFeatures uint64
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEReadLocalSupportedFeaturesRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LESetRandomAddress implements LE Set Random Address (0x08|0x0005) [Vol 2, Part E, 7.8.4]
+type LESetRandomAddress struct {
+	RandomAddress [6]byte
+}
+
+func (c *LESetRandomAddress) String() string {
+	return "LE Set Random Address (0x08|0x0005)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetRandomAddress) OpCode() int { return 0x08<<10 | 0x0005 }
+
+// Len returns the length of the command.
+func (c *LESetRandomAddress) Len() int { return 6 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetRandomAddress) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetRandomAddressRP returns the return parameter of LE Set Random Address
+type LESetRandomAddressRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetRandomAddressRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LESetAdvertisingParameters implements LE Set Advertising Parameters (0x08|0x0006) [Vol 2, Part E, 7.8.5]
+type LESetAdvertisingParameters struct {
+	AdvertisingIntervalMin  uint16
+	AdvertisingIntervalMax  uint16
+	AdvertisingType         uint8
+	OwnAddressType          uint8
+	DirectAddressType       uint8
+	DirectAddress           [6]byte
+	AdvertisingChannelMap   uint8
+	AdvertisingFilterPolicy uint8
+}
+
+func (c *LESetAdvertisingParameters) String() string {
+	return "LE Set Advertising Parameters (0x08|0x0006)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetAdvertisingParameters) OpCode() int { return 0x08<<10 | 0x0006 }
+
+// Len returns the length of the command.
+func (c *LESetAdvertisingParameters) Len() int { return 15 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetAdvertisingParameters) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetAdvertisingParametersRP returns the return parameter of LE Set Advertising Parameters
+type LESetAdvertisingParametersRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetAdvertisingParametersRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEReadAdvertisingChannelTxPower implements LE Read Advertising Channel Tx Power (0x08|0x0007) [Vol 2, Part E, 7.8.6]
+type LEReadAdvertisingChannelTxPower struct {
+}
+
+func (c *LEReadAdvertisingChannelTxPower) String() string {
+	return "LE Read Advertising Channel Tx Power (0x08|0x0007)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEReadAdvertisingChannelTxPower) OpCode() int { return 0x08<<10 | 0x0007 }
+
+// Len returns the length of the command.
+func (c *LEReadAdvertisingChannelTxPower) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEReadAdvertisingChannelTxPower) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEReadAdvertisingChannelTxPowerRP returns the return parameter of LE Read Advertising Channel Tx Power
+type LEReadAdvertisingChannelTxPowerRP struct {
+	Status             uint8
+	TransmitPowerLevel uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEReadAdvertisingChannelTxPowerRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LESetAdvertisingData implements LE Set Advertising Data (0x08|0x0008) [Vol 2, Part E, 7.8.7]
+type LESetAdvertisingData struct {
+	AdvertisingDataLength uint8
+	AdvertisingData       [31]byte
+}
+
+func (c *LESetAdvertisingData) String() string {
+	return "LE Set Advertising Data (0x08|0x0008)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetAdvertisingData) OpCode() int { return 0x08<<10 | 0x0008 }
+
+// Len returns the length of the command.
+func (c *LESetAdvertisingData) Len() int { return 32 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetAdvertisingData) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetAdvertisingDataRP returns the return parameter of LE Set Advertising Data
+type LESetAdvertisingDataRP struct {
+	Status                  uint8
+	HCLEDataPacketLength    uint16
+	HCTotalNumLEDataPackets uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetAdvertisingDataRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LESetScanResponseData implements LE Set Scan Response Data (0x08|0x0009) [Vol 2, Part E, 7.8.8]
+type LESetScanResponseData struct {
+	ScanResponseDataLength uint8
+	ScanResponseData       [31]byte
+}
+
+func (c *LESetScanResponseData) String() string {
+	return "LE Set Scan Response Data (0x08|0x0009)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetScanResponseData) OpCode() int { return 0x08<<10 | 0x0009 }
+
+// Len returns the length of the command.
+func (c *LESetScanResponseData) Len() int { return 32 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetScanResponseData) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetScanResponseDataRP returns the return parameter of LE Set Scan Response Data
+type LESetScanResponseDataRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetScanResponseDataRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LESetAdvertiseEnable implements LE Set Advertise Enable (0x08|0x000A) [Vol 2, Part E, 7.8.9]
+type LESetAdvertiseEnable struct {
+	AdvertisingEnable uint8
+}
+
+func (c *LESetAdvertiseEnable) String() string {
+	return "LE Set Advertise Enable (0x08|0x000A)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetAdvertiseEnable) OpCode() int { return 0x08<<10 | 0x000A }
+
+// Len returns the length of the command.
+func (c *LESetAdvertiseEnable) Len() int { return 1 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetAdvertiseEnable) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetAdvertiseEnableRP returns the return parameter of LE Set Advertise Enable
+type LESetAdvertiseEnableRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetAdvertiseEnableRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LESetScanParameters implements LE Set Scan Parameters (0x08|0x000B) [Vol 2, Part E, 7.8.10]
+type LESetScanParameters struct {
+	LEScanType           uint8
+	LEScanInterval       uint16
+	LEScanWindow         uint16
+	OwnAddressType       uint8
+	ScanningFilterPolicy uint8
+}
+
+func (c *LESetScanParameters) String() string {
+	return "LE Set Scan Parameters (0x08|0x000B)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetScanParameters) OpCode() int { return 0x08<<10 | 0x000B }
+
+// Len returns the length of the command.
+func (c *LESetScanParameters) Len() int { return 7 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetScanParameters) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetScanParametersRP returns the return parameter of LE Set Scan Parameters
+type LESetScanParametersRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetScanParametersRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LESetScanEnable implements LE Set Scan Enable (0x08|0x000C) [Vol 2, Part E, 7.8.11]
+type LESetScanEnable struct {
+	LEScanEnable     uint8
+	FilterDuplicates uint8
+}
+
+func (c *LESetScanEnable) String() string {
+	return "LE Set Scan Enable (0x08|0x000C)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetScanEnable) OpCode() int { return 0x08<<10 | 0x000C }
+
+// Len returns the length of the command.
+func (c *LESetScanEnable) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetScanEnable) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetScanEnableRP returns the return parameter of LE Set Scan Enable
+type LESetScanEnableRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetScanEnableRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LECreateConnection implements LE Create Connection (0x08|0x000D) [Vol 2, Part E, 7.8.12]
+type LECreateConnection struct {
+	LEScanInterval        uint16
+	LEScanWindow          uint16
+	InitiatorFilterPolicy uint8
+	PeerAddressType       uint8
+	PeerAddress           [6]byte
+	OwnAddressType        uint8
+	ConnIntervalMin       uint16
+	ConnIntervalMax       uint16
+	ConnLatency           uint16
+	SupervisionTimeout    uint16
+	MinimumCELength       uint16
+	MaximumCELength       uint16
+}
+
+func (c *LECreateConnection) String() string {
+	return "LE Create Connection (0x08|0x000D)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LECreateConnection) OpCode() int { return 0x08<<10 | 0x000D }
+
+// Len returns the length of the command.
+func (c *LECreateConnection) Len() int { return 25 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LECreateConnection) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LECreateConnectionCancel implements LE Create Connection Cancel (0x08|0x000E) [Vol 2, Part E, 7.8.13]
+type LECreateConnectionCancel struct {
+}
+
+func (c *LECreateConnectionCancel) String() string {
+	return "LE Create Connection Cancel (0x08|0x000E)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LECreateConnectionCancel) OpCode() int { return 0x08<<10 | 0x000E }
+
+// Len returns the length of the command.
+func (c *LECreateConnectionCancel) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LECreateConnectionCancel) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LECreateConnectionCancelRP returns the return parameter of LE Create Connection Cancel
+type LECreateConnectionCancelRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LECreateConnectionCancelRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEReadWhiteListSize implements LE Read White List Size (0x08|0x000F) [Vol 2, Part E, 7.8.14]
+type LEReadWhiteListSize struct {
+}
+
+func (c *LEReadWhiteListSize) String() string {
+	return "LE Read White List Size (0x08|0x000F)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEReadWhiteListSize) OpCode() int { return 0x08<<10 | 0x000F }
+
+// Len returns the length of the command.
+func (c *LEReadWhiteListSize) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEReadWhiteListSize) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEReadWhiteListSizeRP returns the return parameter of LE Read White List Size
+type LEReadWhiteListSizeRP struct {
+	Status        uint8
+	WhiteListSize uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEReadWhiteListSizeRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEClearWhiteList implements LE Clear White List (0x08|0x0010) [Vol 2, Part E, 7.8.15]
+type LEClearWhiteList struct {
+}
+
+func (c *LEClearWhiteList) String() string {
+	return "LE Clear White List (0x08|0x0010)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEClearWhiteList) OpCode() int { return 0x08<<10 | 0x0010 }
+
+// Len returns the length of the command.
+func (c *LEClearWhiteList) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEClearWhiteList) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEClearWhiteListRP returns the return parameter of LE Clear White List
+type LEClearWhiteListRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEClearWhiteListRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEAddDeviceToWhiteList implements LE Add Device To White List (0x08|0x0011) [Vol 2, Part E, 7.8.16]
+type LEAddDeviceToWhiteList struct {
+	AddressType uint8
+	Address     [6]byte
+}
+
+func (c *LEAddDeviceToWhiteList) String() string {
+	return "LE Add Device To White List (0x08|0x0011)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEAddDeviceToWhiteList) OpCode() int { return 0x08<<10 | 0x0011 }
+
+// Len returns the length of the command.
+func (c *LEAddDeviceToWhiteList) Len() int { return 7 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEAddDeviceToWhiteList) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEAddDeviceToWhiteListRP returns the return parameter of LE Add Device To White List
+type LEAddDeviceToWhiteListRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEAddDeviceToWhiteListRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LERemoveDeviceFromWhiteList implements LE Remove Device From White List (0x08|0x0012) [Vol 2, Part E, 7.8.17]
+type LERemoveDeviceFromWhiteList struct {
+	AddressType uint8
+	Address     [6]byte
+}
+
+func (c *LERemoveDeviceFromWhiteList) String() string {
+	return "LE Remove Device From White List (0x08|0x0012)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LERemoveDeviceFromWhiteList) OpCode() int { return 0x08<<10 | 0x0012 }
+
+// Len returns the length of the command.
+func (c *LERemoveDeviceFromWhiteList) Len() int { return 7 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LERemoveDeviceFromWhiteList) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LERemoveDeviceFromWhiteListRP returns the return parameter of LE Remove Device From White List
+type LERemoveDeviceFromWhiteListRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LERemoveDeviceFromWhiteListRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEConnectionUpdate implements LE Connection Update (0x08|0x0013) [Vol 2, Part E, 7.8.18]
+type LEConnectionUpdate struct {
+	ConnectionHandle   uint16
+	ConnIntervalMin    uint16
+	ConnIntervalMax    uint16
+	ConnLatency        uint16
+	SupervisionTimeout uint16
+	MinimumCELength    uint16
+	MaximumCELength    uint16
+}
+
+func (c *LEConnectionUpdate) String() string {
+	return "LE Connection Update (0x08|0x0013)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEConnectionUpdate) OpCode() int { return 0x08<<10 | 0x0013 }
+
+// Len returns the length of the command.
+func (c *LEConnectionUpdate) Len() int { return 14 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEConnectionUpdate) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetHostChannelClassification implements LE Set Host Channel Classification (0x08|0x0014) [Vol 2, Part E, 7.8.19]
+type LESetHostChannelClassification struct {
+	ChannelMap [5]byte
+}
+
+func (c *LESetHostChannelClassification) String() string {
+	return "LE Set Host Channel Classification (0x08|0x0014)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LESetHostChannelClassification) OpCode() int { return 0x08<<10 | 0x0014 }
+
+// Len returns the length of the command.
+func (c *LESetHostChannelClassification) Len() int { return 5 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LESetHostChannelClassification) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LESetHostChannelClassificationRP returns the return parameter of LE Set Host Channel Classification
+type LESetHostChannelClassificationRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LESetHostChannelClassificationRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEReadChannelMap implements LE Read Channel Map (0x08|0x0015) [Vol 2, Part E, 7.8.20]
+type LEReadChannelMap struct {
+	ConnectionHandle uint16
+}
+
+func (c *LEReadChannelMap) String() string {
+	return "LE Read Channel Map (0x08|0x0015)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEReadChannelMap) OpCode() int { return 0x08<<10 | 0x0015 }
+
+// Len returns the length of the command.
+func (c *LEReadChannelMap) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEReadChannelMap) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEReadChannelMapRP returns the return parameter of LE Read Channel Map
+type LEReadChannelMapRP struct {
+	Status           uint8
+	ConnectionHandle uint16
+	ChannelMap       [5]byte
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEReadChannelMapRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEReadRemoteUsedFeatures implements LE Read Remote Used Features (0x08|0x0016) [Vol 2, Part E, 7.8.21]
+type LEReadRemoteUsedFeatures struct {
+	ConnectionHandle uint16
+}
+
+func (c *LEReadRemoteUsedFeatures) String() string {
+	return "LE Read Remote Used Features (0x08|0x0016)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEReadRemoteUsedFeatures) OpCode() int { return 0x08<<10 | 0x0016 }
+
+// Len returns the length of the command.
+func (c *LEReadRemoteUsedFeatures) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEReadRemoteUsedFeatures) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEEncrypt implements LE Encrypt (0x08|0x0017) [Vol 2, Part E, 7.8.22]
+type LEEncrypt struct {
+	Key           [16]byte
+	PlaintextData [16]byte
+}
+
+func (c *LEEncrypt) String() string {
+	return "LE Encrypt (0x08|0x0017)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEEncrypt) OpCode() int { return 0x08<<10 | 0x0017 }
+
+// Len returns the length of the command.
+func (c *LEEncrypt) Len() int { return 32 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEEncrypt) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEEncryptRP returns the return parameter of LE Encrypt
+type LEEncryptRP struct {
+	Status        uint8
+	EncryptedData [16]byte
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEEncryptRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LERand implements LE Rand (0x08|0x0018) [Vol 2, Part E, 7.8.23]
+type LERand struct {
+}
+
+func (c *LERand) String() string {
+	return "LE Rand (0x08|0x0018)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LERand) OpCode() int { return 0x08<<10 | 0x0018 }
+
+// Len returns the length of the command.
+func (c *LERand) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LERand) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LERandRP returns the return parameter of LE Rand
+type LERandRP struct {
+	Status       uint8
+	RandomNumber uint64
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LERandRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEStartEncryption implements LE Start Encryption (0x08|0x0019) [Vol 2, Part E, 7.8.24]
+type LEStartEncryption struct {
+	ConnectionHandle     uint16
+	RandomNumber         uint64
+	EncryptedDiversifier uint16
+	LongTermKey          [16]byte
+}
+
+func (c *LEStartEncryption) String() string {
+	return "LE Start Encryption (0x08|0x0019)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEStartEncryption) OpCode() int { return 0x08<<10 | 0x0019 }
+
+// Len returns the length of the command.
+func (c *LEStartEncryption) Len() int { return 28 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEStartEncryption) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LELongTermKeyRequestReply implements LE Long Term Key Request Reply (0x08|0x001A) [Vol 2, Part E, 7.8.25]
+type LELongTermKeyRequestReply struct {
+	ConnectionHandle uint16
+	LongTermKey      [16]byte
+}
+
+func (c *LELongTermKeyRequestReply) String() string {
+	return "LE Long Term Key Request Reply (0x08|0x001A)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LELongTermKeyRequestReply) OpCode() int { return 0x08<<10 | 0x001A }
+
+// Len returns the length of the command.
+func (c *LELongTermKeyRequestReply) Len() int { return 18 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LELongTermKeyRequestReply) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LELongTermKeyRequestReplyRP returns the return parameter of LE Long Term Key Request Reply
+type LELongTermKeyRequestReplyRP struct {
+	Status           uint8
+	ConnectionHandle uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LELongTermKeyRequestReplyRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LELongTermKeyRequestNegativeReply implements LE Long Term Key Request Negative Reply (0x08|0x001B) [Vol 2, Part E, 7.8.26]
+type LELongTermKeyRequestNegativeReply struct {
+	ConnectionHandle uint16
+}
+
+func (c *LELongTermKeyRequestNegativeReply) String() string {
+	return "LE Long Term Key Request Negative Reply (0x08|0x001B)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LELongTermKeyRequestNegativeReply) OpCode() int { return 0x08<<10 | 0x001B }
+
+// Len returns the length of the command.
+func (c *LELongTermKeyRequestNegativeReply) Len() int { return 2 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LELongTermKeyRequestNegativeReply) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LELongTermKeyRequestNegativeReplyRP returns the return parameter of LE Long Term Key Request Negative Reply
+type LELongTermKeyRequestNegativeReplyRP struct {
+	Status           uint8
+	ConnectionHandle uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LELongTermKeyRequestNegativeReplyRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEReadSupportedStates implements LE Read Supported States (0x08|0x001C) [Vol 2, Part E, 7.8.27]
+type LEReadSupportedStates struct {
+}
+
+func (c *LEReadSupportedStates) String() string {
+	return "LE Read Supported States (0x08|0x001C)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEReadSupportedStates) OpCode() int { return 0x08<<10 | 0x001C }
+
+// Len returns the length of the command.
+func (c *LEReadSupportedStates) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEReadSupportedStates) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEReadSupportedStatesRP returns the return parameter of LE Read Supported States
+type LEReadSupportedStatesRP struct {
+	Status   uint8
+	LEStates uint64
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEReadSupportedStatesRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LEReceiverTest implements LE Receiver Test (0x08|0x001D) [Vol 2, Part E, 7.8.28]
+type LEReceiverTest struct {
+	RXChannel uint8
+}
+
+func (c *LEReceiverTest) String() string {
+	return "LE Receiver Test (0x08|0x001D)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LEReceiverTest) OpCode() int { return 0x08<<10 | 0x001D }
+
+// Len returns the length of the command.
+func (c *LEReceiverTest) Len() int { return 1 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LEReceiverTest) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LEReceiverTestRP returns the return parameter of LE Receiver Test
+type LEReceiverTestRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LEReceiverTestRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LETransmitterTest implements LE Transmitter Test (0x08|0x001E) [Vol 2, Part E, 7.8.29]
+type LETransmitterTest struct {
+	TXChannel        uint8
+	LengthOfTestData uint8
+	PacketPayload    uint8
+}
+
+func (c *LETransmitterTest) String() string {
+	return "LE Transmitter Test (0x08|0x001E)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LETransmitterTest) OpCode() int { return 0x08<<10 | 0x001E }
+
+// Len returns the length of the command.
+func (c *LETransmitterTest) Len() int { return 3 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LETransmitterTest) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LETransmitterTestRP returns the return parameter of LE Transmitter Test
+type LETransmitterTestRP struct {
+	Status uint8
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LETransmitterTestRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LETestEnd implements LE Test End (0x08|0x001F) [Vol 2, Part E, 7.8.30]
+type LETestEnd struct {
+}
+
+func (c *LETestEnd) String() string {
+	return "LE Test End (0x08|0x001F)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LETestEnd) OpCode() int { return 0x08<<10 | 0x001F }
+
+// Len returns the length of the command.
+func (c *LETestEnd) Len() int { return 0 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LETestEnd) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LETestEndRP returns the return parameter of LE Test End
+type LETestEndRP struct {
+	Status          uint8
+	NumberOfPackats uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LETestEndRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LERemoteConnectionParameterRequestReply implements LE Remote Connection Parameter Request Reply (0x08|0x0020) [Vol 2, Part E, 7.8.31]
+type LERemoteConnectionParameterRequestReply struct {
+	ConnectionHandle uint16
+	IntervalMin      uint16
+	IntervalMax      uint16
+	Latency          uint16
+	Timeout          uint16
+	MinimumCELength  uint16
+	MaximumCELength  uint16
+}
+
+func (c *LERemoteConnectionParameterRequestReply) String() string {
+	return "LE Remote Connection Parameter Request Reply (0x08|0x0020)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LERemoteConnectionParameterRequestReply) OpCode() int { return 0x08<<10 | 0x0020 }
+
+// Len returns the length of the command.
+func (c *LERemoteConnectionParameterRequestReply) Len() int { return 14 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LERemoteConnectionParameterRequestReply) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LERemoteConnectionParameterRequestReplyRP returns the return parameter of LE Remote Connection Parameter Request Reply
+type LERemoteConnectionParameterRequestReplyRP struct {
+	Status           uint8
+	ConnectionHandle uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LERemoteConnectionParameterRequestReplyRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
+
+// LERemoteConnectionParameterRequestNegativeReply implements LE Remote Connection Parameter Request Negative Reply (0x08|0x0021) [Vol 2, Part E, 7.8.32]
+type LERemoteConnectionParameterRequestNegativeReply struct {
+	ConnectionHandle uint16
+	Reason           uint8
+}
+
+func (c *LERemoteConnectionParameterRequestNegativeReply) String() string {
+	return "LE Remote Connection Parameter Request Negative Reply (0x08|0x0021)"
+}
+
+// OpCode returns the opcode of the command.
+func (c *LERemoteConnectionParameterRequestNegativeReply) OpCode() int { return 0x08<<10 | 0x0021 }
+
+// Len returns the length of the command.
+func (c *LERemoteConnectionParameterRequestNegativeReply) Len() int { return 3 }
+
+// Marshal serializes the command parameters into binary form.
+func (c *LERemoteConnectionParameterRequestNegativeReply) Marshal(b []byte) error {
+	return marshal(c, b)
+}
+
+// LERemoteConnectionParameterRequestNegativeReplyRP returns the return parameter of LE Remote Connection Parameter Request Negative Reply
+type LERemoteConnectionParameterRequestNegativeReplyRP struct {
+	Status           uint8
+	ConnectionHandle uint16
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (c *LERemoteConnectionParameterRequestNegativeReplyRP) Unmarshal(b []byte) error {
+	return unmarshal(c, b)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/conn.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/conn.go
new file mode 100644
index 0000000..af7d652
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/conn.go
@@ -0,0 +1,338 @@
+package hci
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"net"
+
+	"golang.org/x/net/context"
+
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/linux/hci/cmd"
+	"github.com/currantlabs/ble/linux/hci/evt"
+	"github.com/pkg/errors"
+)
+
+// Conn ...
+type Conn struct {
+	hci *HCI
+	ctx context.Context
+
+	param evt.LEConnectionComplete
+
+	// While MTU is the maximum size of payload data that the upper layer (ATT)
+	// can accept, the MPS is the maximum PDU payload size this L2CAP implementation
+	// supports. When segmantation is not used, the MPS should be made to the same
+	// values of MTUs [Vol 3, Part A, 1.4].
+	//
+	// For LE-U logical transport, the L2CAP implementations should support
+	// a minimum of 23 bytes, which are also the default values before the
+	// upper layer (ATT) optionally reconfigures them [Vol 3, Part A, 3.2.8].
+	rxMTU int
+	txMTU int
+	rxMPS int
+
+	// leFrame is set to be true when the LE Credit based flow control is used.
+	leFrame bool
+
+	// Signaling MTUs are The maximum size of command information that the
+	// L2CAP layer entity is capable of accepting.
+	// A L2CAP implementations supporting LE-U should support at least 23 bytes.
+	// Currently, we support 512 bytes, which should be more than sufficient.
+	// The sigTxMTU is discovered via when we sent a signaling pkt that is
+	// larger thean the remote device can handle, and get a response of "Command
+	// Reject" indicating "Signaling MTU exceeded" along with the actual
+	// signaling MTU [Vol 3, Part A, 4.1].
+	sigRxMTU int
+	sigTxMTU int
+
+	// sigID is used to match responses with signaling requests.
+	// The requesting device sets this field and the responding device uses the
+	// same value in its response. Within each signalling channel a different
+	// Identifier shall be used for each successive command. [Vol 3, Part A, 4]
+	sigID uint8
+
+	sigSent chan []byte
+	smpSent chan []byte
+
+	chInPkt chan packet
+	chInPDU chan pdu
+
+	// Host to Controller Data Flow Control pkt-based Data flow control for LE-U [Vol 2, Part E, 4.1.1]
+	// chSentBufs tracks the HCI buffer occupied by this connection.
+	txBuffer *Client
+
+	chDone chan struct{}
+}
+
+func newConn(h *HCI, param evt.LEConnectionComplete) *Conn {
+	c := &Conn{
+		hci:   h,
+		ctx:   context.Background(),
+		param: param,
+
+		rxMTU: ble.DefaultMTU,
+		txMTU: ble.DefaultMTU,
+
+		rxMPS: ble.DefaultMTU,
+
+		sigRxMTU: ble.MaxMTU,
+		sigTxMTU: ble.DefaultMTU,
+
+		chInPkt: make(chan packet, 16),
+		chInPDU: make(chan pdu, 16),
+
+		txBuffer: NewClient(h.pool),
+
+		chDone: make(chan struct{}),
+	}
+
+	go func() {
+		for {
+			if err := c.recombine(); err != nil {
+				if err != io.EOF {
+					// TODO: wrap and pass the error up.
+					// err := errors.Wrap(err, "recombine failed")
+					logger.Error("recombine failed: ", "err", err)
+				}
+				close(c.chInPDU)
+				return
+			}
+		}
+	}()
+	return c
+}
+
+// Context returns the context that is used by this Conn.
+func (c *Conn) Context() context.Context {
+	return c.ctx
+}
+
+// SetContext sets the context that is used by this Conn.
+func (c *Conn) SetContext(ctx context.Context) {
+	c.ctx = ctx
+}
+
+// Read copies re-assembled L2CAP PDUs into sdu.
+func (c *Conn) Read(sdu []byte) (n int, err error) {
+	p, ok := <-c.chInPDU
+	if !ok {
+		return 0, errors.Wrap(io.ErrClosedPipe, "input channel closed")
+	}
+	if len(p) == 0 {
+		return 0, errors.Wrap(io.ErrUnexpectedEOF, "recieved empty packet")
+	}
+
+	// Assume it's a B-Frame.
+	slen := p.dlen()
+	data := p.payload()
+	if c.leFrame {
+		// LE-Frame.
+		slen = leFrameHdr(p).slen()
+		data = leFrameHdr(p).payload()
+	}
+	if cap(sdu) < slen {
+		return 0, errors.Wrapf(io.ErrShortBuffer, "payload recieved exceeds sdu buffer")
+	}
+	buf := bytes.NewBuffer(sdu)
+	buf.Reset()
+	buf.Write(data)
+	for buf.Len() < slen {
+		p := <-c.chInPDU
+		buf.Write(pdu(p).payload())
+	}
+	return slen, nil
+}
+
+// Write breaks down a L2CAP SDU into segmants [Vol 3, Part A, 7.3.1]
+func (c *Conn) Write(sdu []byte) (int, error) {
+	if len(sdu) > c.txMTU {
+		return 0, errors.Wrap(io.ErrShortWrite, "payload exceeds mtu")
+	}
+
+	plen := len(sdu)
+	if plen > c.txMTU {
+		plen = c.txMTU
+	}
+	b := make([]byte, 4+plen)
+	binary.LittleEndian.PutUint16(b[0:2], uint16(len(sdu)))
+	binary.LittleEndian.PutUint16(b[2:4], cidLEAtt)
+	if c.leFrame {
+		binary.LittleEndian.PutUint16(b[4:6], uint16(len(sdu)))
+		copy(b[6:], sdu)
+	} else {
+		copy(b[4:], sdu)
+	}
+	sent, err := c.writePDU(b)
+	if err != nil {
+		return sent, err
+	}
+	sdu = sdu[plen:]
+
+	for len(sdu) > 0 {
+		plen := len(sdu)
+		if plen > c.txMTU {
+			plen = c.txMTU
+		}
+		n, err := c.writePDU(sdu[:plen])
+		sent += n
+		if err != nil {
+			return sent, err
+		}
+		sdu = sdu[plen:]
+	}
+	return sent, nil
+}
+
+// writePDU breaks down a L2CAP PDU into fragments if it's larger than the HCI buffer size. [Vol 3, Part A, 7.2.1]
+func (c *Conn) writePDU(pdu []byte) (int, error) {
+	sent := 0
+	flags := uint16(pbfHostToControllerStart << 4) // ACL boundary flags
+
+	// All L2CAP fragments associated with an L2CAP PDU shall be processed for
+	// transmission by the Controller before any other L2CAP PDU for the same
+	// logical transport shall be processed.
+	c.txBuffer.LockPool()
+	defer c.txBuffer.UnlockPool()
+
+	for len(pdu) > 0 {
+		// Get a buffer from our pre-allocated and flow-controlled pool.
+		pkt := c.txBuffer.Get() // ACL pkt
+		flen := len(pdu)        // fragment length
+		if flen > pkt.Cap()-1-4 {
+			flen = pkt.Cap() - 1 - 4
+		}
+
+		// Prepare the Headers
+		binary.Write(pkt, binary.LittleEndian, uint8(pktTypeACLData))                         // HCI Header: pkt Type
+		binary.Write(pkt, binary.LittleEndian, uint16(c.param.ConnectionHandle()|(flags<<8))) // ACL Header: handle and flags
+		binary.Write(pkt, binary.LittleEndian, uint16(flen))                                  // ACL Header: data len
+		binary.Write(pkt, binary.LittleEndian, pdu[:flen])                                    // Append payload
+
+		// Flush the pkt to HCI
+		select {
+		case <-c.chDone:
+			return 0, io.ErrClosedPipe
+		default:
+		}
+
+		if _, err := c.hci.skt.Write(pkt.Bytes()); err != nil {
+			return sent, err
+		}
+		sent += flen
+
+		flags = (pbfContinuing << 4) // Set "continuing" in the boundary flags for the rest of fragments, if any.
+		pdu = pdu[flen:]             // Advence the point
+	}
+	return sent, nil
+}
+
+// Recombines fragments into a L2CAP PDU. [Vol 3, Part A, 7.2.2]
+func (c *Conn) recombine() error {
+	pkt, ok := <-c.chInPkt
+	if !ok {
+		return io.EOF
+	}
+
+	p := pdu(pkt.data())
+
+	// Currently, check for LE-U only. For channels that we don't recognizes,
+	// re-combine them anyway, and discard them later when we dispatch the PDU
+	// according to CID.
+	if p.cid() == cidLEAtt && p.dlen() > c.rxMPS {
+		return fmt.Errorf("fragment size (%d) larger than rxMPS (%d)", p.dlen(), c.rxMPS)
+	}
+
+	// If this pkt is not a complete PDU, and we'll be receiving more
+	// fragments, re-allocate the whole PDU (including Header).
+	if len(p.payload()) < p.dlen() {
+		p = make([]byte, 0, 4+p.dlen())
+		p = append(p, pdu(pkt.data())...)
+	}
+	for len(p) < 4+p.dlen() {
+		if pkt, ok = <-c.chInPkt; !ok || (pkt.pbf()&pbfContinuing) == 0 {
+			return io.ErrUnexpectedEOF
+		}
+		p = append(p, pdu(pkt.data())...)
+	}
+
+	// TODO: support dynamic or assigned channels for LE-Frames.
+	switch p.cid() {
+	case cidLEAtt:
+		c.chInPDU <- p
+	case cidLESignal:
+		c.handleSignal(p)
+	case cidSMP:
+		c.handleSMP(p)
+	default:
+		logger.Info("recombine()", "unrecognized CID", fmt.Sprintf("%04X, [%X]", p.cid(), p))
+	}
+	return nil
+}
+
+// Disconnected returns a receiving channel, which is closed when the connection disconnects.
+func (c *Conn) Disconnected() <-chan struct{} {
+	return c.chDone
+}
+
+// Close disconnects the connection by sending hci disconnect command to the device.
+func (c *Conn) Close() error {
+	select {
+	case <-c.chDone:
+		// Return if it's already closed.
+		return nil
+	default:
+		c.hci.Send(&cmd.Disconnect{
+			ConnectionHandle: c.param.ConnectionHandle(),
+			Reason:           0x13,
+		}, nil)
+		return nil
+	}
+}
+
+// LocalAddr returns local device's MAC address.
+func (c *Conn) LocalAddr() ble.Addr { return c.hci.Addr() }
+
+// RemoteAddr returns remote device's MAC address.
+func (c *Conn) RemoteAddr() ble.Addr {
+	a := c.param.PeerAddress()
+	return net.HardwareAddr([]byte{a[5], a[4], a[3], a[2], a[1], a[0]})
+}
+
+// RxMTU returns the MTU which the upper layer is capable of accepting.
+func (c *Conn) RxMTU() int { return c.rxMTU }
+
+// SetRxMTU sets the MTU which the upper layer is capable of accepting.
+func (c *Conn) SetRxMTU(mtu int) { c.rxMTU, c.rxMPS = mtu, mtu }
+
+// TxMTU returns the MTU which the remote device is capable of accepting.
+func (c *Conn) TxMTU() int { return c.txMTU }
+
+// SetTxMTU sets the MTU which the remote device is capable of accepting.
+func (c *Conn) SetTxMTU(mtu int) { c.txMTU = mtu }
+
+// pkt implements HCI ACL Data Packet [Vol 2, Part E, 5.4.2]
+// Packet boundary flags , bit[5:6] of handle field's MSB
+// Broadcast flags. bit[7:8] of handle field's MSB
+// Not used in LE-U. Leave it as 0x00 (Point-to-Point).
+// Broadcasting in LE uses ADVB logical transport.
+type packet []byte
+
+func (a packet) handle() uint16 { return uint16(a[0]) | (uint16(a[1]&0x0f) << 8) }
+func (a packet) pbf() int       { return (int(a[1]) >> 4) & 0x3 }
+func (a packet) bcf() int       { return (int(a[1]) >> 6) & 0x3 }
+func (a packet) dlen() int      { return int(a[2]) | (int(a[3]) << 8) }
+func (a packet) data() []byte   { return a[4:] }
+
+type pdu []byte
+
+func (p pdu) dlen() int       { return int(binary.LittleEndian.Uint16(p[0:2])) }
+func (p pdu) cid() uint16     { return binary.LittleEndian.Uint16(p[2:4]) }
+func (p pdu) payload() []byte { return p[4:] }
+
+type leFrameHdr pdu
+
+func (f leFrameHdr) slen() int       { return int(binary.LittleEndian.Uint16(f[4:6])) }
+func (f leFrameHdr) payload() []byte { return f[6:] }
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/const.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/const.go
new file mode 100644
index 0000000..bf1781b
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/const.go
@@ -0,0 +1,30 @@
+package hci
+
+// HCI Packet types
+const (
+	pktTypeCommand uint8 = 0x01
+	pktTypeACLData uint8 = 0x02
+	pktTypeSCOData uint8 = 0x03
+	pktTypeEvent   uint8 = 0x04
+	pktTypeVendor  uint8 = 0xFF
+)
+
+// Packet boundary flags of HCI ACL Data Packet [Vol 2, Part E, 5.4.2].
+const (
+	pbfHostToControllerStart = 0x00 // Start of a non-automatically-flushable from host to controller.
+	pbfContinuing            = 0x01 // Continuing fragment.
+	pbfControllerToHostStart = 0x02 // Start of a non-automatically-flushable from controller to host.
+	pbfCompleteL2CAPPDU      = 0x03 // A automatically flushable complete PDU. (Not used in LE-U).
+)
+
+// L2CAP Channel Identifier namespace for LE-U logical link [Vol 3, Part A, 2.1].
+const (
+	cidLEAtt    uint16 = 0x04 // Attribute Protocol [Vol 3, Part F].
+	cidLESignal uint16 = 0x05 // Low Energy L2CAP Signaling channel [Vol 3, Part A, 4].
+	cidSMP      uint16 = 0x06 // SecurityManager Protocol [Vol 3, Part H].
+)
+
+const (
+	roleMaster = 0x00
+	roleSlave  = 0x01
+)
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/error.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/error.go
new file mode 100644
index 0000000..0a23b6a
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/error.go
@@ -0,0 +1,161 @@
+package hci
+
+import "errors"
+
+// errors
+var (
+	ErrBusyScanning    = errors.New("busy scanning")
+	ErrBusyAdvertising = errors.New("busy advertising")
+	ErrBusyDialing     = errors.New("busy dialing")
+	ErrBusyListening   = errors.New("busy listening")
+	ErrInvalidAddr     = errors.New("invalid address")
+)
+
+// HCI Command Errors  [Vol2, Part D, 1.3 ]
+// FIXME: Terrible shorthand. Name them properly.
+const (
+	ErrUnknownCommand       ErrCommand = 0x01 // Unknown HCI Command
+	ErrConnID               ErrCommand = 0x02 // Unknown Connection Identifier
+	ErrHardware             ErrCommand = 0x03 // Hardware Failure
+	ErrPageTimeout          ErrCommand = 0x04 // Page Timeout
+	ErrAuth                 ErrCommand = 0x05 // Authentication Failure
+	ErrPINMissing           ErrCommand = 0x06 // PIN or Key Missing
+	ErrMemoryCapacity       ErrCommand = 0x07 // Memory Capacity Exceeded
+	ErrConnTimeout          ErrCommand = 0x08 // Connection Timeout
+	ErrConnLimit            ErrCommand = 0x09 // Connection Limit Exceeded
+	ErrSCOConnLimit         ErrCommand = 0x0A // Synchronous Connection Limit To A Device Exceeded
+	ErrACLConnExists        ErrCommand = 0x0B // ACL Connection Already Exists
+	ErrDisallowed           ErrCommand = 0x0C // Command Disallowed
+	ErrLimitedResource      ErrCommand = 0x0D // Connection Rejected due to Limited Resources
+	ErrSecurity             ErrCommand = 0x0E // Connection Rejected Due To Security Reasons
+	ErrBDADDR               ErrCommand = 0x0F // Connection Rejected due to Unacceptable BD_ADDR
+	ErrConnAcceptTimeout    ErrCommand = 0x10 // Connection Accept Timeout Exceeded
+	ErrUnsupportedParams    ErrCommand = 0x11 // Unsupported Feature or Parameter Value
+	ErrInvalidParams        ErrCommand = 0x12 // Invalid HCI Command Parameters
+	ErrRemoteUser           ErrCommand = 0x13 // Remote User Terminated Connection
+	ErrRemoteLowResources   ErrCommand = 0x14 // Remote Device Terminated Connection due to Low Resources
+	ErrRemotePowerOff       ErrCommand = 0x15 // Remote Device Terminated Connection due to Power Off
+	ErrLocalHost            ErrCommand = 0x16 // Connection Terminated By Local Host
+	ErrRepeatedAttempts     ErrCommand = 0x17 // Repeated Attempts
+	ErrPairingNotAllowed    ErrCommand = 0x18 // Pairing Not Allowed
+	ErrUnknownLMP           ErrCommand = 0x19 // Unknown LMP PDU
+	ErrUnsupportedLMP       ErrCommand = 0x1A // Unsupported Remote Feature / Unsupported LMP Feature
+	ErrSCOOffset            ErrCommand = 0x1B // SCO Offset Rejected
+	ErrSCOInterval          ErrCommand = 0x1C // SCO Interval Rejected
+	ErrSCOAirMode           ErrCommand = 0x1D // SCO Air Mode Rejected
+	ErrInvalidLLParams      ErrCommand = 0x1E // Invalid LMP Parameters / Invalid LL Parameters
+	ErrUnspecified          ErrCommand = 0x1F // Unspecified Error
+	ErrUnsupportedLLParams  ErrCommand = 0x20 // Unsupported LMP Parameter Value / Unsupported LL Parameter Value
+	ErrRoleChangeNotAllowed ErrCommand = 0x21 // Role Change Not Allowed
+	ErrLLResponseTimeout    ErrCommand = 0x22 // LMP Response Timeout / LL Response Timeout
+	ErrLMPTransColl         ErrCommand = 0x23 // LMP Error Transaction Collision
+	ErrLMPPDU               ErrCommand = 0x24 // LMP PDU Not Allowed
+	ErrEncNotAccepted       ErrCommand = 0x25 // Encryption Mode Not Acceptable
+	ErrLinkKey              ErrCommand = 0x26 // Link Key cannot be Changed
+	ErrQoSNotSupported      ErrCommand = 0x27 // Requested QoS Not Supported
+	ErrInstantPassed        ErrCommand = 0x28 // Instant Passed
+	ErrUnitKeyNotSupported  ErrCommand = 0x29 // Pairing With Unit Key Not Supported
+	ErrDifferentTransColl   ErrCommand = 0x2A // Different Transaction Collision
+	ErrQOSParameter         ErrCommand = 0x2C // QoS Unacceptable Parameter
+	ErrQOSReject            ErrCommand = 0x2D // QoS Rejected
+	ErrChannelClass         ErrCommand = 0x2E // Channel Classification Not Supported
+	ErrInsufficientSecurity ErrCommand = 0x2F // Insufficient Security
+	ErrOutOfRange           ErrCommand = 0x30 // Parameter Out Of Mandatory Range
+	ErrRoleSwitchPending    ErrCommand = 0x32 // Role Switch Pending
+	ErrReservedSlot         ErrCommand = 0x34 // Reserved Slot Violation
+	ErrRoleSwitch           ErrCommand = 0x35 // Role Switch Failed
+	ErrEIRTooLarge          ErrCommand = 0x36 // Extended Inquiry Response Too Large
+	ErrSecureSimplePairing  ErrCommand = 0x37 // Secure Simple Pairing Not Supported By Host
+	ErrHostBusy             ErrCommand = 0x38 // Host Busy - Pairing
+	ErrNoChannel            ErrCommand = 0x39 // Connection Rejected due to No Suitable Channel Found
+	ErrControllerBusy       ErrCommand = 0x3A // Controller Busy
+	ErrConnParams           ErrCommand = 0x3B // Unacceptable Connection Parameters
+	ErrDirAdvTimeout        ErrCommand = 0x3C // Directed Advertising Timeout
+	ErrMIC                  ErrCommand = 0x3D // Connection Terminated due to MIC Failure
+	ErrEstablished          ErrCommand = 0x3E // Connection Failed to be Established
+	ErrMACConn              ErrCommand = 0x3F // MAC Connection Failed
+	ErrCoarseClock          ErrCommand = 0x40 // Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging
+	// 0x2B // Reserved
+	// 0x31 // Reserved
+	// 0x33 // Reserved
+)
+
+// ErrCommand [Vol2, Part D, 1.3 ]
+type ErrCommand byte
+
+func (e ErrCommand) Error() string {
+	if s, ok := errCmd[e]; ok {
+		return s
+	}
+	// A Host shall consider any error code that it does not explicitly
+	// understand equivalent to the “Unspecified Error (0x1F).”
+	return errCmd[0x1F]
+}
+
+var errCmd = map[ErrCommand]string{
+	0x00: "Success",
+	0x01: "Unknown HCI Command",
+	0x02: "Unknown Connection Identifier",
+	0x03: "Hardware Failure",
+	0x04: "Page Timeou",
+	0x05: "Authentication Failure",
+	0x06: "PIN or Key Missing",
+	0x07: "Memory Capacity Exceeded",
+	0x08: "Connection Timeout",
+	0x09: "Connection Limit Exceeded",
+	0x0A: "Synchronous Connection Limit To A Device Exceeded",
+	0x0B: "ACL Connection Already Exists",
+	0x0C: "Command Disallowed",
+	0x0D: "Connection Rejected due to Limited Resources",
+	0x0E: "Connection Rejected Due To Security Reasons",
+	0x0F: "Connection Rejected due to Unacceptable BD_ADDR",
+	0x10: "Connection Accept Timeout Exceeded",
+	0x11: "Unsupported Feature or Parameter Value",
+	0x12: "Invalid HCI Command Parameters",
+	0x13: "Remote User Terminated Connection",
+	0x14: "Remote Device Terminated Connection due to Low Resources",
+	0x15: "Remote Device Terminated Connection due to Power Off",
+	0x16: "Connection Terminated By Local Host",
+	0x17: "Repeated Attempts",
+	0x18: "Pairing Not Allowed",
+	0x19: "Unknown LMP PDU",
+	0x1A: "Unsupported Remote Feature / Unsupported LMP Feature",
+	0x1B: "SCO Offset Rejected",
+	0x1C: "SCO Interval Rejected",
+	0x1D: "SCO Air Mode Rejected",
+	0x1E: "Invalid LMP Parameters / Invalid LL Parameters",
+	0x1F: "Unspecified Error",
+	0x20: "Unsupported LMP Parameter Value / Unsupported LL Parameter Value",
+	0x21: "Role Change Not Allowed",
+	0x22: "LMP Response Timeout / LL Response Timeout",
+	0x23: "LMP Error Transaction Collision",
+	0x24: "LMP PDU Not Allowed",
+	0x25: "Encryption Mode Not Acceptable",
+	0x26: "Link Key cannot be Changed",
+	0x27: "Requested QoS Not Supported",
+	0x28: "Instant Passed",
+	0x29: "Pairing With Unit Key Not Supported",
+	0x2A: "Different Transaction Collision",
+	0x2B: "Reserved",
+	0x2C: "QoS Unacceptable Parameter",
+	0x2D: "QoS Rejected",
+	0x2E: "Channel Classification Not Supported",
+	0x2F: "Insufficient Security",
+	0x30: "Parameter Out Of Mandatory Range",
+	0x31: "Reserved",
+	0x32: "Role Switch Pending",
+	0x33: "Reserved",
+	0x34: "Reserved Slot Violation",
+	0x35: "Role Switch Failed",
+	0x36: "Extended Inquiry Response Too Large",
+	0x37: "Secure Simple Pairing Not Supported By Host",
+	0x38: "Host Busy - Pairing",
+	0x39: "Connection Rejected due to No Suitable Channel Found",
+	0x3A: "Controller Busy",
+	0x3B: "Unacceptable Connection Parameters",
+	0x3C: "Directed Advertising Timeout",
+	0x3D: "Connection Terminated due to MIC Failure",
+	0x3E: "Connection Failed to be Established",
+	0x3F: "MAC Connection Failed",
+	0x40: "Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging",
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/evt/evt.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/evt/evt.go
new file mode 100644
index 0000000..4ce88d5
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/evt/evt.go
@@ -0,0 +1,55 @@
+package evt
+
+import "encoding/binary"
+
+func (e CommandComplete) NumHCICommandPackets() uint8 { return e[0] }
+func (e CommandComplete) CommandOpcode() uint16       { return binary.LittleEndian.Uint16(e[1:]) }
+func (e CommandComplete) ReturnParameters() []byte    { return e[3:] }
+
+// Per-spec [Vol 2, Part E, 7.7.19], the packet structure should be:
+//
+//     NumOfHandle, HandleA, HandleB, CompPktNumA, CompPktNumB
+//
+// But we got the actual packet from BCM20702A1 with the following structure instead.
+//
+//     NumOfHandle, HandleA, CompPktNumA, HandleB, CompPktNumB
+//              02,   40 00,       01 00,   41 00,       01 00
+
+func (e NumberOfCompletedPackets) NumberOfHandles() uint8 { return e[0] }
+func (e NumberOfCompletedPackets) ConnectionHandle(i int) uint16 {
+	// return binary.LittleEndian.Uint16(e[1+i*2:])
+	return binary.LittleEndian.Uint16(e[1+i*4:])
+}
+func (e NumberOfCompletedPackets) HCNumOfCompletedPackets(i int) uint16 {
+	// return binary.LittleEndian.Uint16(e[1+int(e.NumberOfHandles())*2:])
+	return binary.LittleEndian.Uint16(e[1+i*4+2:])
+}
+func (e LEAdvertisingReport) SubeventCode() uint8     { return e[0] }
+func (e LEAdvertisingReport) NumReports() uint8       { return e[1] }
+func (e LEAdvertisingReport) EventType(i int) uint8   { return e[2+i] }
+func (e LEAdvertisingReport) AddressType(i int) uint8 { return e[2+int(e.NumReports())*1+i] }
+func (e LEAdvertisingReport) Address(i int) [6]byte {
+	e = e[2+int(e.NumReports())*2:]
+	b := [6]byte{}
+	copy(b[:], e[6*i:])
+	return b
+}
+
+func (e LEAdvertisingReport) LengthData(i int) uint8 { return e[2+int(e.NumReports())*8+i] }
+
+func (e LEAdvertisingReport) Data(i int) []byte {
+	l := 0
+	for j := 0; j < i; j++ {
+		l += int(e.LengthData(j))
+	}
+	b := e[2+int(e.NumReports())*9+l:]
+	return b[:e.LengthData(i)]
+}
+
+func (e LEAdvertisingReport) RSSI(i int) int8 {
+	l := 0
+	for j := 0; j < int(e.NumReports()); j++ {
+		l += int(e.LengthData(j))
+	}
+	return int8(e[2+int(e.NumReports())*9+l+i])
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/evt/evt_gen.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/evt/evt_gen.go
new file mode 100644
index 0000000..7582d7f
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/evt/evt_gen.go
@@ -0,0 +1,227 @@
+package evt
+
+import "encoding/binary"
+
+const DisconnectionCompleteCode = 0x05
+
+// DisconnectionComplete implements Disconnection Complete (0x05) [Vol 2, Part E, 7.7.5].
+type DisconnectionComplete []byte
+
+func (r DisconnectionComplete) Status() uint8 { return r[0] }
+
+func (r DisconnectionComplete) ConnectionHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+func (r DisconnectionComplete) Reason() uint8 { return r[3] }
+
+const EncryptionChangeCode = 0x08
+
+// EncryptionChange implements Encryption Change (0x08) [Vol 2, Part E, 7.7.8].
+type EncryptionChange []byte
+
+func (r EncryptionChange) Status() uint8 { return r[0] }
+
+func (r EncryptionChange) ConnectionHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+func (r EncryptionChange) EncryptionEnabled() uint8 { return r[3] }
+
+const ReadRemoteVersionInformationCompleteCode = 0x0C
+
+// ReadRemoteVersionInformationComplete implements Read Remote Version Information Complete (0x0C) [Vol 2, Part E, 7.7.12].
+type ReadRemoteVersionInformationComplete []byte
+
+func (r ReadRemoteVersionInformationComplete) Status() uint8 { return r[0] }
+
+func (r ReadRemoteVersionInformationComplete) ConnectionHandle() uint16 {
+	return binary.LittleEndian.Uint16(r[1:])
+}
+
+func (r ReadRemoteVersionInformationComplete) Version() uint8 { return r[3] }
+
+func (r ReadRemoteVersionInformationComplete) ManufacturerName() uint16 {
+	return binary.LittleEndian.Uint16(r[4:])
+}
+
+func (r ReadRemoteVersionInformationComplete) Subversion() uint16 {
+	return binary.LittleEndian.Uint16(r[6:])
+}
+
+const CommandCompleteCode = 0x0E
+
+// CommandComplete implements Command Complete (0x0E) [Vol 2, Part E, 7.7.14].
+type CommandComplete []byte
+
+const CommandStatusCode = 0x0F
+
+// CommandStatus implements Command Status (0x0F) [Vol 2, Part E, 7.7.15].
+type CommandStatus []byte
+
+func (r CommandStatus) Status() uint8 { return r[0] }
+
+func (r CommandStatus) NumHCICommandPackets() uint8 { return r[1] }
+
+func (r CommandStatus) CommandOpcode() uint16 { return binary.LittleEndian.Uint16(r[2:]) }
+
+const HardwareErrorCode = 0x10
+
+// HardwareError implements Hardware Error (0x10) [Vol 2, Part E, 7.7.16].
+type HardwareError []byte
+
+func (r HardwareError) HardwareCode() uint8 { return r[0] }
+
+const NumberOfCompletedPacketsCode = 0x13
+
+// NumberOfCompletedPackets implements Number Of Completed Packets (0x13) [Vol 2, Part E, 7.7.19].
+type NumberOfCompletedPackets []byte
+
+const DataBufferOverflowCode = 0x1A
+
+// DataBufferOverflow implements Data Buffer Overflow (0x1A) [Vol 2, Part E, 7.7.26].
+type DataBufferOverflow []byte
+
+func (r DataBufferOverflow) LinkType() uint8 { return r[0] }
+
+const EncryptionKeyRefreshCompleteCode = 0x30
+
+// EncryptionKeyRefreshComplete implements Encryption Key Refresh Complete (0x30) [Vol 2, Part E, 7.7.39].
+type EncryptionKeyRefreshComplete []byte
+
+func (r EncryptionKeyRefreshComplete) Status() uint8 { return r[0] }
+
+func (r EncryptionKeyRefreshComplete) ConnectionHandle() uint16 {
+	return binary.LittleEndian.Uint16(r[1:])
+}
+
+const LEConnectionCompleteCode = 0x3E
+
+const LEConnectionCompleteSubCode = 0x01
+
+// LEConnectionComplete implements LE Connection Complete (0x3E:0x01) [Vol 2, Part E, 7.7.65.1].
+type LEConnectionComplete []byte
+
+func (r LEConnectionComplete) SubeventCode() uint8 { return r[0] }
+
+func (r LEConnectionComplete) Status() uint8 { return r[1] }
+
+func (r LEConnectionComplete) ConnectionHandle() uint16 { return binary.LittleEndian.Uint16(r[2:]) }
+
+func (r LEConnectionComplete) Role() uint8 { return r[4] }
+
+func (r LEConnectionComplete) PeerAddressType() uint8 { return r[5] }
+
+func (r LEConnectionComplete) PeerAddress() [6]byte {
+	b := [6]byte{}
+	copy(b[:], r[6:])
+	return b
+}
+
+func (r LEConnectionComplete) ConnInterval() uint16 { return binary.LittleEndian.Uint16(r[12:]) }
+
+func (r LEConnectionComplete) ConnLatency() uint16 { return binary.LittleEndian.Uint16(r[14:]) }
+
+func (r LEConnectionComplete) SupervisionTimeout() uint16 { return binary.LittleEndian.Uint16(r[16:]) }
+
+func (r LEConnectionComplete) MasterClockAccuracy() uint8 { return r[18] }
+
+const LEAdvertisingReportCode = 0x3E
+
+const LEAdvertisingReportSubCode = 0x02
+
+// LEAdvertisingReport implements LE Advertising Report (0x3E:0x02) [Vol 2, Part E, 7.7.65.2].
+type LEAdvertisingReport []byte
+
+const LEConnectionUpdateCompleteCode = 0x0E
+
+const LEConnectionUpdateCompleteSubCode = 0x03
+
+// LEConnectionUpdateComplete implements LE Connection Update Complete (0x0E:0x03) [Vol 2, Part E, 7.7.65.3].
+type LEConnectionUpdateComplete []byte
+
+func (r LEConnectionUpdateComplete) SubeventCode() uint8 { return r[0] }
+
+func (r LEConnectionUpdateComplete) Status() uint8 { return r[1] }
+
+func (r LEConnectionUpdateComplete) ConnectionHandle() uint16 {
+	return binary.LittleEndian.Uint16(r[2:])
+}
+
+func (r LEConnectionUpdateComplete) ConnInterval() uint16 { return binary.LittleEndian.Uint16(r[4:]) }
+
+func (r LEConnectionUpdateComplete) ConnLatency() uint16 { return binary.LittleEndian.Uint16(r[6:]) }
+
+func (r LEConnectionUpdateComplete) SupervisionTimeout() uint16 {
+	return binary.LittleEndian.Uint16(r[8:])
+}
+
+const LEReadRemoteUsedFeaturesCompleteCode = 0x3E
+
+const LEReadRemoteUsedFeaturesCompleteSubCode = 0x04
+
+// LEReadRemoteUsedFeaturesComplete implements LE Read Remote Used Features Complete (0x3E:0x04) [Vol 2, Part E, 7.7.65.4].
+type LEReadRemoteUsedFeaturesComplete []byte
+
+func (r LEReadRemoteUsedFeaturesComplete) SubeventCode() uint8 { return r[0] }
+
+func (r LEReadRemoteUsedFeaturesComplete) Status() uint8 { return r[1] }
+
+func (r LEReadRemoteUsedFeaturesComplete) ConnectionHandle() uint16 {
+	return binary.LittleEndian.Uint16(r[2:])
+}
+
+func (r LEReadRemoteUsedFeaturesComplete) LEFeatures() uint64 {
+	return binary.LittleEndian.Uint64(r[4:])
+}
+
+const LELongTermKeyRequestCode = 0x3E
+
+const LELongTermKeyRequestSubCode = 0x05
+
+// LELongTermKeyRequest implements LE Long Term Key Request (0x3E:0x05) [Vol 2, Part E, 7.7.65.5].
+type LELongTermKeyRequest []byte
+
+func (r LELongTermKeyRequest) SubeventCode() uint8 { return r[0] }
+
+func (r LELongTermKeyRequest) ConnectionHandle() uint16 { return binary.LittleEndian.Uint16(r[1:]) }
+
+func (r LELongTermKeyRequest) RandomNumber() uint64 { return binary.LittleEndian.Uint64(r[3:]) }
+
+func (r LELongTermKeyRequest) EncryptionDiversifier() uint16 {
+	return binary.LittleEndian.Uint16(r[11:])
+}
+
+const LERemoteConnectionParameterRequestCode = 0x3E
+
+const LERemoteConnectionParameterRequestSubCode = 0x06
+
+// LERemoteConnectionParameterRequest implements LE Remote Connection Parameter Request (0x3E:0x06) [Vol 2, Part E, 7.7.65.6].
+type LERemoteConnectionParameterRequest []byte
+
+func (r LERemoteConnectionParameterRequest) SubeventCode() uint8 { return r[0] }
+
+func (r LERemoteConnectionParameterRequest) ConnectionHandle() uint16 {
+	return binary.LittleEndian.Uint16(r[1:])
+}
+
+func (r LERemoteConnectionParameterRequest) IntervalMin() uint16 {
+	return binary.LittleEndian.Uint16(r[3:])
+}
+
+func (r LERemoteConnectionParameterRequest) IntervalMax() uint16 {
+	return binary.LittleEndian.Uint16(r[5:])
+}
+
+func (r LERemoteConnectionParameterRequest) Latency() uint16 {
+	return binary.LittleEndian.Uint16(r[7:])
+}
+
+func (r LERemoteConnectionParameterRequest) Timeout() uint16 {
+	return binary.LittleEndian.Uint16(r[9:])
+}
+
+const AuthenticatedPayloadTimeoutExpiredCode = 0x57
+
+// AuthenticatedPayloadTimeoutExpired implements Authenticated Payload Timeout Expired (0x57) [Vol 2, Part E, 7.7.75].
+type AuthenticatedPayloadTimeoutExpired []byte
+
+func (r AuthenticatedPayloadTimeoutExpired) ConnectionHandle() uint16 {
+	return binary.LittleEndian.Uint16(r[0:])
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/gap.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/gap.go
new file mode 100644
index 0000000..0a0e0f0
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/gap.go
@@ -0,0 +1,214 @@
+package hci
+
+import (
+	"fmt"
+	"net"
+	"time"
+
+	"golang.org/x/net/context"
+
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/linux/adv"
+	"github.com/currantlabs/ble/linux/gatt"
+	"github.com/pkg/errors"
+)
+
+// Addr ...
+func (h *HCI) Addr() ble.Addr { return h.addr }
+
+// SetAdvHandler ...
+func (h *HCI) SetAdvHandler(ah ble.AdvHandler) error {
+	h.advHandler = ah
+	return nil
+}
+
+// Scan starts scanning.
+func (h *HCI) Scan(allowDup bool) error {
+	h.params.scanEnable.FilterDuplicates = 1
+	if allowDup {
+		h.params.scanEnable.FilterDuplicates = 0
+	}
+	h.params.scanEnable.LEScanEnable = 1
+	h.adHist = make([]*Advertisement, 128)
+	h.adLast = 0
+	return h.Send(&h.params.scanEnable, nil)
+}
+
+// StopScanning stops scanning.
+func (h *HCI) StopScanning() error {
+	h.params.scanEnable.LEScanEnable = 0
+	return h.Send(&h.params.scanEnable, nil)
+}
+
+// AdvertiseNameAndServices advertises device name, and specified service UUIDs.
+// It tries to fit the UUIDs in the advertising data as much as possible.
+// If name doesn't fit in the advertising data, it will be put in scan response.
+func (h *HCI) AdvertiseNameAndServices(name string, uuids ...ble.UUID) error {
+	ad, err := adv.NewPacket(adv.Flags(adv.FlagGeneralDiscoverable | adv.FlagLEOnly))
+	if err != nil {
+		return err
+	}
+	f := adv.AllUUID
+
+	// Current length of ad packet plus two bytes of length and tag.
+	l := ad.Len() + 1 + 1
+	for _, u := range uuids {
+		l += u.Len()
+	}
+	if l > adv.MaxEIRPacketLength {
+		f = adv.SomeUUID
+	}
+	for _, u := range uuids {
+		if err := ad.Append(f(u)); err != nil {
+			if err == adv.ErrNotFit {
+				break
+			}
+			return err
+		}
+	}
+	sr, _ := adv.NewPacket()
+	switch {
+	case ad.Append(adv.CompleteName(name)) == nil:
+	case sr.Append(adv.CompleteName(name)) == nil:
+	case sr.Append(adv.ShortName(name)) == nil:
+	}
+	if err := h.SetAdvertisement(ad.Bytes(), sr.Bytes()); err != nil {
+		return nil
+	}
+	return h.Advertise()
+}
+
+// AdvertiseMfgData avertises the given manufacturer data.
+func (h *HCI) AdvertiseMfgData(id uint16, md []byte) error {
+	ad, err := adv.NewPacket(adv.ManufacturerData(id, md))
+	if err != nil {
+		return err
+	}
+	if err := h.SetAdvertisement(ad.Bytes(), nil); err != nil {
+		return nil
+	}
+	return h.Advertise()
+}
+
+// AdvertiseServiceData16 advertises data associated with a 16bit service uuid
+func (h *HCI) AdvertiseServiceData16(id uint16, b []byte) error {
+	ad, err := adv.NewPacket(adv.ServiceData16(id, b))
+	if err != nil {
+		return err
+	}
+	if err := h.SetAdvertisement(ad.Bytes(), nil); err != nil {
+		return nil
+	}
+	return h.Advertise()
+}
+
+// AdvertiseIBeaconData advertise iBeacon with given manufacturer data.
+func (h *HCI) AdvertiseIBeaconData(md []byte) error {
+	ad, err := adv.NewPacket(adv.IBeaconData(md))
+	if err != nil {
+		return err
+	}
+	if err := h.SetAdvertisement(ad.Bytes(), nil); err != nil {
+		return nil
+	}
+	return h.Advertise()
+}
+
+// AdvertiseIBeacon advertises iBeacon with specified parameters.
+func (h *HCI) AdvertiseIBeacon(u ble.UUID, major, minor uint16, pwr int8) error {
+	ad, err := adv.NewPacket(adv.IBeacon(u, major, minor, pwr))
+	if err != nil {
+		return err
+	}
+	if err := h.SetAdvertisement(ad.Bytes(), nil); err != nil {
+		return nil
+	}
+	return h.Advertise()
+}
+
+// StopAdvertising stops advertising.
+func (h *HCI) StopAdvertising() error {
+	h.params.advEnable.AdvertisingEnable = 0
+	return h.Send(&h.params.advEnable, nil)
+}
+
+// Accept starts advertising and accepts connection.
+func (h *HCI) Accept() (ble.Conn, error) {
+	var tmo <-chan time.Time
+	if h.listenerTmo != time.Duration(0) {
+		tmo = time.After(h.listenerTmo)
+	}
+	select {
+	case <-h.done:
+		return nil, h.err
+	case c := <-h.chSlaveConn:
+		return c, nil
+	case <-tmo:
+		return nil, fmt.Errorf("listner timed out")
+	}
+}
+
+// Dial ...
+func (h *HCI) Dial(ctx context.Context, a ble.Addr) (ble.Client, error) {
+	b, err := net.ParseMAC(a.String())
+	if err != nil {
+		return nil, ErrInvalidAddr
+	}
+	h.params.connParams.PeerAddress = [6]byte{b[5], b[4], b[3], b[2], b[1], b[0]}
+	if _, ok := a.(RandomAddress); ok {
+		h.params.connParams.PeerAddressType = 1
+	}
+	if err = h.Send(&h.params.connParams, nil); err != nil {
+		return nil, err
+	}
+	var tmo <-chan time.Time
+	if h.dialerTmo != time.Duration(0) {
+		tmo = time.After(h.dialerTmo)
+	}
+	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	case <-h.done:
+		return nil, h.err
+	case c := <-h.chMasterConn:
+		return gatt.NewClient(c)
+	case <-tmo:
+		err := h.Send(&h.params.connCancel, nil)
+		if err == nil {
+			// The pending connection was canceled successfully.
+			return nil, fmt.Errorf("connection timed out")
+		}
+		// The connection has been established, the cancel command
+		// failed with ErrDisallowed.
+		if err == ErrDisallowed {
+			return gatt.NewClient(<-h.chMasterConn)
+		}
+		return nil, errors.Wrap(err, "cancel connection failed")
+	}
+}
+
+// Advertise starts advertising.
+func (h *HCI) Advertise() error {
+	h.params.advEnable.AdvertisingEnable = 1
+	return h.Send(&h.params.advEnable, nil)
+}
+
+// SetAdvertisement sets advertising data and scanResp.
+func (h *HCI) SetAdvertisement(ad []byte, sr []byte) error {
+	if len(ad) > adv.MaxEIRPacketLength || len(sr) > adv.MaxEIRPacketLength {
+		return ble.ErrEIRPacketTooLong
+	}
+
+	h.params.advData.AdvertisingDataLength = uint8(len(ad))
+	copy(h.params.advData.AdvertisingData[:], ad)
+	if err := h.Send(&h.params.advData, nil); err != nil {
+		return err
+	}
+
+	h.params.scanResp.ScanResponseDataLength = uint8(len(sr))
+	copy(h.params.scanResp.ScanResponseData[:], sr)
+	if err := h.Send(&h.params.scanResp, nil); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/hci.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/hci.go
new file mode 100644
index 0000000..6d711f2
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/hci.go
@@ -0,0 +1,517 @@
+package hci
+
+import (
+	"fmt"
+	"io"
+	"net"
+	"sync"
+	"time"
+
+	"github.com/currantlabs/ble"
+	"github.com/currantlabs/ble/linux/hci/cmd"
+	"github.com/currantlabs/ble/linux/hci/evt"
+	"github.com/currantlabs/ble/linux/hci/socket"
+	"github.com/pkg/errors"
+)
+
+// Command ...
+type Command interface {
+	OpCode() int
+	Len() int
+	Marshal([]byte) error
+}
+
+// CommandRP ...
+type CommandRP interface {
+	Unmarshal(b []byte) error
+}
+
+type handlerFn func(b []byte) error
+
+type pkt struct {
+	cmd  Command
+	done chan []byte
+}
+
+// NewHCI returns a hci device.
+func NewHCI(opts ...Option) (*HCI, error) {
+	h := &HCI{
+		id: -1,
+
+		chCmdPkt:  make(chan *pkt),
+		chCmdBufs: make(chan []byte, 8),
+		sent:      make(map[int]*pkt),
+
+		evth: map[int]handlerFn{},
+		subh: map[int]handlerFn{},
+
+		muConns:      &sync.Mutex{},
+		conns:        make(map[uint16]*Conn),
+		chMasterConn: make(chan *Conn),
+		chSlaveConn:  make(chan *Conn),
+
+		done: make(chan bool),
+	}
+	h.params.init()
+	if err := h.Option(opts...); err != nil {
+		return nil, errors.Wrap(err, "can't set options")
+	}
+
+	return h, nil
+}
+
+// HCI ...
+type HCI struct {
+	sync.Mutex
+
+	params params
+
+	skt io.ReadWriteCloser
+	id  int
+
+	// Host to Controller command flow control [Vol 2, Part E, 4.4]
+	chCmdPkt  chan *pkt
+	chCmdBufs chan []byte
+	sent      map[int]*pkt
+
+	// evtHub
+	evth map[int]handlerFn
+	subh map[int]handlerFn
+
+	// aclHandler
+	bufSize int
+	bufCnt  int
+
+	// Device information or status.
+	addr    net.HardwareAddr
+	txPwrLv int
+
+	// adHist and adLast track the history of past scannable advertising packets.
+	// Controller delivers AD(Advertising Data) and SR(Scan Response) separately
+	// through HCI. Upon recieving an AD, no matter it's scannable or not, we
+	// pass a Advertisment (AD only) to advHandler immediately.
+	// Upon recieving a SR, we search the AD history for the AD from the same
+	// device, and pass the Advertisiement (AD+SR) to advHandler.
+	// The adHist and adLast are allocated in the Scan().
+	advHandler ble.AdvHandler
+	adHist     []*Advertisement
+	adLast     int
+
+	// Host to Controller Data Flow Control Packet-based Data flow control for LE-U [Vol 2, Part E, 4.1.1]
+	// Minimum 27 bytes. 4 bytes of L2CAP Header, and 23 bytes Payload from upper layer (ATT)
+	pool *Pool
+
+	// L2CAP connections
+	muConns      *sync.Mutex
+	conns        map[uint16]*Conn
+	chMasterConn chan *Conn // Dial returns master connections.
+	chSlaveConn  chan *Conn // Peripheral accept slave connections.
+
+	dialerTmo   time.Duration
+	listenerTmo time.Duration
+
+	err  error
+	done chan bool
+}
+
+// Init ...
+func (h *HCI) Init() error {
+	h.evth[0x3E] = h.handleLEMeta
+	h.evth[evt.CommandCompleteCode] = h.handleCommandComplete
+	h.evth[evt.CommandStatusCode] = h.handleCommandStatus
+	h.evth[evt.DisconnectionCompleteCode] = h.handleDisconnectionComplete
+	h.evth[evt.NumberOfCompletedPacketsCode] = h.handleNumberOfCompletedPackets
+
+	h.subh[evt.LEAdvertisingReportSubCode] = h.handleLEAdvertisingReport
+	h.subh[evt.LEConnectionCompleteSubCode] = h.handleLEConnectionComplete
+	h.subh[evt.LEConnectionUpdateCompleteSubCode] = h.handleLEConnectionUpdateComplete
+	h.subh[evt.LELongTermKeyRequestSubCode] = h.handleLELongTermKeyRequest
+	// evt.EncryptionChangeCode:                     todo),
+	// evt.ReadRemoteVersionInformationCompleteCode: todo),
+	// evt.HardwareErrorCode:                        todo),
+	// evt.DataBufferOverflowCode:                   todo),
+	// evt.EncryptionKeyRefreshCompleteCode:         todo),
+	// evt.AuthenticatedPayloadTimeoutExpiredCode:   todo),
+	// evt.LEReadRemoteUsedFeaturesCompleteSubCode:   todo),
+	// evt.LERemoteConnectionParameterRequestSubCode: todo),
+
+	skt, err := socket.NewSocket(h.id)
+	if err != nil {
+		return err
+	}
+	h.skt = skt
+
+	h.chCmdBufs <- make([]byte, 64)
+
+	go h.sktLoop()
+	h.init()
+
+	// Pre-allocate buffers with additional head room for lower layer headers.
+	// HCI header (1 Byte) + ACL Data Header (4 bytes) + L2CAP PDU (or fragment)
+	h.pool = NewPool(1+4+h.bufSize, h.bufCnt-1)
+
+	h.Send(&h.params.advParams, nil)
+	h.Send(&h.params.scanParams, nil)
+	return nil
+}
+
+// Close ...
+func (h *HCI) Close() error {
+	return h.close(nil)
+}
+
+// Error ...
+func (h *HCI) Error() error {
+	return h.err
+}
+
+// Option sets the options specified.
+func (h *HCI) Option(opts ...Option) error {
+	var err error
+	for _, opt := range opts {
+		err = opt(h)
+	}
+	return err
+}
+
+func (h *HCI) init() error {
+	h.Send(&cmd.Reset{}, nil)
+
+	ReadBDADDRRP := cmd.ReadBDADDRRP{}
+	h.Send(&cmd.ReadBDADDR{}, &ReadBDADDRRP)
+
+	a := ReadBDADDRRP.BDADDR
+	h.addr = net.HardwareAddr([]byte{a[5], a[4], a[3], a[2], a[1], a[0]})
+
+	ReadBufferSizeRP := cmd.ReadBufferSizeRP{}
+	h.Send(&cmd.ReadBufferSize{}, &ReadBufferSizeRP)
+
+	// Assume the buffers are shared between ACL-U and LE-U.
+	h.bufCnt = int(ReadBufferSizeRP.HCTotalNumACLDataPackets)
+	h.bufSize = int(ReadBufferSizeRP.HCACLDataPacketLength)
+
+	LEReadBufferSizeRP := cmd.LEReadBufferSizeRP{}
+	h.Send(&cmd.LEReadBufferSize{}, &LEReadBufferSizeRP)
+
+	if LEReadBufferSizeRP.HCTotalNumLEDataPackets != 0 {
+		// Okay, LE-U do have their own buffers.
+		h.bufCnt = int(LEReadBufferSizeRP.HCTotalNumLEDataPackets)
+		h.bufSize = int(LEReadBufferSizeRP.HCLEDataPacketLength)
+	}
+
+	LEReadAdvertisingChannelTxPowerRP := cmd.LEReadAdvertisingChannelTxPowerRP{}
+	h.Send(&cmd.LEReadAdvertisingChannelTxPower{}, &LEReadAdvertisingChannelTxPowerRP)
+
+	h.txPwrLv = int(LEReadAdvertisingChannelTxPowerRP.TransmitPowerLevel)
+
+	LESetEventMaskRP := cmd.LESetEventMaskRP{}
+	h.Send(&cmd.LESetEventMask{LEEventMask: 0x000000000000001F}, &LESetEventMaskRP)
+
+	SetEventMaskRP := cmd.SetEventMaskRP{}
+	h.Send(&cmd.SetEventMask{EventMask: 0x3dbff807fffbffff}, &SetEventMaskRP)
+
+	WriteLEHostSupportRP := cmd.WriteLEHostSupportRP{}
+	h.Send(&cmd.WriteLEHostSupport{LESupportedHost: 1, SimultaneousLEHost: 0}, &WriteLEHostSupportRP)
+
+	return h.err
+}
+
+// Send ...
+func (h *HCI) Send(c Command, r CommandRP) error {
+	b, err := h.send(c)
+	if err != nil {
+		return err
+	}
+	if len(b) > 0 && b[0] != 0x00 {
+		return ErrCommand(b[0])
+	}
+	if r != nil {
+		return r.Unmarshal(b)
+	}
+	return nil
+}
+
+func (h *HCI) send(c Command) ([]byte, error) {
+	if h.err != nil {
+		return nil, h.err
+	}
+	p := &pkt{c, make(chan []byte)}
+	b := <-h.chCmdBufs
+	b[0] = byte(pktTypeCommand) // HCI header
+	b[1] = byte(c.OpCode())
+	b[2] = byte(c.OpCode() >> 8)
+	b[3] = byte(c.Len())
+	if err := c.Marshal(b[4:]); err != nil {
+		h.close(fmt.Errorf("hci: failed to marshal cmd"))
+	}
+
+	h.sent[c.OpCode()] = p // TODO: lock
+	if n, err := h.skt.Write(b[:4+c.Len()]); err != nil {
+		h.close(fmt.Errorf("hci: failed to send cmd"))
+	} else if n != 4+c.Len() {
+		h.close(fmt.Errorf("hci: failed to send whole cmd pkt to hci socket"))
+	}
+
+	select {
+	case <-h.done:
+		return nil, h.err
+	case b := <-p.done:
+		return b, nil
+	}
+}
+
+func (h *HCI) sktLoop() {
+	b := make([]byte, 4096)
+	defer close(h.done)
+	for {
+		n, err := h.skt.Read(b)
+		if n == 0 || err != nil {
+			h.err = fmt.Errorf("skt: %s", err)
+			return
+		}
+		p := make([]byte, n)
+		copy(p, b)
+		if err := h.handlePkt(p); err != nil {
+			h.err = fmt.Errorf("skt: %s", err)
+			return
+		}
+	}
+}
+
+func (h *HCI) close(err error) error {
+	h.err = err
+	return h.skt.Close()
+}
+
+func (h *HCI) handlePkt(b []byte) error {
+	// Strip the 1-byte HCI header and pass down the rest of the packet.
+	t, b := b[0], b[1:]
+	switch t {
+	case pktTypeCommand:
+		return fmt.Errorf("unmanaged cmd: % X", b)
+	case pktTypeACLData:
+		return h.handleACL(b)
+	case pktTypeSCOData:
+		return fmt.Errorf("unsupported sco packet: % X", b)
+	case pktTypeEvent:
+		return h.handleEvt(b)
+	case pktTypeVendor:
+		return fmt.Errorf("unsupported vendor packet: % X", b)
+	default:
+		return fmt.Errorf("invalid packet: 0x%02X % X", t, b)
+	}
+}
+
+func (h *HCI) handleACL(b []byte) error {
+	h.muConns.Lock()
+	c, ok := h.conns[packet(b).handle()]
+	h.muConns.Unlock()
+	if !ok {
+		return fmt.Errorf("invalid connection handle")
+	}
+	c.chInPkt <- b
+	return nil
+}
+
+func (h *HCI) handleEvt(b []byte) error {
+	code, plen := int(b[0]), int(b[1])
+	if plen != len(b[2:]) {
+		return fmt.Errorf("invalid event packet: % X", b)
+	}
+	if code == evt.CommandCompleteCode || code == evt.CommandStatusCode {
+		if f := h.evth[code]; f != nil {
+			return f(b[2:])
+		}
+	}
+	if plen != len(b[2:]) {
+		h.err = fmt.Errorf("invalid event packet: % X", b)
+	}
+	if f := h.evth[code]; f != nil {
+		h.err = f(b[2:])
+		return nil
+	}
+	return fmt.Errorf("unsupported event packet: % X", b)
+}
+
+func (h *HCI) handleLEMeta(b []byte) error {
+	subcode := int(b[0])
+	if f := h.subh[subcode]; f != nil {
+		return f(b)
+	}
+	return fmt.Errorf("unsupported LE event: % X", b)
+}
+
+func (h *HCI) handleLEAdvertisingReport(b []byte) error {
+	if h.advHandler == nil {
+		return nil
+	}
+
+	e := evt.LEAdvertisingReport(b)
+	for i := 0; i < int(e.NumReports()); i++ {
+		var a *Advertisement
+		switch e.EventType(i) {
+		case evtTypAdvInd:
+			fallthrough
+		case evtTypAdvScanInd:
+			a = newAdvertisement(e, i)
+			h.adHist[h.adLast] = a
+			h.adLast++
+			if h.adLast == len(h.adHist) {
+				h.adLast = 0
+			}
+		case evtTypScanRsp:
+			sr := newAdvertisement(e, i)
+			for idx := h.adLast - 1; idx != h.adLast; idx-- {
+				if idx == -1 {
+					idx = len(h.adHist) - 1
+				}
+				if h.adHist[idx] == nil {
+					break
+				}
+				if h.adHist[idx].Address().String() == sr.Address().String() {
+					h.adHist[idx].setScanResponse(sr)
+					a = h.adHist[idx]
+					break
+				}
+			}
+			// Got a SR without having recieved an associated AD before?
+			if a == nil {
+				return fmt.Errorf("recieved scan response %s with no associated Advertising Data packet", sr.Address())
+			}
+		default:
+			a = newAdvertisement(e, i)
+		}
+		go h.advHandler(a)
+	}
+
+	return nil
+}
+
+func (h *HCI) handleCommandComplete(b []byte) error {
+	e := evt.CommandComplete(b)
+	for i := 0; i < int(e.NumHCICommandPackets()); i++ {
+		h.chCmdBufs <- make([]byte, 64)
+	}
+
+	// NOP command, used for flow control purpose [Vol 2, Part E, 4.4]
+	if e.CommandOpcode() == 0x0000 {
+		h.chCmdBufs = make(chan []byte, 8)
+		return nil
+	}
+	p, found := h.sent[int(e.CommandOpcode())]
+	if !found {
+		return fmt.Errorf("can't find the cmd for CommandCompleteEP: % X", e)
+	}
+	p.done <- e.ReturnParameters()
+	return nil
+}
+
+func (h *HCI) handleCommandStatus(b []byte) error {
+	e := evt.CommandStatus(b)
+	for i := 0; i < int(e.NumHCICommandPackets()); i++ {
+		h.chCmdBufs <- make([]byte, 64)
+	}
+
+	p, found := h.sent[int(e.CommandOpcode())]
+	if !found {
+		return fmt.Errorf("can't find the cmd for CommandStatusEP: % X", e)
+	}
+	p.done <- []byte{e.Status()}
+	return nil
+}
+
+func (h *HCI) handleLEConnectionComplete(b []byte) error {
+	e := evt.LEConnectionComplete(b)
+	c := newConn(h, e)
+	h.muConns.Lock()
+	h.conns[e.ConnectionHandle()] = c
+	h.muConns.Unlock()
+	if e.Role() == roleMaster {
+		if e.Status() == 0x00 {
+			h.chMasterConn <- c
+			return nil
+		}
+		if ErrCommand(e.Status()) == ErrConnID {
+			// The connection was canceled successfully.
+			return nil
+		}
+		return nil
+	}
+	if e.Status() == 0x00 {
+		h.chSlaveConn <- c
+		// When a controller accepts a connection, it moves from advertising
+		// state to idle/ready state. Host needs to explicitly ask the
+		// controller to re-enable advertising. Note that the host was most
+		// likely in advertising state. Otherwise it couldn't accept the
+		// connection in the first place. The only exception is that user
+		// asked the host to stop advertising during this tiny window.
+		// The re-enabling might failed or ignored by the controller, if
+		// it had reached the maximum number of concurrent connections.
+		// So we also re-enable the advertising when a connection disconnected
+		h.params.RLock()
+		if h.params.advEnable.AdvertisingEnable == 1 {
+			go h.Send(&h.params.advEnable, nil)
+		}
+		h.params.RUnlock()
+	}
+	return nil
+}
+
+func (h *HCI) handleLEConnectionUpdateComplete(b []byte) error {
+	return nil
+}
+
+func (h *HCI) handleDisconnectionComplete(b []byte) error {
+	e := evt.DisconnectionComplete(b)
+	h.muConns.Lock()
+	c, found := h.conns[e.ConnectionHandle()]
+	delete(h.conns, e.ConnectionHandle())
+	h.muConns.Unlock()
+	if !found {
+		return fmt.Errorf("disconnecting an invalid handle %04X", e.ConnectionHandle())
+	}
+	close(c.chInPkt)
+	if c.param.Role() == roleSlave {
+		// Re-enable advertising, if it was advertising. Refer to the
+		// handleLEConnectionComplete() for details.
+		// This may failed with ErrCommandDisallowed, if the controller
+		// was actually in advertising state. It does no harm though.
+		h.params.RLock()
+		if h.params.advEnable.AdvertisingEnable == 1 {
+			go h.Send(&h.params.advEnable, nil)
+		}
+		h.params.RUnlock()
+	} else {
+		// remote peripheral disconnected
+		close(c.chDone)
+	}
+	// When a connection disconnects, all the sent packets and weren't acked yet
+	// will be recycled. [Vol2, Part E 4.1.1]
+	c.txBuffer.PutAll()
+	return nil
+}
+
+func (h *HCI) handleNumberOfCompletedPackets(b []byte) error {
+	e := evt.NumberOfCompletedPackets(b)
+	h.muConns.Lock()
+	defer h.muConns.Unlock()
+	for i := 0; i < int(e.NumberOfHandles()); i++ {
+		c, found := h.conns[e.ConnectionHandle(i)]
+		if !found {
+			continue
+		}
+
+		// Put the delivered buffers back to the pool.
+		for j := 0; j < int(e.HCNumOfCompletedPackets(i)); j++ {
+			c.txBuffer.Put()
+		}
+	}
+	return nil
+}
+
+func (h *HCI) handleLELongTermKeyRequest(b []byte) error {
+	e := evt.LELongTermKeyRequest(b)
+	return h.Send(&cmd.LELongTermKeyRequestNegativeReply{
+		ConnectionHandle: e.ConnectionHandle(),
+	}, nil)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/log.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/log.go
new file mode 100644
index 0000000..412ef65
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/log.go
@@ -0,0 +1,7 @@
+package hci
+
+import (
+	"github.com/mgutz/logxi/v1"
+)
+
+var logger = log.New("hci")
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/option.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/option.go
new file mode 100644
index 0000000..5d1ca26
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/option.go
@@ -0,0 +1,42 @@
+package hci
+
+import (
+	"time"
+
+	"github.com/currantlabs/ble/linux/hci/cmd"
+)
+
+// An Option is a configuration function, which configures the device.
+type Option func(*HCI) error
+
+// OptDeviceID sets HCI device ID.
+func OptDeviceID(id int) Option {
+	return func(h *HCI) error {
+		h.id = id
+		return nil
+	}
+}
+
+// OptDialerTimeout sets dialing timeout for Dialer.
+func OptDialerTimeout(d time.Duration) Option {
+	return func(h *HCI) error {
+		h.dialerTmo = d
+		return nil
+	}
+}
+
+// OptListenerTimeout sets dialing timeout for Listener.
+func OptListenerTimeout(d time.Duration) Option {
+	return func(h *HCI) error {
+		h.listenerTmo = d
+		return nil
+	}
+}
+
+// OptConnParams overrides default connection parameters.
+func OptConnParams(param cmd.LECreateConnection) Option {
+	return func(h *HCI) error {
+		h.params.connParams = param
+		return nil
+	}
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/params.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/params.go
new file mode 100644
index 0000000..bbf36f6
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/params.go
@@ -0,0 +1,55 @@
+package hci
+
+import (
+	"sync"
+
+	"github.com/currantlabs/ble/linux/hci/cmd"
+)
+
+type params struct {
+	sync.RWMutex
+
+	advEnable  cmd.LESetAdvertiseEnable
+	scanEnable cmd.LESetScanEnable
+	connCancel cmd.LECreateConnectionCancel
+
+	advData    cmd.LESetAdvertisingData
+	scanResp   cmd.LESetScanResponseData
+	advParams  cmd.LESetAdvertisingParameters
+	scanParams cmd.LESetScanParameters
+	connParams cmd.LECreateConnection
+}
+
+func (p *params) init() {
+	p.scanParams = cmd.LESetScanParameters{
+		LEScanType:           0x01,   // 0x00: passive, 0x01: active
+		LEScanInterval:       0x0004, // 0x0004 - 0x4000; N * 0.625msec
+		LEScanWindow:         0x0004, // 0x0004 - 0x4000; N * 0.625msec
+		OwnAddressType:       0x00,   // 0x00: public, 0x01: random
+		ScanningFilterPolicy: 0x00,   // 0x00: accept all, 0x01: ignore non-white-listed.
+	}
+	p.advParams = cmd.LESetAdvertisingParameters{
+		AdvertisingIntervalMin:  0x0020,    // 0x0020 - 0x4000; N * 0.625 msec
+		AdvertisingIntervalMax:  0x0020,    // 0x0020 - 0x4000; N * 0.625 msec
+		AdvertisingType:         0x00,      // 00: 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,
+	}
+	p.connParams = cmd.LECreateConnection{
+		LEScanInterval:        0x0004,    // 0x0004 - 0x4000; N * 0.625 msec
+		LEScanWindow:          0x0004,    // 0x0004 - 0x4000; N * 0.625 msec
+		InitiatorFilterPolicy: 0x00,      // White list is not used
+		PeerAddressType:       0x00,      // Public Device Address
+		PeerAddress:           [6]byte{}, //
+		OwnAddressType:        0x00,      // Public Device Address
+		ConnIntervalMin:       0x0006,    // 0x0006 - 0x0C80; N * 1.25 msec
+		ConnIntervalMax:       0x0006,    // 0x0006 - 0x0C80; N * 1.25 msec
+		ConnLatency:           0x0000,    // 0x0000 - 0x01F3; N * 1.25 msec
+		SupervisionTimeout:    0x0048,    // 0x000A - 0x0C80; N * 10 msec
+		MinimumCELength:       0x0000,    // 0x0000 - 0xFFFF; N * 0.625 msec
+		MaximumCELength:       0x0000,    // 0x0000 - 0xFFFF; N * 0.625 msec
+	}
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/signal.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/signal.go
new file mode 100644
index 0000000..81d4998
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/signal.go
@@ -0,0 +1,223 @@
+package hci
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"time"
+
+	"github.com/currantlabs/ble/linux/hci/cmd"
+)
+
+// Signal ...
+type Signal interface {
+	Code() int
+	Marshal() []byte
+	Unmarshal([]byte) error
+}
+
+type sigCmd []byte
+
+func (s sigCmd) code() int    { return int(s[0]) }
+func (s sigCmd) id() uint8    { return s[1] }
+func (s sigCmd) len() int     { return int(binary.LittleEndian.Uint16(s[2:4])) }
+func (s sigCmd) data() []byte { return s[4 : 4+s.len()] }
+
+// Signal ...
+func (c *Conn) Signal(req Signal, rsp Signal) error {
+	data := req.Marshal()
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, uint16(4+len(data)))
+	binary.Write(buf, binary.LittleEndian, uint16(cidLESignal))
+
+	binary.Write(buf, binary.LittleEndian, uint8(req.Code()))
+	binary.Write(buf, binary.LittleEndian, uint8(c.sigID))
+	binary.Write(buf, binary.LittleEndian, uint16(len(data)))
+	binary.Write(buf, binary.LittleEndian, data)
+
+	c.sigSent = make(chan []byte)
+	defer close(c.sigSent)
+	if _, err := c.writePDU(buf.Bytes()); err != nil {
+		return err
+	}
+	var s sigCmd
+	select {
+	case s = <-c.sigSent:
+	case <-time.After(time.Second):
+		// TODO: Find the proper timed out defined in spec, if any.
+		return errors.New("signaling request timed out")
+	}
+
+	if s.code() != req.Code() {
+		return errors.New("mismatched signaling response")
+	}
+	if s.id() != c.sigID {
+		return errors.New("mismatched signaling id")
+	}
+	c.sigID++
+	if rsp == nil {
+		return nil
+	}
+	return rsp.Unmarshal(s.data())
+}
+
+func (c *Conn) sendResponse(code uint8, id uint8, r Signal) (int, error) {
+	data := r.Marshal()
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, uint16(4+len(data)))
+	binary.Write(buf, binary.LittleEndian, uint16(cidLESignal))
+	binary.Write(buf, binary.LittleEndian, uint8(code))
+	binary.Write(buf, binary.LittleEndian, uint8(id))
+	binary.Write(buf, binary.LittleEndian, uint16(len(data)))
+	if err := binary.Write(buf, binary.LittleEndian, data); err != nil {
+		return 0, err
+	}
+	logger.Debug("sig", "send", fmt.Sprintf("[%X]", buf.Bytes()))
+	return c.writePDU(buf.Bytes())
+}
+
+func (c *Conn) handleSignal(p pdu) error {
+	logger.Debug("sig", "recv", fmt.Sprintf("[%X]", p))
+	// When multiple commands are included in an L2CAP packet and the packet
+	// exceeds the signaling MTU (MTUsig) of the receiver, a single Command Reject
+	// packet shall be sent in response. The identifier shall match the first Request
+	// command in the L2CAP packet. If only Responses are recognized, the packet
+	// shall be silently discarded. [Vol3, Part A, 4.1]
+	if p.dlen() > c.sigRxMTU {
+		c.sendResponse(
+			SignalCommandReject,
+			sigCmd(p.payload()).id(),
+			&CommandReject{
+				Reason: 0x0001,                                            // Signaling MTU exceeded.
+				Data:   []byte{uint8(c.sigRxMTU), uint8(c.sigRxMTU >> 8)}, // Actual MTUsig.
+			})
+		return nil
+	}
+
+	s := sigCmd(p.payload())
+	for len(s) > 0 {
+		// Check if it's a supported request.
+		switch s.code() {
+		case SignalDisconnectRequest:
+			c.handleDisconnectRequest(s)
+		case SignalConnectionParameterUpdateRequest:
+			c.handleConnectionParameterUpdateRequest(s)
+		case SignalLECreditBasedConnectionRequest:
+			c.LECreditBasedConnectionRequest(s)
+		case SignalLEFlowControlCredit:
+			c.LEFlowControlCredit(s)
+		default:
+			// Check if it's a response to a sent command.
+			select {
+			case c.sigSent <- s:
+				continue
+			default:
+			}
+
+			c.sendResponse(
+				SignalCommandReject,
+				s.id(),
+				&CommandReject{
+					Reason: 0x0000, // Command not understood.
+				})
+		}
+		s = s[4+s.len():] // advance to next the packet.
+
+	}
+	return nil
+}
+
+// DisconnectRequest implements Disconnect Request (0x06) [Vol 3, Part A, 4.6].
+func (c *Conn) handleDisconnectRequest(s sigCmd) {
+	var req DisconnectRequest
+	if err := req.Unmarshal(s.data()); err != nil {
+		return
+	}
+
+	// Send Command Reject when the DCID is unrecognized.
+	if req.DestinationCID != cidLEAtt {
+		endpoints := make([]byte, 4)
+		binary.LittleEndian.PutUint16(endpoints, req.SourceCID)
+		binary.LittleEndian.PutUint16(endpoints, req.DestinationCID)
+		c.sendResponse(
+			SignalCommandReject,
+			s.id(),
+			&CommandReject{
+				Reason: 0x0002, // Invalid CID in request
+				Data:   endpoints,
+			})
+		return
+	}
+
+	// Silently discard the request if SCID failed to find the same match.
+	if req.SourceCID != cidLEAtt {
+		return
+	}
+
+	c.sendResponse(
+		SignalDisconnectResponse,
+		s.id(),
+		&DisconnectResponse{
+			DestinationCID: req.DestinationCID,
+			SourceCID:      req.SourceCID,
+		})
+}
+
+// ConnectionParameterUpdateRequest implements Connection Parameter Update Request (0x12) [Vol 3, Part A, 4.20].
+func (c *Conn) handleConnectionParameterUpdateRequest(s sigCmd) {
+	// This command shall only be sent from the LE slave device to the LE master
+	// device and only if one or more of the LE slave Controller, the LE master
+	// Controller, the LE slave Host and the LE master Host do not support the
+	// Connection Parameters Request Link Layer Control Procedure ([Vol. 6] Part B,
+	// Section 5.1.7). If an LE slave Host receives a Connection Parameter Update
+	// Request packet it shall respond with a Command Reject packet with reason
+	// 0x0000 (Command not understood).
+	if c.param.Role() != roleMaster {
+		c.sendResponse(
+			SignalCommandReject,
+			s.id(),
+			&CommandReject{
+				Reason: 0x0000, // Command not understood.
+			})
+
+		return
+	}
+	var req ConnectionParameterUpdateRequest
+	if err := req.Unmarshal(s.data()); err != nil {
+		return
+	}
+
+	// LE Connection Update (0x08|0x0013) [Vol 2, Part E, 7.8.18]
+	c.hci.Send(&cmd.LEConnectionUpdate{
+		ConnectionHandle:   c.param.ConnectionHandle(),
+		ConnIntervalMin:    req.IntervalMin,
+		ConnIntervalMax:    req.IntervalMax,
+		ConnLatency:        req.SlaveLatency,
+		SupervisionTimeout: req.TimeoutMultiplier,
+		MinimumCELength:    0, // Informational, and spec doesn't specify the use.
+		MaximumCELength:    0, // Informational, and spec doesn't specify the use.
+	}, nil)
+
+	// Currently, we (as a slave host) accept all the parameters and forward
+	// it to the controller. The controller might update all, partial or even
+	// none (ignore) of the parameters. The slave(remote) host will be indicated
+	// by its controller if the update actually happens.
+	// TODO: allow users to implement what parameters to accept.
+	c.sendResponse(
+		SignalConnectionParameterUpdateResponse,
+		s.id(),
+		&ConnectionParameterUpdateResponse{
+			Result: 0, // Accept.
+		})
+}
+
+// LECreditBasedConnectionRequest ...
+func (c *Conn) LECreditBasedConnectionRequest(s sigCmd) {
+	// TODO:
+}
+
+// LEFlowControlCredit ...
+func (c *Conn) LEFlowControlCredit(s sigCmd) {
+	// TODO:
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/signal_gen.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/signal_gen.go
new file mode 100644
index 0000000..6f2d988
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/signal_gen.go
@@ -0,0 +1,205 @@
+package hci
+
+import (
+	"bytes"
+	"encoding/binary"
+)
+
+// SignalCommandReject is the code of Command Reject signaling packet.
+const SignalCommandReject = 0x01
+
+// CommandReject implements Command Reject (0x01) [Vol 3, Part A, 4.1].
+type CommandReject struct {
+	Reason uint16
+	Data   []byte
+}
+
+// Code returns the event code of the command.
+func (s CommandReject) Code() int { return 0x01 }
+
+// Marshal serializes the command parameters into binary form.
+func (s *CommandReject) Marshal() []byte {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, s)
+	return buf.Bytes()
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (s *CommandReject) Unmarshal(b []byte) error {
+	return binary.Read(bytes.NewBuffer(b), binary.LittleEndian, s)
+}
+
+// SignalDisconnectRequest is the code of Disconnect Request signaling packet.
+const SignalDisconnectRequest = 0x06
+
+// DisconnectRequest implements Disconnect Request (0x06) [Vol 3, Part A, 4.6].
+type DisconnectRequest struct {
+	DestinationCID uint16
+	SourceCID      uint16
+}
+
+// Code returns the event code of the command.
+func (s DisconnectRequest) Code() int { return 0x06 }
+
+// Marshal serializes the command parameters into binary form.
+func (s *DisconnectRequest) Marshal() []byte {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, s)
+	return buf.Bytes()
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (s *DisconnectRequest) Unmarshal(b []byte) error {
+	return binary.Read(bytes.NewBuffer(b), binary.LittleEndian, s)
+}
+
+// SignalDisconnectResponse is the code of Disconnect Response signaling packet.
+const SignalDisconnectResponse = 0x07
+
+// DisconnectResponse implements Disconnect Response (0x07) [Vol 3, Part A, 4.7].
+type DisconnectResponse struct {
+	DestinationCID uint16
+	SourceCID      uint16
+}
+
+// Code returns the event code of the command.
+func (s DisconnectResponse) Code() int { return 0x07 }
+
+// Marshal serializes the command parameters into binary form.
+func (s *DisconnectResponse) Marshal() []byte {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, s)
+	return buf.Bytes()
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (s *DisconnectResponse) Unmarshal(b []byte) error {
+	return binary.Read(bytes.NewBuffer(b), binary.LittleEndian, s)
+}
+
+// SignalConnectionParameterUpdateRequest is the code of Connection Parameter Update Request signaling packet.
+const SignalConnectionParameterUpdateRequest = 0x12
+
+// ConnectionParameterUpdateRequest implements Connection Parameter Update Request (0x12) [Vol 3, Part A, 4.20].
+type ConnectionParameterUpdateRequest struct {
+	IntervalMin       uint16
+	IntervalMax       uint16
+	SlaveLatency      uint16
+	TimeoutMultiplier uint16
+}
+
+// Code returns the event code of the command.
+func (s ConnectionParameterUpdateRequest) Code() int { return 0x12 }
+
+// Marshal serializes the command parameters into binary form.
+func (s *ConnectionParameterUpdateRequest) Marshal() []byte {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, s)
+	return buf.Bytes()
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (s *ConnectionParameterUpdateRequest) Unmarshal(b []byte) error {
+	return binary.Read(bytes.NewBuffer(b), binary.LittleEndian, s)
+}
+
+// SignalConnectionParameterUpdateResponse is the code of Connection Parameter Update Response signaling packet.
+const SignalConnectionParameterUpdateResponse = 0x13
+
+// ConnectionParameterUpdateResponse implements Connection Parameter Update Response (0x13) [Vol 3, Part A, 4.21].
+type ConnectionParameterUpdateResponse struct {
+	Result uint16
+}
+
+// Code returns the event code of the command.
+func (s ConnectionParameterUpdateResponse) Code() int { return 0x13 }
+
+// Marshal serializes the command parameters into binary form.
+func (s *ConnectionParameterUpdateResponse) Marshal() []byte {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, s)
+	return buf.Bytes()
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (s *ConnectionParameterUpdateResponse) Unmarshal(b []byte) error {
+	return binary.Read(bytes.NewBuffer(b), binary.LittleEndian, s)
+}
+
+// SignalLECreditBasedConnectionRequest is the code of LE Credit Based Connection Request signaling packet.
+const SignalLECreditBasedConnectionRequest = 0x14
+
+// LECreditBasedConnectionRequest implements LE Credit Based Connection Request (0x14) [Vol 3, Part A, 4.22].
+type LECreditBasedConnectionRequest struct {
+	LEPSM          uint16
+	SourceCID      uint16
+	MTU            uint16
+	MPS            uint16
+	InitialCredits uint16
+}
+
+// Code returns the event code of the command.
+func (s LECreditBasedConnectionRequest) Code() int { return 0x14 }
+
+// Marshal serializes the command parameters into binary form.
+func (s *LECreditBasedConnectionRequest) Marshal() []byte {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, s)
+	return buf.Bytes()
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (s *LECreditBasedConnectionRequest) Unmarshal(b []byte) error {
+	return binary.Read(bytes.NewBuffer(b), binary.LittleEndian, s)
+}
+
+// SignalLECreditBasedConnectionResponse is the code of LE Credit Based Connection Response signaling packet.
+const SignalLECreditBasedConnectionResponse = 0x15
+
+// LECreditBasedConnectionResponse implements LE Credit Based Connection Response (0x15) [Vol 3, Part A, 4.23].
+type LECreditBasedConnectionResponse struct {
+	DestinationCID    uint16
+	MTU               uint16
+	MPS               uint16
+	InitialCreditsCID uint16
+	Result            uint16
+}
+
+// Code returns the event code of the command.
+func (s LECreditBasedConnectionResponse) Code() int { return 0x15 }
+
+// Marshal serializes the command parameters into binary form.
+func (s *LECreditBasedConnectionResponse) Marshal() []byte {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, s)
+	return buf.Bytes()
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (s *LECreditBasedConnectionResponse) Unmarshal(b []byte) error {
+	return binary.Read(bytes.NewBuffer(b), binary.LittleEndian, s)
+}
+
+// SignalLEFlowControlCredit is the code of LE Flow Control Credit signaling packet.
+const SignalLEFlowControlCredit = 0x16
+
+// LEFlowControlCredit implements LE Flow Control Credit (0x16) [Vol 3, Part A, 4.24].
+type LEFlowControlCredit struct {
+	CID     uint16
+	Credits uint16
+}
+
+// Code returns the event code of the command.
+func (s LEFlowControlCredit) Code() int { return 0x16 }
+
+// Marshal serializes the command parameters into binary form.
+func (s *LEFlowControlCredit) Marshal() []byte {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, s)
+	return buf.Bytes()
+}
+
+// Unmarshal de-serializes the binary data and stores the result in the receiver.
+func (s *LEFlowControlCredit) Unmarshal(b []byte) error {
+	return binary.Read(bytes.NewBuffer(b), binary.LittleEndian, s)
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/smp.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/smp.go
new file mode 100644
index 0000000..87a43f8
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/smp.go
@@ -0,0 +1,61 @@
+package hci
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+)
+
+const (
+	pairingRequest           = 0x01 // Pairing Request LE-U, ACL-U
+	pairingResponse          = 0x02 // Pairing Response LE-U, ACL-U
+	pairingConfirm           = 0x03 // Pairing Confirm LE-U
+	pairingRandom            = 0x04 // Pairing Random LE-U
+	pairingFailed            = 0x05 // Pairing Failed LE-U, ACL-U
+	encryptionInformation    = 0x06 // Encryption Information LE-U
+	masterIdentification     = 0x07 // Master Identification LE-U
+	identiInformation        = 0x08 // Identity Information LE-U, ACL-U
+	identityAddreInformation = 0x09 // Identity Address Information LE-U, ACL-U
+	signingInformation       = 0x0A // Signing Information LE-U, ACL-U
+	securityRequest          = 0x0B // Security Request LE-U
+	pairingPublicKey         = 0x0C // Pairing Public Key LE-U
+	pairingDHKeyCheck        = 0x0D // Pairing DHKey Check LE-U
+	pairingKeypress          = 0x0E // Pairing Keypress Notification LE-U
+)
+
+func (c *Conn) sendSMP(p pdu) error {
+	buf := bytes.NewBuffer(make([]byte, 0))
+	binary.Write(buf, binary.LittleEndian, uint16(4+len(p)))
+	binary.Write(buf, binary.LittleEndian, cidSMP)
+	binary.Write(buf, binary.LittleEndian, p)
+	_, err := c.writePDU(buf.Bytes())
+	logger.Debug("smp", "send", fmt.Sprintf("[%X]", buf.Bytes()))
+	return err
+}
+
+func (c *Conn) handleSMP(p pdu) error {
+	logger.Debug("smp", "recv", fmt.Sprintf("[%X]", p))
+	code := p[0]
+	switch code {
+	case pairingRequest:
+	case pairingResponse:
+	case pairingConfirm:
+	case pairingRandom:
+	case pairingFailed:
+	case encryptionInformation:
+	case masterIdentification:
+	case identiInformation:
+	case identityAddreInformation:
+	case signingInformation:
+	case securityRequest:
+	case pairingPublicKey:
+	case pairingDHKeyCheck:
+	case pairingKeypress:
+	default:
+		// If a packet is received with a reserved Code it shall be ignored. [Vol 3, Part H, 3.3]
+		return nil
+	}
+	// FIXME: work aound to the lack of SMP implementation - always return non-supported.
+	// C.5.1 Pairing Not Supported by Slave
+	return c.sendSMP([]byte{pairingFailed, 0x05})
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/socket/dummy.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/socket/dummy.go
new file mode 100644
index 0000000..6062008
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/socket/dummy.go
@@ -0,0 +1,10 @@
+// +build !linux
+
+package socket
+
+import "io"
+
+// NewSocket is a dummy function for non-Linux platform.
+func NewSocket(id int) (io.ReadWriteCloser, error) {
+	return nil, nil
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/socket/socket.go b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/socket/socket.go
new file mode 100644
index 0000000..312f600
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/linux/hci/socket/socket.go
@@ -0,0 +1,146 @@
+// +build linux
+
+package socket
+
+import (
+	"fmt"
+	"io"
+	"sync"
+	"unsafe"
+
+	"github.com/pkg/errors"
+	"golang.org/x/sys/unix"
+)
+
+func ioR(t, nr, size uintptr) uintptr {
+	return (2 << 30) | (t << 8) | nr | (size << 16)
+}
+
+func ioW(t, nr, size uintptr) uintptr {
+	return (1 << 30) | (t << 8) | nr | (size << 16)
+}
+
+func ioctl(fd, op, arg uintptr) error {
+	if _, _, ep := unix.Syscall(unix.SYS_IOCTL, fd, op, arg); ep != 0 {
+		return ep
+	}
+	return nil
+}
+
+const (
+	ioctlSize     = 4
+	hciMaxDevices = 16
+	typHCI        = 72 // 'H'
+)
+
+var (
+	hciUpDevice      = ioW(typHCI, 201, ioctlSize) // HCIDEVUP
+	hciDownDevice    = ioW(typHCI, 202, ioctlSize) // HCIDEVDOWN
+	hciResetDevice   = ioW(typHCI, 203, ioctlSize) // HCIDEVRESET
+	hciGetDeviceList = ioR(typHCI, 210, ioctlSize) // HCIGETDEVLIST
+	hciGetDeviceInfo = ioR(typHCI, 211, ioctlSize) // HCIGETDEVINFO
+)
+
+type devListRequest struct {
+	devNum     uint16
+	devRequest [hciMaxDevices]struct {
+		id  uint16
+		opt uint32
+	}
+}
+
+// Socket implements a HCI User Channel as ReadWriteCloser.
+type Socket struct {
+	fd     int
+	closed chan struct{}
+	rmu    sync.Mutex
+	wmu    sync.Mutex
+}
+
+// NewSocket returns a HCI User Channel of specified device id.
+// If id is -1, the first available HCI device is returned.
+func NewSocket(id int) (*Socket, error) {
+	var err error
+	// Create RAW HCI Socket.
+	fd, err := unix.Socket(unix.AF_BLUETOOTH, unix.SOCK_RAW, unix.BTPROTO_HCI)
+	if err != nil {
+		return nil, errors.Wrap(err, "can't create socket")
+	}
+
+	if id != -1 {
+		return open(fd, id)
+	}
+
+	req := devListRequest{devNum: hciMaxDevices}
+	if err = ioctl(uintptr(fd), hciGetDeviceList, uintptr(unsafe.Pointer(&req))); err != nil {
+		return nil, errors.Wrap(err, "can't get device list")
+	}
+	var msg string
+	for id := 0; id < int(req.devNum); id++ {
+		s, err := open(fd, id)
+		if err == nil {
+			return s, nil
+		}
+		msg = msg + fmt.Sprintf("(hci%d: %s)", id, err)
+	}
+	return nil, errors.Errorf("no devices available: %s", msg)
+}
+
+func open(fd, id int) (*Socket, error) {
+	// Reset the device in case previous session didn't cleanup properly.
+	if err := ioctl(uintptr(fd), hciDownDevice, uintptr(id)); err != nil {
+		return nil, errors.Wrap(err, "can't down device")
+	}
+	if err := ioctl(uintptr(fd), hciUpDevice, uintptr(id)); err != nil {
+		return nil, errors.Wrap(err, "can't up device")
+	}
+
+	// HCI User Channel requires exclusive access to the device.
+	// The device has to be down at the time of binding.
+	if err := ioctl(uintptr(fd), hciDownDevice, uintptr(id)); err != nil {
+		return nil, errors.Wrap(err, "can't down device")
+	}
+
+	// Bind the RAW socket to HCI User Channel
+	sa := unix.SockaddrHCI{Dev: uint16(id), Channel: unix.HCI_CHANNEL_USER}
+	if err := unix.Bind(fd, &sa); err != nil {
+		return nil, errors.Wrap(err, "can't bind socket to hci user channel")
+	}
+
+	// poll for 20ms to see if any data becomes available, then clear it
+	pfds := []unix.PollFd{unix.PollFd{Fd: int32(fd), Events: unix.POLLIN}}
+	unix.Poll(pfds, 20)
+	if pfds[0].Revents&unix.POLLIN > 0 {
+		b := make([]byte, 100)
+		unix.Read(fd, b)
+	}
+
+	return &Socket{fd: fd, closed: make(chan struct{})}, nil
+}
+
+func (s *Socket) Read(p []byte) (int, error) {
+	select {
+	case <-s.closed:
+		return 0, io.EOF
+	default:
+	}
+	s.rmu.Lock()
+	defer s.rmu.Unlock()
+	n, err := unix.Read(s.fd, p)
+	return n, errors.Wrap(err, "can't read hci socket")
+}
+
+func (s *Socket) Write(p []byte) (int, error) {
+	s.wmu.Lock()
+	defer s.wmu.Unlock()
+	n, err := unix.Write(s.fd, p)
+	return n, errors.Wrap(err, "can't write hci socket")
+}
+
+func (s *Socket) Close() error {
+	close(s.closed)
+	s.Write([]byte{0x01, 0x09, 0x10, 0x00})
+	s.rmu.Lock()
+	defer s.rmu.Unlock()
+	return errors.Wrap(unix.Close(s.fd), "can't close hci socket")
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/profile.go b/newtmgr/vendor/github.com/currantlabs/ble/profile.go
new file mode 100644
index 0000000..a59772d
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/profile.go
@@ -0,0 +1,221 @@
+package ble
+
+// NewService creates and initialize a new Service using u as it's UUID.
+func NewService(u UUID) *Service {
+	return &Service{UUID: u}
+}
+
+// NewDescriptor creates and returns a Descriptor.
+func NewDescriptor(u UUID) *Descriptor {
+	return &Descriptor{UUID: u}
+}
+
+// NewCharacteristic creates and returns a Characteristic.
+func NewCharacteristic(u UUID) *Characteristic {
+	return &Characteristic{UUID: u}
+}
+
+// Property ...
+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
+)
+
+// A Profile is composed of one or more services necessary to fulfill a use case.
+type Profile struct {
+	Services []*Service
+}
+
+// Find searches discovered profile for the specified target's type and UUID.
+// The target must has the type of *Service, *Characteristic, or *Descriptor.
+func (p *Profile) Find(target interface{}) interface{} {
+	switch target.(type) {
+	case *Service:
+	case *Characteristic:
+	case *Descriptor:
+	default:
+		return nil
+	}
+	for _, s := range p.Services {
+		ts, ok := target.(*Service)
+		if ok && s.UUID.Equal(ts.UUID) {
+			target = s
+			return s
+		}
+		for _, c := range s.Characteristics {
+			tc, ok := target.(*Characteristic)
+			if ok && c.UUID.Equal(tc.UUID) {
+				return c
+			}
+			for _, d := range c.Descriptors {
+				td, ok := target.(*Descriptor)
+				if ok && d.UUID.Equal(td.UUID) {
+					return d
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// A Service is a BLE service.
+type Service struct {
+	UUID            UUID
+	Characteristics []*Characteristic
+
+	Handle    uint16
+	EndHandle uint16
+}
+
+// AddCharacteristic adds a characteristic to a service.
+// AddCharacteristic panics if the service already contains another characteristic with the same UUID.
+func (s *Service) AddCharacteristic(c *Characteristic) *Characteristic {
+	for _, x := range s.Characteristics {
+		if x.UUID.Equal(c.UUID) {
+			panic("service already contains a characteristic with UUID " + c.UUID.String())
+		}
+	}
+	s.Characteristics = append(s.Characteristics, c)
+	return c
+}
+
+// NewCharacteristic adds a characteristic to a service.
+// NewCharacteristic panics if the service already contains another characteristic with the same UUID.
+func (s *Service) NewCharacteristic(u UUID) *Characteristic {
+	return s.AddCharacteristic(&Characteristic{UUID: u})
+}
+
+// A Characteristic is a BLE characteristic.
+type Characteristic struct {
+	UUID        UUID
+	Property    Property
+	Secure      Property // FIXME
+	Descriptors []*Descriptor
+	CCCD        *Descriptor
+
+	Value []byte
+
+	ReadHandler     ReadHandler
+	WriteHandler    WriteHandler
+	NotifyHandler   NotifyHandler
+	IndicateHandler NotifyHandler
+
+	Handle      uint16
+	ValueHandle uint16
+	EndHandle   uint16
+}
+
+// AddDescriptor adds a descriptor to a characteristic.
+// AddDescriptor panics if the characteristic already contains another descriptor with the same UUID.
+func (c *Characteristic) AddDescriptor(d *Descriptor) *Descriptor {
+	for _, x := range c.Descriptors {
+		if x.UUID.Equal(d.UUID) {
+			panic("service already contains a characteristic with UUID " + d.UUID.String())
+		}
+	}
+	c.Descriptors = append(c.Descriptors, d)
+	return d
+}
+
+// NewDescriptor adds a descriptor to a characteristic.
+// NewDescriptor panics if the characteristic already contains another descriptor with the same UUID.
+func (c *Characteristic) NewDescriptor(u UUID) *Descriptor {
+	return c.AddDescriptor(&Descriptor{UUID: u})
+}
+
+// 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.ReadHandler != nil {
+		panic("charactristic has been configured with a read handler")
+	}
+	c.Property |= 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.Property |= CharRead
+	c.ReadHandler = h
+}
+
+// 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.Property |= CharWrite | CharWriteNR
+	c.WriteHandler = h
+}
+
+// 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) {
+	c.Property |= CharNotify
+	c.NotifyHandler = h
+}
+
+// HandleIndicate makes the characteristic support indicate requests, and routes notification requests to h.
+// HandleIndicate must be called before the containing service is added to a server.
+func (c *Characteristic) HandleIndicate(h NotifyHandler) {
+	c.Property |= CharIndicate
+	c.IndicateHandler = h
+}
+
+// Descriptor is a BLE descriptor
+type Descriptor struct {
+	UUID     UUID
+	Property Property
+
+	Handle uint16
+	Value  []byte
+
+	ReadHandler  ReadHandler
+	WriteHandler WriteHandler
+}
+
+// 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.ReadHandler != nil {
+		panic("descriptor has been configured with a read handler")
+	}
+	d.Property |= 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.Property |= CharRead
+	d.ReadHandler = h
+}
+
+// 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.Property |= CharWrite | CharWriteNR
+	d.WriteHandler = h
+}
diff --git a/newtmgr/vendor/github.com/currantlabs/ble/uuid.go b/newtmgr/vendor/github.com/currantlabs/ble/uuid.go
new file mode 100644
index 0000000..79ebf33
--- /dev/null
+++ b/newtmgr/vendor/github.com/currantlabs/ble/uuid.go
@@ -0,0 +1,217 @@
+package ble
+
+import (
+	"bytes"
+	"encoding/binary"
+	"encoding/hex"
+	"fmt"
+	"strings"
+)
+
+// A UUID is a BLE UUID.
+type UUID []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)
+}
+
+// Parse parses a standard-format UUID string, such
+// as "1800" or "34DA3AD1-7110-41A1-B1EF-4430F509CDE7".
+func Parse(s string) (UUID, error) {
+	s = strings.Replace(s, "-", "", -1)
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		return nil, err
+	}
+	if err := lenErr(len(b)); err != nil {
+		return nil, err
+	}
+	return UUID(Reverse(b)), nil
+}
+
+// MustParse parses a standard-format UUID string,
+// like Parse, but panics in case of error.
+func MustParse(s string) UUID {
+	u, err := Parse(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)
+}
+
+// String hex-encodes a UUID.
+func (u UUID) String() string {
+	return fmt.Sprintf("%x", Reverse(u))
+}
+
+// Equal returns a boolean reporting whether v represent the same UUID as u.
+func (u UUID) Equal(v UUID) bool {
+	return bytes.Equal(u, v)
+}
+
+// Contains returns a boolean reporting whether u is in the slice s.
+func Contains(s []UUID, u UUID) bool {
+	if s == nil {
+		return true
+	}
+
+	for _, a := range s {
+		if a.Equal(u) {
+			return true
+		}
+	}
+
+	return false
+}
+
+// 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
+}
+
+// Name returns name of know services, characteristics, or descriptors.
+func Name(u UUID) string {
+	return knownUUID[u.String()].Name
+}
+
+// A dictionary of known service names and type (keyed by service uuid)
+var knownUUID = map[string]struct{ Name, Type string }{
+	"1800": {Name: "Generic Access", Type: "org.bluetooth.service.generic_access"},
+	"1801": {Name: "Generic Attribute", Type: "org.bluetooth.service.generic_attribute"},
+	"1802": {Name: "Immediate Alert", Type: "org.bluetooth.service.immediate_alert"},
+	"1803": {Name: "Link Loss", Type: "org.bluetooth.service.link_loss"},
+	"1804": {Name: "Tx Power", Type: "org.bluetooth.service.tx_power"},
+	"1805": {Name: "Current Time Service", Type: "org.bluetooth.service.current_time"},
+	"1806": {Name: "Reference Time Update Service", Type: "org.bluetooth.service.reference_time_update"},
+	"1807": {Name: "Next DST Change Service", Type: "org.bluetooth.service.next_dst_change"},
+	"1808": {Name: "Glucose", Type: "org.bluetooth.service.glucose"},
+	"1809": {Name: "Health Thermometer", Type: "org.bluetooth.service.health_thermometer"},
+	"180a": {Name: "Device Information", Type: "org.bluetooth.service.device_information"},
+	"180d": {Name: "Heart Rate", Type: "org.bluetooth.service.heart_rate"},
+	"180e": {Name: "Phone Alert Status Service", Type: "org.bluetooth.service.phone_alert_service"},
+	"180f": {Name: "Battery Service", Type: "org.bluetooth.service.battery_service"},
+	"1810": {Name: "Blood Pressure", Type: "org.bluetooth.service.blood_pressuer"},
+	"1811": {Name: "Alert Notification Service", Type: "org.bluetooth.service.alert_notification"},
+	"1812": {Name: "Human Interface Device", Type: "org.bluetooth.service.human_interface_device"},
+	"1813": {Name: "Scan Parameters", Type: "org.bluetooth.service.scan_parameters"},
+	"1814": {Name: "Running Speed and Cadence", Type: "org.bluetooth.service.running_speed_and_cadence"},
+	"1815": {Name: "Cycling Speed and Cadence", Type: "org.bluetooth.service.cycling_speed_and_cadence"},
+
+	// A dictionary of known descriptor names and type (keyed by attribute uuid)
+	"2800": {Name: "Primary Service", Type: "org.bluetooth.attribute.gatt.primary_service_declaration"},
+	"2801": {Name: "Secondary Service", Type: "org.bluetooth.attribute.gatt.secondary_service_declaration"},
+	"2802": {Name: "Include", Type: "org.bluetooth.attribute.gatt.include_declaration"},
+	"2803": {Name: "Characteristic", Type: "org.bluetooth.attribute.gatt.characteristic_declaration"},
+
+	// A dictionary of known descriptor names and type (keyed by descriptor uuid)
+	"2900": {Name: "Characteristic Extended Properties", Type: "org.bluetooth.descriptor.gatt.characteristic_extended_properties"},
+	"2901": {Name: "Characteristic User Description", Type: "org.bluetooth.descriptor.gatt.characteristic_user_description"},
+	"2902": {Name: "Client Characteristic Configuration", Type: "org.bluetooth.descriptor.gatt.client_characteristic_configuration"},
+	"2903": {Name: "Server Characteristic Configuration", Type: "org.bluetooth.descriptor.gatt.server_characteristic_configuration"},
+	"2904": {Name: "Characteristic Presentation Format", Type: "org.bluetooth.descriptor.gatt.characteristic_presentation_format"},
+	"2905": {Name: "Characteristic Aggregate Format", Type: "org.bluetooth.descriptor.gatt.characteristic_aggregate_format"},
+	"2906": {Name: "Valid Range", Type: "org.bluetooth.descriptor.valid_range"},
+	"2907": {Name: "External Report Reference", Type: "org.bluetooth.descriptor.external_report_reference"},
+	"2908": {Name: "Report Reference", Type: "org.bluetooth.descriptor.report_reference"},
+
+	// A dictionary of known characteristic names and type (keyed by characteristic uuid)
+	"2a00": {Name: "Device Name", Type: "org.bluetooth.characteristic.ble.device_name"},
+	"2a01": {Name: "Appearance", Type: "org.bluetooth.characteristic.ble.appearance"},
+	"2a02": {Name: "Peripheral Privacy Flag", Type: "org.bluetooth.characteristic.ble.peripheral_privacy_flag"},
+	"2a03": {Name: "Reconnection Address", Type: "org.bluetooth.characteristic.ble.reconnection_address"},
+	"2a04": {Name: "Peripheral Preferred Connection Parameters", Type: "org.bluetooth.characteristic.ble.peripheral_preferred_connection_parameters"},
+	"2a05": {Name: "Service Changed", Type: "org.bluetooth.characteristic.gatt.service_changed"},
+	"2a06": {Name: "Alert Level", Type: "org.bluetooth.characteristic.alert_level"},
+	"2a07": {Name: "Tx Power Level", Type: "org.bluetooth.characteristic.tx_power_level"},
+	"2a08": {Name: "Date Time", Type: "org.bluetooth.characteristic.date_time"},
+	"2a09": {Name: "Day of Week", Type: "org.bluetooth.characteristic.day_of_week"},
+	"2a0a": {Name: "Day Date Time", Type: "org.bluetooth.characteristic.day_date_time"},
+	"2a0c": {Name: "Exact Time 256", Type: "org.bluetooth.characteristic.exact_time_256"},
+	"2a0d": {Name: "DST Offset", Type: "org.bluetooth.characteristic.dst_offset"},
+	"2a0e": {Name: "Time Zone", Type: "org.bluetooth.characteristic.time_zone"},
+	"2a0f": {Name: "Local Time Information", Type: "org.bluetooth.characteristic.local_time_information"},
+	"2a11": {Name: "Time with DST", Type: "org.bluetooth.characteristic.time_with_dst"},
+	"2a12": {Name: "Time Accuracy", Type: "org.bluetooth.characteristic.time_accuracy"},
+	"2a13": {Name: "Time Source", Type: "org.bluetooth.characteristic.time_source"},
+	"2a14": {Name: "Reference Time Information", Type: "org.bluetooth.characteristic.reference_time_information"},
+	"2a16": {Name: "Time Update Control Point", Type: "org.bluetooth.characteristic.time_update_control_point"},
+	"2a17": {Name: "Time Update State", Type: "org.bluetooth.characteristic.time_update_state"},
+	"2a18": {Name: "Glucose Measurement", Type: "org.bluetooth.characteristic.glucose_measurement"},
+	"2a19": {Name: "Battery Level", Type: "org.bluetooth.characteristic.battery_level"},
+	"2a1c": {Name: "Temperature Measurement", Type: "org.bluetooth.characteristic.temperature_measurement"},
+	"2a1d": {Name: "Temperature Type", Type: "org.bluetooth.characteristic.temperature_type"},
+	"2a1e": {Name: "Intermediate Temperature", Type: "org.bluetooth.characteristic.intermediate_temperature"},
+	"2a21": {Name: "Measurement Interval", Type: "org.bluetooth.characteristic.measurement_interval"},
+	"2a22": {Name: "Boot Keyboard Input Report", Type: "org.bluetooth.characteristic.boot_keyboard_input_report"},
+	"2a23": {Name: "System ID", Type: "org.bluetooth.characteristic.system_id"},
+	"2a24": {Name: "Model Number String", Type: "org.bluetooth.characteristic.model_number_string"},
+	"2a25": {Name: "Serial Number String", Type: "org.bluetooth.characteristic.serial_number_string"},
+	"2a26": {Name: "Firmware Revision String", Type: "org.bluetooth.characteristic.firmware_revision_string"},
+	"2a27": {Name: "Hardware Revision String", Type: "org.bluetooth.characteristic.hardware_revision_string"},
+	"2a28": {Name: "Software Revision String", Type: "org.bluetooth.characteristic.software_revision_string"},
+	"2a29": {Name: "Manufacturer Name String", Type: "org.bluetooth.characteristic.manufacturer_name_string"},
+	"2a2a": {Name: "IEEE 11073-20601 Regulatory Certification Data List", Type: "org.bluetooth.characteristic.ieee_11073-20601_regulatory_certification_data_list"},
+	"2a2b": {Name: "Current Time", Type: "org.bluetooth.characteristic.current_time"},
+	"2a31": {Name: "Scan Refresh", Type: "org.bluetooth.characteristic.scan_refresh"},
+	"2a32": {Name: "Boot Keyboard Output Report", Type: "org.bluetooth.characteristic.boot_keyboard_output_report"},
+	"2a33": {Name: "Boot Mouse Input Report", Type: "org.bluetooth.characteristic.boot_mouse_input_report"},
+	"2a34": {Name: "Glucose Measurement Context", Type: "org.bluetooth.characteristic.glucose_measurement_context"},
+	"2a35": {Name: "Blood Pressure Measurement", Type: "org.bluetooth.characteristic.blood_pressure_measurement"},
+	"2a36": {Name: "Intermediate Cuff Pressure", Type: "org.bluetooth.characteristic.intermediate_blood_pressure"},
+	"2a37": {Name: "Heart Rate Measurement", Type: "org.bluetooth.characteristic.heart_rate_measurement"},
+	"2a38": {Name: "Body Sensor Location", Type: "org.bluetooth.characteristic.body_sensor_location"},
+	"2a39": {Name: "Heart Rate Control Point", Type: "org.bluetooth.characteristic.heart_rate_control_point"},
+	"2a3f": {Name: "Alert Status", Type: "org.bluetooth.characteristic.alert_status"},
+	"2a40": {Name: "Ringer Control Point", Type: "org.bluetooth.characteristic.ringer_control_point"},
+	"2a41": {Name: "Ringer Setting", Type: "org.bluetooth.characteristic.ringer_setting"},
+	"2a42": {Name: "Alert Category ID Bit Mask", Type: "org.bluetooth.characteristic.alert_category_id_bit_mask"},
+	"2a43": {Name: "Alert Category ID", Type: "org.bluetooth.characteristic.alert_category_id"},
+	"2a44": {Name: "Alert Notification Control Point", Type: "org.bluetooth.characteristic.alert_notification_control_point"},
+	"2a45": {Name: "Unread Alert Status", Type: "org.bluetooth.characteristic.unread_alert_status"},
+	"2a46": {Name: "New Alert", Type: "org.bluetooth.characteristic.new_alert"},
+	"2a47": {Name: "Supported New Alert Category", Type: "org.bluetooth.characteristic.supported_new_alert_category"},
+	"2a48": {Name: "Supported Unread Alert Category", Type: "org.bluetooth.characteristic.supported_unread_alert_category"},
+	"2a49": {Name: "Blood Pressure Feature", Type: "org.bluetooth.characteristic.blood_pressure_feature"},
+	"2a4a": {Name: "HID Information", Type: "org.bluetooth.characteristic.hid_information"},
+	"2a4b": {Name: "Report Map", Type: "org.bluetooth.characteristic.report_map"},
+	"2a4c": {Name: "HID Control Point", Type: "org.bluetooth.characteristic.hid_control_point"},
+	"2a4d": {Name: "Report", Type: "org.bluetooth.characteristic.report"},
+	"2a4e": {Name: "Protocol Mode", Type: "org.bluetooth.characteristic.protocol_mode"},
+	"2a4f": {Name: "Scan Interval Window", Type: "org.bluetooth.characteristic.scan_interval_window"},
+	"2a50": {Name: "PnP ID", Type: "org.bluetooth.characteristic.pnp_id"},
+	"2a51": {Name: "Glucose Feature", Type: "org.bluetooth.characteristic.glucose_feature"},
+	"2a52": {Name: "Record Access Control Point", Type: "org.bluetooth.characteristic.record_access_control_point"},
+	"2a53": {Name: "RSC Measurement", Type: "org.bluetooth.characteristic.rsc_measurement"},
+	"2a54": {Name: "RSC Feature", Type: "org.bluetooth.characteristic.rsc_feature"},
+	"2a55": {Name: "SC Control Point", Type: "org.bluetooth.characteristic.sc_control_point"},
+	"2a5b": {Name: "CSC Measurement", Type: "org.bluetooth.characteristic.csc_measurement"},
+	"2a5c": {Name: "CSC Feature", Type: "org.bluetooth.characteristic.csc_feature"},
+	"2a5d": {Name: "Sensor Location", Type: "org.bluetooth.characteristic.sensor_location"},
+}
diff --git a/newtmgr/vendor/github.com/raff/goble/LICENSE b/newtmgr/vendor/github.com/raff/goble/LICENSE
new file mode 100644
index 0000000..a4f7f21
--- /dev/null
+++ b/newtmgr/vendor/github.com/raff/goble/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Raffaele Sena
+
+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.
diff --git a/newtmgr/vendor/github.com/raff/goble/xpc/xpc.go b/newtmgr/vendor/github.com/raff/goble/xpc/xpc.go
new file mode 100644
index 0000000..fd210ac
--- /dev/null
+++ b/newtmgr/vendor/github.com/raff/goble/xpc/xpc.go
@@ -0,0 +1,381 @@
+package xpc
+
+/*
+#include "xpc_wrapper.h"
+*/
+import "C"
+
+import (
+	"errors"
+	"fmt"
+	"log"
+	r "reflect"
+	"strings"
+	"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) UUID {
+	return d[k].(UUID)
+}
+
+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 [16]byte
+
+func MakeUUID(s string) UUID {
+	var sl []byte
+
+	s = strings.Replace(s, "-", "", -1)
+	fmt.Sscanf(s, "%32x", &sl)
+
+	var uuid [16]byte
+	copy(uuid[:], sl)
+	return UUID(uuid)
+}
+
+func MustUUID(s string) UUID {
+	var sl []byte
+
+	s = strings.Replace(s, "-", "", -1)
+	if len(s) != 32 {
+		log.Fatal("invalid UUID")
+	}
+	if n, err := fmt.Sscanf(s, "%32x", &sl); err != nil || n != 1 {
+		log.Fatal("invalid UUID ", s, " len ", n, " error ", err)
+	}
+
+	var uuid [16]byte
+	copy(uuid[:], sl)
+	return UUID(uuid)
+}
+
+func (uuid UUID) String() string {
+	return fmt.Sprintf("%x", [16]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{})
+
+	handlers = map[uintptr]XpcEventHandler{}
+)
+
+type XpcEventHandler interface {
+	HandleXpcEvent(event Dict, err error)
+}
+
+func XpcConnect(service string, eh XpcEventHandler) XPC {
+	// func XpcConnect(service string, eh XpcEventHandler) C.xpc_connection_t {
+	ctx := uintptr(unsafe.Pointer(&eh))
+	handlers[ctx] = eh
+
+	cservice := C.CString(service)
+	defer C.free(unsafe.Pointer(cservice))
+	// return C.XpcConnect(cservice, C.uintptr_t(ctx))
+	return XPC{conn: C.XpcConnect(cservice, C.uintptr_t(ctx))}
+}
+
+//export handleXpcEvent
+func handleXpcEvent(event C.xpc_object_t, p C.ulong) {
+	//log.Printf("handleXpcEvent %#v %#v\n", event, p)
+
+	t := C.xpc_get_type(event)
+
+	eh := handlers[uintptr(p)]
+	if eh == nil {
+		//log.Println("no handler for", p)
+		return
+	}
+
+	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 C.uintptr_t, i C.int, v C.xpc_object_t) {
+	a := *(*Array)(unsafe.Pointer(uintptr(u)))
+	a[i] = xpcToGo(v)
+}
+
+//export dictSet
+func dictSet(u C.uintptr_t, k *C.char, v C.xpc_object_t) {
+	d := *(*Dict)(unsafe.Pointer(uintptr(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)))
+		p := uintptr(unsafe.Pointer(&a))
+		C.XpcArrayApply(C.uintptr_t(p), 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)
+		p := uintptr(unsafe.Pointer(&d))
+		C.XpcDictApply(C.uintptr_t(p), 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
+}
diff --git a/newtmgr/vendor/github.com/raff/goble/xpc/xpc_wrapper.c b/newtmgr/vendor/github.com/raff/goble/xpc/xpc_wrapper.c
new file mode 100644
index 0000000..130b237
--- /dev/null
+++ b/newtmgr/vendor/github.com/raff/goble/xpc/xpc_wrapper.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, uintptr_t 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, ctx); //(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(uintptr_t 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(uintptr_t 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];
+   }
+}
diff --git a/newtmgr/vendor/github.com/raff/goble/xpc/xpc_wrapper.h b/newtmgr/vendor/github.com/raff/goble/xpc/xpc_wrapper.h
new file mode 100644
index 0000000..eb7528f
--- /dev/null
+++ b/newtmgr/vendor/github.com/raff/goble/xpc/xpc_wrapper.h
@@ -0,0 +1,33 @@
+#ifndef _XPC_WRAPPER_H_
+#define _XPC_WRAPPER_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <xpc/xpc.h>
+#include <sys/utsname.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 *, uintptr_t);
+extern void XpcSendMessage(xpc_connection_t, xpc_object_t, bool, bool);
+extern void XpcArrayApply(uintptr_t, xpc_object_t);
+extern void XpcDictApply(uintptr_t, 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
diff --git a/newtmgr/vendor/mynewt.apache.org/newt/util/util.go b/newtmgr/vendor/mynewt.apache.org/newt/util/util.go
index cc56e8a..e513cf7 100644
--- a/newtmgr/vendor/mynewt.apache.org/newt/util/util.go
+++ b/newtmgr/vendor/mynewt.apache.org/newt/util/util.go
@@ -43,6 +43,7 @@ import (
 
 var Verbosity int
 var PrintShellCmds bool
+var ExecuteShell bool
 var logFile *os.File
 
 func ParseEqualsPair(v string) (string, string, error) {
@@ -249,6 +250,7 @@ func Init(logLevel log.Level, logFile string, verbosity int) error {
 
 	Verbosity = verbosity
 	PrintShellCmds = false
+	ExecuteShell = false
 
 	return nil
 }
@@ -286,6 +288,8 @@ func ReadConfig(path string, name string) (*viper.Viper, error) {
 // @return error                NewtError on failure.
 func ShellCommandLimitDbgOutput(
 	cmdStrs []string, env []string, maxDbgOutputChrs int) ([]byte, error) {
+	var name string
+	var args []string
 
 	envLogStr := ""
 	if env != nil {
@@ -297,8 +301,14 @@ func ShellCommandLimitDbgOutput(
 		StatusMessage(VERBOSITY_SILENT, "%s\n", strings.Join(cmdStrs, " "))
 	}
 
-	name := cmdStrs[0]
-	args := cmdStrs[1:]
+	if ExecuteShell && ((runtime.GOOS == "linux") || (runtime.GOOS == "darwin")) {
+		cmd := strings.Join(cmdStrs, " ")
+		name = "/bin/sh"
+		args = []string{"-c", strings.Replace(cmd, "\"", "\\\"", -1)}
+	} else {
+		name = cmdStrs[0]
+		args = cmdStrs[1:]
+	}
 	cmd := exec.Command(name, args...)
 
 	if env != nil {
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/bledefs/bledefs.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/bledefs/bledefs.go
index 780587e..6b31ca2 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/bledefs/bledefs.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/bledefs/bledefs.go
@@ -33,9 +33,9 @@ const BLE_ATT_MTU_DFLT = 23
 
 const CccdUuid = 0x2902
 
-const PublicSvcUuid = "40e32721-9153-43a3-9ab3-ee7d4c84fcb2"
-const PublicReqChrUuid = "223387b6-63e6-4d16-8a58-988542253a54"
-const PublicRspChrUuid = "cb9564db-184c-4b9d-b221-6362679cad10"
+const IotivitySvcUuid = "ade3d529-c784-4f63-a987-eb69f70ee816"
+const IotivityReqChrUuid = "ad7b334f-4637-4b86-90b6-9d787f03d218"
+const IotivityRspChrUuid = "ad7b334f-4637-4b86-90b6-9d787f03d218"
 
 const UnauthSvcUuid = "0c08c213-98ed-4e43-a499-7e1137c39567"
 const UnauthReqChrUuid = "69b8a928-2ab2-487b-923e-54ce53a18bc1"
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go
index 8a11ec0..d1d0bfb 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go
@@ -683,36 +683,36 @@ func GattService() BleSvc {
 }
 
 type CoapServiceCfg struct {
-	x          *BleXport
-	svcUuid    BleUuid
-	reqChrUuid BleUuid
-	rspChrUuid BleUuid
-	enc        bool
-	auth       bool
-	resources  []oic.Resource
+	X          *BleXport
+	SvcUuid    BleUuid
+	ReqChrUuid BleUuid
+	RspChrUuid BleUuid
+	Enc        bool
+	Auth       bool
+	Resources  []oic.Resource
 }
 
 func GenCoapService(cfg CoapServiceCfg) (BleSvc, error) {
-	svr := NewBleOicSvr(cfg.x, cfg.svcUuid, cfg.rspChrUuid)
-	for _, r := range cfg.resources {
+	svr := NewBleOicSvr(cfg.X, cfg.SvcUuid, cfg.RspChrUuid)
+	for _, r := range cfg.Resources {
 		if err := svr.AddResource(r); err != nil {
 			return BleSvc{}, err
 		}
 	}
 
 	var secFlags BleChrFlags
-	if cfg.enc {
+	if cfg.Enc {
 		secFlags |= BLE_GATT_F_WRITE_ENC
 	}
-	if cfg.auth {
+	if cfg.Auth {
 		secFlags |= BLE_GATT_F_WRITE_AUTHEN
 	}
 	svc := BleSvc{
-		Uuid:    cfg.svcUuid,
+		Uuid:    cfg.SvcUuid,
 		SvcType: BLE_SVC_TYPE_PRIMARY,
 		Chrs: []BleChr{
 			BleChr{
-				Uuid:       cfg.reqChrUuid,
+				Uuid:       cfg.ReqChrUuid,
 				Flags:      BLE_GATT_F_WRITE_NO_RSP | secFlags,
 				MinKeySize: 0,
 				AccessCb: func(access BleGattAccess) (uint8, []byte) {
@@ -720,7 +720,7 @@ func GenCoapService(cfg CoapServiceCfg) (BleSvc, error) {
 				},
 			},
 			BleChr{
-				Uuid:       cfg.rspChrUuid,
+				Uuid:       cfg.RspChrUuid,
 				Flags:      BLE_GATT_F_NOTIFY,
 				MinKeySize: 0,
 				AccessCb:   nil,
@@ -765,9 +765,9 @@ func BuildMgmtChrs(mgmtProto sesn.MgmtProto) (BleMgmtChrs, error) {
 	ompReqChrUuid, _ := ParseUuid(OmpUnsecReqChrUuid)
 	ompRspChrUuid, _ := ParseUuid(OmpUnsecRspChrUuid)
 
-	publicSvcUuid, _ := ParseUuid(PublicSvcUuid)
-	publicReqChrUuid, _ := ParseUuid(PublicReqChrUuid)
-	publicRspChrUuid, _ := ParseUuid(PublicRspChrUuid)
+	publicSvcUuid, _ := ParseUuid(IotivitySvcUuid)
+	publicReqChrUuid, _ := ParseUuid(IotivityReqChrUuid)
+	publicRspChrUuid, _ := ParseUuid(IotivityRspChrUuid)
 
 	unauthSvcUuid, _ := ParseUuid(UnauthSvcUuid)
 	unauthReqChrUuid, _ := ParseUuid(UnauthReqChrUuid)

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.