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/04 19:28:16 UTC

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

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 bcff584562bd4d0519894c1df555e5c1c70b9ae1
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Mon Jul 24 18:25:44 2017 -0700

    newtmgr - revendor
---
 newtmgr/Godeps/Godeps.json                         |  76 +-
 .../vendor/github.com/runtimeco/go-coap/client.go  |   8 +-
 .../vendor/github.com/runtimeco/go-coap/message.go | 177 ++---
 .../github.com/runtimeco/go-coap/messagedgram.go   | 109 +++
 .../github.com/runtimeco/go-coap/messagetcp.go     |  46 +-
 .../vendor/github.com/runtimeco/go-coap/server.go  |  18 +-
 .../vendor/github.com/runtimeco/go-coap/servmux.go |  14 +-
 .../mynewt.apache.org/newtmgr/nmxact/adv/adv.go    |  43 ++
 .../newtmgr/nmxact/bledefs/bledefs.go              | 194 ++++-
 .../newtmgr/nmxact/mgmt/transceiver.go             | 202 +++++
 .../newtmgr/nmxact/nmble/ble_act.go                | 385 +++++++++-
 .../newtmgr/nmxact/nmble/ble_advertiser.go         | 217 ++++++
 .../newtmgr/nmxact/nmble/ble_fsm.go                | 815 ---------------------
 .../newtmgr/nmxact/nmble/ble_oic_sesn.go           | 230 ------
 .../newtmgr/nmxact/nmble/ble_oic_svr.go            |  59 ++
 .../newtmgr/nmxact/nmble/ble_plain_sesn.go         | 188 -----
 .../newtmgr/nmxact/nmble/ble_proto.go              | 434 +++++++++--
 .../newtmgr/nmxact/nmble/ble_scanner.go            |   4 +-
 .../newtmgr/nmxact/nmble/ble_sesn.go               | 342 +++++++++
 .../newtmgr/nmxact/nmble/ble_util.go               | 388 +++++++++-
 .../newtmgr/nmxact/nmble/ble_xport.go              |  61 +-
 .../newtmgr/nmxact/nmble/chrmgr.go                 | 123 ++++
 .../mynewt.apache.org/newtmgr/nmxact/nmble/conn.go | 713 ++++++++++++++++++
 .../newtmgr/nmxact/nmble/dispatch.go               |  36 +-
 .../newtmgr/nmxact/nmble/profile.go                |  82 +++
 .../newtmgr/nmxact/nmserial/serial_oic_sesn.go     |  21 +-
 .../newtmgr/nmxact/nmserial/serial_plain_sesn.go   |   8 +-
 .../newtmgr/nmxact/nmserial/serial_xport.go        |   5 +
 .../newtmgr/nmxact/nmxutil/nmxutil.go              |  13 +-
 .../newtmgr/nmxact/oic/dispatch.go                 |  38 +-
 .../mynewt.apache.org/newtmgr/nmxact/oic/frag.go   |   5 +-
 .../mynewt.apache.org/newtmgr/nmxact/oic/oic.go    |  56 +-
 .../newtmgr/nmxact/oic/receiver.go                 |  40 +
 .../mynewt.apache.org/newtmgr/nmxact/oic/resmgr.go |  73 ++
 .../mynewt.apache.org/newtmgr/nmxact/oic/server.go |  64 ++
 .../mynewt.apache.org/newtmgr/nmxact/omp/omp.go    |  38 +-
 .../mynewt.apache.org/newtmgr/nmxact/scan/scan.go  |   1 -
 .../mynewt.apache.org/newtmgr/nmxact/sesn/sesn.go  |   8 +-
 .../newtmgr/nmxact/sesn/sesn_cfg.go                |  48 +-
 .../newtmgr/nmxact/sesn/sesn_util.go               |  12 +-
 .../newtmgr/nmxact/udp/udp_oic_sesn.go             |  21 +-
 .../newtmgr/nmxact/udp/udp_plain_sesn.go           |   8 +-
 .../newtmgr/nmxact/udp/udp_xport.go                |   5 +
 .../newtmgr/nmxact/{omp/frag.go => xact/getres.go} |  50 +-
 .../newtmgr/nmxact/xport/xport.go                  |   2 +
 45 files changed, 3852 insertions(+), 1628 deletions(-)

diff --git a/newtmgr/Godeps/Godeps.json b/newtmgr/Godeps/Godeps.json
index e994da5..d960ed4 100644
--- a/newtmgr/Godeps/Godeps.json
+++ b/newtmgr/Godeps/Godeps.json
@@ -64,7 +64,7 @@
 		},
 		{
 			"ImportPath": "github.com/runtimeco/go-coap",
-			"Rev": "69c7d16d97310edddc3bde6da452b684051549a7"
+			"Rev": "00d0ad21a4e212b48744a8456e0203395aa42f21"
 		},
 		{
 			"ImportPath": "github.com/spf13/cast",
@@ -107,83 +107,93 @@
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newt/util",
-			"Comment": "mynewt_1_0_1_tag-17-g5a6266e",
-			"Rev": "5a6266e693bff0890b2526b99bbce2e17da79be1"
+			"Comment": "mynewt_1_1_0_rc2_tag",
+			"Rev": "0e174a618b473e89b5c0d681957830f0d4b7a665"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newt/util/unixchild",
-			"Comment": "mynewt_1_0_1_tag-17-g5a6266e",
-			"Rev": "5a6266e693bff0890b2526b99bbce2e17da79be1"
+			"Comment": "mynewt_1_1_0_rc2_tag",
+			"Rev": "0e174a618b473e89b5c0d681957830f0d4b7a665"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newt/viper",
-			"Comment": "mynewt_1_0_1_tag-17-g5a6266e",
-			"Rev": "5a6266e693bff0890b2526b99bbce2e17da79be1"
+			"Comment": "mynewt_1_1_0_rc2_tag",
+			"Rev": "0e174a618b473e89b5c0d681957830f0d4b7a665"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newt/yaml",
-			"Comment": "mynewt_1_0_1_tag-17-g5a6266e",
-			"Rev": "5a6266e693bff0890b2526b99bbce2e17da79be1"
+			"Comment": "mynewt_1_1_0_rc2_tag",
+			"Rev": "0e174a618b473e89b5c0d681957830f0d4b7a665"
+		},
+		{
+			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/adv",
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/bledefs",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
+		},
+		{
+			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/mgmt",
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmble",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmp",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmserial",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/nmxutil",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/oic",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/omp",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/scan",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/sesn",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/udp",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/xact",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		},
 		{
 			"ImportPath": "mynewt.apache.org/newtmgr/nmxact/xport",
-			"Comment": "mynewt_0_9_0_tag-564-gda4f833",
-			"Rev": "da4f833574bb400c85cbc443f190b99891d6bb3c"
+			"Comment": "mynewt_1_1_0_rc1_tag-6-g01881bf",
+			"Rev": "01881bff3fb90177cffca6f997a93e92e3c6fac9"
 		}
 	]
 }
diff --git a/newtmgr/vendor/github.com/runtimeco/go-coap/client.go b/newtmgr/vendor/github.com/runtimeco/go-coap/client.go
index 95cf03f..f254e11 100644
--- a/newtmgr/vendor/github.com/runtimeco/go-coap/client.go
+++ b/newtmgr/vendor/github.com/runtimeco/go-coap/client.go
@@ -38,7 +38,7 @@ func Dial(n, addr string) (*Conn, error) {
 }
 
 // Send a message.  Get a response if there is one.
-func (c *Conn) Send(req Message) (*Message, error) {
+func (c *Conn) Send(req Message) (Message, error) {
 	err := Transmit(c.conn, nil, req)
 	if err != nil {
 		return nil, err
@@ -53,14 +53,14 @@ func (c *Conn) Send(req Message) (*Message, error) {
 		return nil, err
 	}
 
-	return &rv, nil
+	return rv, nil
 }
 
 // Receive a message.
-func (c *Conn) Receive() (*Message, error) {
+func (c *Conn) Receive() (Message, error) {
 	rv, err := Receive(c.conn, c.buf)
 	if err != nil {
 		return nil, err
 	}
-	return &rv, nil
+	return rv, nil
 }
diff --git a/newtmgr/vendor/github.com/runtimeco/go-coap/message.go b/newtmgr/vendor/github.com/runtimeco/go-coap/message.go
index 8142fb6..cb473c7 100644
--- a/newtmgr/vendor/github.com/runtimeco/go-coap/message.go
+++ b/newtmgr/vendor/github.com/runtimeco/go-coap/message.go
@@ -1,13 +1,11 @@
 package coap
 
 import (
-	"bytes"
 	"encoding/binary"
 	"errors"
 	"fmt"
 	"io"
 	"reflect"
-	"sort"
 	"strings"
 )
 
@@ -335,24 +333,80 @@ func (o options) Minus(oid OptionID) options {
 	return rv
 }
 
-// Message is a CoAP message.
-type Message struct {
+type Message interface {
+	Type() COAPType
+	Code() COAPCode
+	MessageID() uint16
+	Token() []byte
+	Payload() []byte
+	AllOptions() options
+
+	IsConfirmable() bool
+	Options(o OptionID) []interface{}
+	Option(o OptionID) interface{}
+	optionStrings(o OptionID) []string
+	Path() []string
+	PathString() string
+	SetPathString(s string)
+	SetPath(s []string)
+	SetPayload(p []byte)
+	RemoveOption(opID OptionID)
+	AddOption(opID OptionID, val interface{})
+	SetOption(opID OptionID, val interface{})
+	MarshalBinary() ([]byte, error)
+	UnmarshalBinary(data []byte) error
+}
+
+type MessageParams struct {
 	Type      COAPType
 	Code      COAPCode
 	MessageID uint16
+	Token     []byte
+	Payload   []byte
+}
+
+// MessageBase is a CoAP message.
+type MessageBase struct {
+	typ       COAPType
+	code      COAPCode
+	messageID uint16
 
-	Token, Payload []byte
+	token, payload []byte
 
 	opts options
 }
 
+func (m *MessageBase) Type() COAPType {
+	return m.typ
+}
+
+func (m *MessageBase) Code() COAPCode {
+	return m.code
+}
+
+func (m *MessageBase) MessageID() uint16 {
+	return m.messageID
+}
+
+func (m *MessageBase) Token() []byte {
+	return m.token
+}
+
+func (m *MessageBase) Payload() []byte {
+	return m.payload
+}
+
+func (m *MessageBase) AllOptions() options {
+	return m.opts
+}
+
 // IsConfirmable returns true if this message is confirmable.
-func (m Message) IsConfirmable() bool {
-	return m.Type == Confirmable
+func (m *MessageBase) IsConfirmable() bool {
+	return m.typ == Confirmable
 }
 
 // Options gets all the values for the given option.
-func (m Message) Options(o OptionID) []interface{} {
+func (m *MessageBase) Options(o OptionID) []interface{} {
 	var rv []interface{}
 
 	for _, v := range m.opts {
@@ -365,7 +419,7 @@ func (m Message) Options(o OptionID) []interface{} {
 }
 
 // Option gets the first value for the given option ID.
-func (m Message) Option(o OptionID) interface{} {
+func (m *MessageBase) Option(o OptionID) interface{} {
 	for _, v := range m.opts {
 		if o == v.ID {
 			return v.Value
@@ -374,7 +428,7 @@ func (m Message) Option(o OptionID) interface{} {
 	return nil
 }
 
-func (m Message) optionStrings(o OptionID) []string {
+func (m *MessageBase) optionStrings(o OptionID) []string {
 	var rv []string
 	for _, o := range m.Options(o) {
 		rv = append(rv, o.(string))
@@ -383,17 +437,17 @@ func (m Message) optionStrings(o OptionID) []string {
 }
 
 // Path gets the Path set on this message if any.
-func (m Message) Path() []string {
+func (m *MessageBase) Path() []string {
 	return m.optionStrings(URIPath)
 }
 
 // PathString gets a path as a / separated string.
-func (m Message) PathString() string {
+func (m *MessageBase) PathString() string {
 	return strings.Join(m.Path(), "/")
 }
 
 // SetPathString sets a path by a / separated string.
-func (m *Message) SetPathString(s string) {
+func (m *MessageBase) SetPathString(s string) {
 	for s[0] == '/' {
 		s = s[1:]
 	}
@@ -401,17 +455,22 @@ func (m *Message) SetPathString(s string) {
 }
 
 // SetPath updates or adds a URIPath attribute on this message.
-func (m *Message) SetPath(s []string) {
+func (m *MessageBase) SetPath(s []string) {
 	m.SetOption(URIPath, s)
 }
 
+// SetPayload
+func (m *MessageBase) SetPayload(p []byte) {
+	m.payload = p
+}
+
 // RemoveOption removes all references to an option
-func (m *Message) RemoveOption(opID OptionID) {
+func (m *MessageBase) RemoveOption(opID OptionID) {
 	m.opts = m.opts.Minus(opID)
 }
 
 // AddOption adds an option.
-func (m *Message) AddOption(opID OptionID, val interface{}) {
+func (m *MessageBase) AddOption(opID OptionID, val interface{}) {
 	iv := reflect.ValueOf(val)
 	if (iv.Kind() == reflect.Slice || iv.Kind() == reflect.Array) &&
 		iv.Type().Elem().Kind() == reflect.String {
@@ -424,7 +483,7 @@ func (m *Message) AddOption(opID OptionID, val interface{}) {
 }
 
 // SetOption sets an option, discarding any previous value
-func (m *Message) SetOption(opID OptionID, val interface{}) {
+func (m *MessageBase) SetOption(opID OptionID, val interface{}) {
 	m.RemoveOption(opID)
 	m.AddOption(opID, val)
 }
@@ -514,51 +573,6 @@ func writeOpts(buf io.Writer, opts options) {
 	}
 }
 
-// MarshalBinary produces the binary form of this Message.
-func (m *Message) MarshalBinary() ([]byte, error) {
-	tmpbuf := []byte{0, 0}
-	binary.BigEndian.PutUint16(tmpbuf, m.MessageID)
-
-	/*
-	     0                   1                   2                   3
-	    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	   |Ver| T |  TKL  |      Code     |          Message ID           |
-	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	   |   Token (if any, TKL bytes) ...
-	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	   |   Options (if any) ...
-	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	   |1 1 1 1 1 1 1 1|    Payload (if any) ...
-	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	*/
-
-	buf := bytes.Buffer{}
-	buf.Write([]byte{
-		(1 << 6) | (uint8(m.Type) << 4) | uint8(0xf&len(m.Token)),
-		byte(m.Code),
-		tmpbuf[0], tmpbuf[1],
-	})
-	buf.Write(m.Token)
-
-	sort.Stable(&m.opts)
-	writeOpts(&buf, m.opts)
-
-	if len(m.Payload) > 0 {
-		buf.Write([]byte{0xff})
-	}
-
-	buf.Write(m.Payload)
-
-	return buf.Bytes(), nil
-}
-
-// ParseMessage extracts the Message from the given input.
-func ParseMessage(data []byte) (Message, error) {
-	rv := Message{}
-	return rv, rv.UnmarshalBinary(data)
-}
-
 // parseBody extracts the options and payload from a byte slice.  The supplied
 // byte slice contains everything following the message header (everything
 // after the token).
@@ -626,42 +640,3 @@ func parseBody(data []byte) (options, []byte, error) {
 
 	return opts, data, nil
 }
-
-// UnmarshalBinary parses the given binary slice as a Message.
-func (m *Message) UnmarshalBinary(data []byte) error {
-	if len(data) < 4 {
-		return errors.New("short packet")
-	}
-
-	if data[0]>>6 != 1 {
-		return errors.New("invalid version")
-	}
-
-	m.Type = COAPType((data[0] >> 4) & 0x3)
-	tokenLen := int(data[0] & 0xf)
-	if tokenLen > 8 {
-		return ErrInvalidTokenLen
-	}
-
-	m.Code = COAPCode(data[1])
-	m.MessageID = binary.BigEndian.Uint16(data[2:4])
-
-	if tokenLen > 0 {
-		m.Token = make([]byte, tokenLen)
-	}
-	if len(data) < 4+tokenLen {
-		return errors.New("truncated")
-	}
-	copy(m.Token, data[4:4+tokenLen])
-	b := data[4+tokenLen:]
-
-	o, p, err := parseBody(b)
-	if err != nil {
-		return err
-	}
-
-	m.Payload = p
-	m.opts = o
-
-	return nil
-}
diff --git a/newtmgr/vendor/github.com/runtimeco/go-coap/messagedgram.go b/newtmgr/vendor/github.com/runtimeco/go-coap/messagedgram.go
new file mode 100644
index 0000000..11cebdb
--- /dev/null
+++ b/newtmgr/vendor/github.com/runtimeco/go-coap/messagedgram.go
@@ -0,0 +1,109 @@
+package coap
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+	"sort"
+)
+
+// DgramMessage implements Message interface.
+type DgramMessage struct {
+	MessageBase
+}
+
+func NewDgramMessage(p MessageParams) *DgramMessage {
+	return &DgramMessage{
+		MessageBase{
+			typ:       p.Type,
+			code:      p.Code,
+			messageID: p.MessageID,
+			token:     p.Token,
+			payload:   p.Payload,
+		},
+	}
+}
+
+// MarshalBinary produces the binary form of this DgramMessage.
+func (m *DgramMessage) MarshalBinary() ([]byte, error) {
+	tmpbuf := []byte{0, 0}
+	binary.BigEndian.PutUint16(tmpbuf, m.MessageID())
+
+	/*
+	     0                   1                   2                   3
+	    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	   |Ver| T |  TKL  |      Code     |          Message ID           |
+	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	   |   Token (if any, TKL bytes) ...
+	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	   |   Options (if any) ...
+	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	   |1 1 1 1 1 1 1 1|    Payload (if any) ...
+	   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	*/
+
+	buf := bytes.Buffer{}
+	buf.Write([]byte{
+		(1 << 6) | (uint8(m.Type()) << 4) | uint8(0xf&len(m.MessageBase.token)),
+		byte(m.MessageBase.code),
+		tmpbuf[0], tmpbuf[1],
+	})
+	buf.Write(m.MessageBase.token)
+
+	sort.Stable(&m.MessageBase.opts)
+	writeOpts(&buf, m.MessageBase.opts)
+
+	if len(m.MessageBase.payload) > 0 {
+		buf.Write([]byte{0xff})
+	}
+
+	buf.Write(m.MessageBase.payload)
+
+	return buf.Bytes(), nil
+}
+
+// UnmarshalBinary parses the given binary slice as a DgramMessage.
+func (m *DgramMessage) UnmarshalBinary(data []byte) error {
+	if len(data) < 4 {
+		return errors.New("short packet")
+	}
+
+	if data[0]>>6 != 1 {
+		return errors.New("invalid version")
+	}
+
+	m.MessageBase.typ = COAPType((data[0] >> 4) & 0x3)
+	tokenLen := int(data[0] & 0xf)
+	if tokenLen > 8 {
+		return ErrInvalidTokenLen
+	}
+
+	m.MessageBase.code = COAPCode(data[1])
+	m.MessageBase.messageID = binary.BigEndian.Uint16(data[2:4])
+
+	if tokenLen > 0 {
+		m.MessageBase.token = make([]byte, tokenLen)
+	}
+	if len(data) < 4+tokenLen {
+		return errors.New("truncated")
+	}
+	copy(m.MessageBase.token, data[4:4+tokenLen])
+	b := data[4+tokenLen:]
+
+	o, p, err := parseBody(b)
+	if err != nil {
+		return err
+	}
+
+	m.MessageBase.payload = p
+	m.MessageBase.opts = o
+
+	return nil
+}
+
+// ParseDgramMessage extracts the Message from the given input.
+func ParseDgramMessage(data []byte) (*DgramMessage, error) {
+	rv := &DgramMessage{}
+	return rv, rv.UnmarshalBinary(data)
+}
diff --git a/newtmgr/vendor/github.com/runtimeco/go-coap/messagetcp.go b/newtmgr/vendor/github.com/runtimeco/go-coap/messagetcp.go
index 8af7d70..85a79d8 100644
--- a/newtmgr/vendor/github.com/runtimeco/go-coap/messagetcp.go
+++ b/newtmgr/vendor/github.com/runtimeco/go-coap/messagetcp.go
@@ -15,10 +15,22 @@ const (
 	TCP_MESSAGE_MAX_LEN    = 0x7fff0000 // Large number that works in 32-bit builds.
 )
 
-// TcpMessage is a CoAP Message that can encode itself for TCP
+// TcpMessage is a CoAP MessageBase that can encode itself for TCP
 // transport.
 type TcpMessage struct {
-	Message
+	MessageBase
+}
+
+func NewTcpMessage(p MessageParams) *TcpMessage {
+	return &TcpMessage{
+		MessageBase{
+			typ:       p.Type,
+			code:      p.Code,
+			messageID: p.MessageID,
+			token:     p.Token,
+			payload:   p.Payload,
+		},
+	}
 }
 
 func (m *TcpMessage) MarshalBinary() ([]byte, error) {
@@ -50,12 +62,12 @@ func (m *TcpMessage) MarshalBinary() ([]byte, error) {
 
 	buf := bytes.Buffer{}
 
-	sort.Stable(&m.Message.opts)
-	writeOpts(&buf, m.Message.opts)
+	sort.Stable(&m.MessageBase.opts)
+	writeOpts(&buf, m.MessageBase.opts)
 
-	if len(m.Message.Payload) > 0 {
+	if len(m.MessageBase.payload) > 0 {
 		buf.Write([]byte{0xff})
-		buf.Write(m.Message.Payload)
+		buf.Write(m.MessageBase.payload)
 	}
 
 	var lenNib uint8
@@ -79,11 +91,11 @@ func (m *TcpMessage) MarshalBinary() ([]byte, error) {
 		binary.BigEndian.PutUint32(extLenBytes, uint32(extLen))
 	}
 
-	hdr := make([]byte, 1+len(extLenBytes)+len(m.Message.Token)+1)
+	hdr := make([]byte, 1+len(extLenBytes)+len(m.MessageBase.token)+1)
 	hdrOff := 0
 
 	// Length and TKL nibbles.
-	hdr[hdrOff] = uint8(0xf&len(m.Token)) | (lenNib << 4)
+	hdr[hdrOff] = uint8(0xf&len(m.MessageBase.token)) | (lenNib << 4)
 	hdrOff++
 
 	// Extended length, if present.
@@ -93,13 +105,13 @@ func (m *TcpMessage) MarshalBinary() ([]byte, error) {
 	}
 
 	// Code.
-	hdr[hdrOff] = byte(m.Message.Code)
+	hdr[hdrOff] = byte(m.MessageBase.code)
 	hdrOff++
 
 	// Token.
-	if len(m.Message.Token) > 0 {
-		copy(hdr[hdrOff:hdrOff+len(m.Message.Token)], m.Message.Token)
-		hdrOff += len(m.Message.Token)
+	if len(m.MessageBase.token) > 0 {
+		copy(hdr[hdrOff:hdrOff+len(m.MessageBase.token)], m.MessageBase.token)
+		hdrOff += len(m.MessageBase.token)
 	}
 
 	return append(hdr, buf.Bytes()...), nil
@@ -190,11 +202,11 @@ func readTcpMsgBody(mti msgTcpInfo, r io.Reader) (options, []byte, error) {
 }
 
 func (m *TcpMessage) fill(mti msgTcpInfo, o options, p []byte) {
-	m.Type = COAPType(mti.typ)
-	m.Code = COAPCode(mti.code)
-	m.Token = mti.token
-	m.opts = o
-	m.Payload = p
+	m.MessageBase.typ = COAPType(mti.typ)
+	m.MessageBase.code = COAPCode(mti.code)
+	m.MessageBase.token = mti.token
+	m.MessageBase.opts = o
+	m.MessageBase.payload = p
 }
 
 func (m *TcpMessage) UnmarshalBinary(data []byte) error {
diff --git a/newtmgr/vendor/github.com/runtimeco/go-coap/server.go b/newtmgr/vendor/github.com/runtimeco/go-coap/server.go
index 343b875..e8721b6 100644
--- a/newtmgr/vendor/github.com/runtimeco/go-coap/server.go
+++ b/newtmgr/vendor/github.com/runtimeco/go-coap/server.go
@@ -12,32 +12,32 @@ const maxPktLen = 1500
 // Handler is a type that handles CoAP messages.
 type Handler interface {
 	// Handle the message and optionally return a response message.
-	ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message
+	ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m Message) Message
 }
 
-type funcHandler func(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message
+type funcHandler func(l *net.UDPConn, a *net.UDPAddr, m Message) Message
 
-func (f funcHandler) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message {
+func (f funcHandler) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m Message) Message {
 	return f(l, a, m)
 }
 
 // FuncHandler builds a handler from a function.
-func FuncHandler(f func(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message) Handler {
+func FuncHandler(f func(l *net.UDPConn, a *net.UDPAddr, m Message) Message) Handler {
 	return funcHandler(f)
 }
 
 func handlePacket(l *net.UDPConn, data []byte, u *net.UDPAddr,
 	rh Handler) {
 
-	msg, err := ParseMessage(data)
+	msg, err := ParseDgramMessage(data)
 	if err != nil {
 		log.Printf("Error parsing %v", err)
 		return
 	}
 
-	rv := rh.ServeCOAP(l, u, &msg)
+	rv := rh.ServeCOAP(l, u, msg)
 	if rv != nil {
-		Transmit(l, u, *rv)
+		Transmit(l, u, rv)
 	}
 }
 
@@ -62,9 +62,9 @@ func Receive(l *net.UDPConn, buf []byte) (Message, error) {
 
 	nr, _, err := l.ReadFromUDP(buf)
 	if err != nil {
-		return Message{}, err
+		return &DgramMessage{}, err
 	}
-	return ParseMessage(buf[:nr])
+	return ParseDgramMessage(buf[:nr])
 }
 
 // ListenAndServe binds to the given address and serve requests forever.
diff --git a/newtmgr/vendor/github.com/runtimeco/go-coap/servmux.go b/newtmgr/vendor/github.com/runtimeco/go-coap/servmux.go
index 23132f1..f5b262d 100644
--- a/newtmgr/vendor/github.com/runtimeco/go-coap/servmux.go
+++ b/newtmgr/vendor/github.com/runtimeco/go-coap/servmux.go
@@ -48,11 +48,13 @@ func (mux *ServeMux) match(path string) (h Handler, pattern string) {
 	return
 }
 
-func notFoundHandler(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message {
+func notFoundHandler(l *net.UDPConn, a *net.UDPAddr, m Message) Message {
 	if m.IsConfirmable() {
-		return &Message{
-			Type: Acknowledgement,
-			Code: NotFound,
+		return &DgramMessage{
+			MessageBase{
+				typ:  Acknowledgement,
+				code: NotFound,
+			},
 		}
 	}
 	return nil
@@ -62,7 +64,7 @@ var _ = Handler(&ServeMux{})
 
 // ServeCOAP handles a single COAP message.  The message arrives from
 // the given listener having originated from the given UDPAddr.
-func (mux *ServeMux) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message {
+func (mux *ServeMux) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m Message) Message {
 	h, _ := mux.match(m.PathString())
 	if h == nil {
 		h, _ = funcHandler(notFoundHandler), ""
@@ -89,6 +91,6 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
 
 // HandleFunc configures a handler for the given path.
 func (mux *ServeMux) HandleFunc(pattern string,
-	f func(l *net.UDPConn, a *net.UDPAddr, m *Message) *Message) {
+	f func(l *net.UDPConn, a *net.UDPAddr, m Message) Message) {
 	mux.Handle(pattern, FuncHandler(f))
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/adv/adv.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/adv/adv.go
new file mode 100644
index 0000000..859d6ea
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/adv/adv.go
@@ -0,0 +1,43 @@
+package adv
+
+import (
+	"mynewt.apache.org/newtmgr/nmxact/bledefs"
+	"mynewt.apache.org/newtmgr/nmxact/sesn"
+)
+
+type CfgBle struct {
+	// Mandatory
+	OwnAddrType   bledefs.BleAddrType
+	ConnMode      bledefs.BleAdvConnMode
+	DiscMode      bledefs.BleAdvDiscMode
+	ItvlMin       uint16
+	ItvlMax       uint16
+	ChannelMap    uint8
+	FilterPolicy  bledefs.BleAdvFilterPolicy
+	HighDutyCycle bool
+	AdvFields     bledefs.BleAdvFields
+	RspFields     bledefs.BleAdvFields
+	SesnCfg       sesn.SesnCfg
+
+	// Only required for direct advertisements
+	PeerAddr *bledefs.BleAddr
+}
+
+type Cfg struct {
+	Ble CfgBle
+}
+
+type Advertiser interface {
+	Start(cfg Cfg) (sesn.Sesn, error)
+	Stop() error
+}
+
+func NewCfg() Cfg {
+	return Cfg{
+		Ble: CfgBle{
+			OwnAddrType: bledefs.BLE_ADDR_TYPE_RANDOM,
+			ConnMode:    bledefs.BLE_ADV_CONN_MODE_UND,
+			DiscMode:    bledefs.BLE_ADV_DISC_MODE_GEN,
+		},
+	}
+}
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 3541ac2..4f0b8c9 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/bledefs/bledefs.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/bledefs/bledefs.go
@@ -31,17 +31,23 @@ const BLE_ATT_ATTR_MAX_LEN = 512
 
 const BLE_ATT_MTU_DFLT = 23
 
-const NmpPlainSvcUuid = "8D53DC1D-1DB7-4CD3-868B-8A527460AA84"
-const NmpPlainChrUuid = "DA2E7828-FBCE-4E01-AE9E-261174997C48"
+const CccdUuid = 0x2902
 
-const OmpUnsecSvcUuid = "ADE3D529-C784-4F63-A987-EB69F70EE816"
-const OmpUnsecReqChrUuid = "AD7B334F-4637-4B86-90B6-9D787F03D218"
-const OmpUnsecRspChrUuid = "E9241982-4580-42C4-8831-95048216B256"
+const NmpPlainSvcUuid = "8d53dc1d-1db7-4cd3-868b-8a527460aa84"
+const NmpPlainChrUuid = "da2e7828-fbce-4e01-ae9e-261174997c48"
+
+const OmpUnsecSvcUuid = "ade3d529-c784-4f63-a987-eb69f70ee816"
+const OmpUnsecReqChrUuid = "ad7b334f-4637-4b86-90b6-9d787f03d218"
+const OmpUnsecRspChrUuid = "e9241982-4580-42c4-8831-95048216b256"
 
 const OmpSecSvcUuid = 0xfe18
 const OmpSecReqChrUuid = 0x1000
 const OmpSecRspChrUuid = 0x1001
 
+const GwSvcUuid = "0c08c213-98ed-4e43-a499-7e1137c39567"
+const GwReqChrUuid = "69b8a928-2ab2-487b-923e-54ce53a18bc1"
+const GwRspChrUuid = "bca10aea-5df1-4248-b72b-f52955ad9c88"
+
 type BleAddrType int
 
 const (
@@ -520,9 +526,10 @@ func (a *BleAdvDiscMode) UnmarshalJSON(data []byte) error {
 type BleAdvFilterPolicy int
 
 const (
-	BLE_ADV_FILTER_POLICY_NON BleAdvFilterPolicy = iota
-	BLE_ADV_FILTER_POLICY_LTD
-	BLE_ADV_FILTER_POLICY_GEN
+	BLE_ADV_FILTER_POLICY_NONE BleAdvFilterPolicy = iota
+	BLE_ADV_FILTER_POLICY_SCAN
+	BLE_ADV_FILTER_POLICY_CONN
+	BLE_ADV_FILTER_POLICY_BOTH
 )
 
 var BleAdvFilterPolicyStringMap = map[BleAdvFilterPolicy]string{
@@ -607,6 +614,13 @@ type BleAdvReport struct {
 type BleAdvRptFn func(r BleAdvReport)
 type BleAdvPredicate func(adv BleAdvReport) bool
 
+type BleRole int
+
+const (
+	BLE_ROLE_MASTER BleRole = iota
+	BLE_ROLE_SLAVE
+)
+
 type BleConnDesc struct {
 	ConnHandle      uint16
 	OwnIdAddrType   BleAddrType
@@ -617,6 +631,7 @@ type BleConnDesc struct {
 	PeerIdAddr      BleAddr
 	PeerOtaAddrType BleAddrType
 	PeerOtaAddr     BleAddr
+	Role            BleRole
 }
 
 func (d *BleConnDesc) String() string {
@@ -641,3 +656,166 @@ const (
 	BLE_ENCRYPT_PRIV_ONLY
 	BLE_ENCRYPT_ALWAYS
 )
+
+type BleGattOp int
+
+const (
+	BLE_GATT_ACCESS_OP_READ_CHR  BleGattOp = 0
+	BLE_GATT_ACCESS_OP_WRITE_CHR           = 1
+	BLE_GATT_ACCESS_OP_READ_DSC            = 2
+	BLE_GATT_ACCESS_OP_WRITE_DSC           = 3
+)
+
+var BleGattOpStringMap = map[BleGattOp]string{
+	BLE_GATT_ACCESS_OP_READ_CHR:  "read_chr",
+	BLE_GATT_ACCESS_OP_WRITE_CHR: "write_chr",
+	BLE_GATT_ACCESS_OP_READ_DSC:  "read_dsc",
+	BLE_GATT_ACCESS_OP_WRITE_DSC: "write_dsc",
+}
+
+func BleGattOpToString(op BleGattOp) string {
+	s := BleGattOpStringMap[op]
+	if s == "" {
+		return "???"
+	}
+
+	return s
+}
+
+func BleGattOpFromString(s string) (BleGattOp, error) {
+	for op, name := range BleGattOpStringMap {
+		if s == name {
+			return op, nil
+		}
+	}
+
+	return BleGattOp(0),
+		fmt.Errorf("Invalid BleGattOp string: %s", s)
+}
+
+type BleSvcType int
+
+const (
+	BLE_SVC_TYPE_PRIMARY BleSvcType = iota
+	BLE_SVC_TYPE_SECONDARY
+)
+
+var BleSvcTypeStringMap = map[BleSvcType]string{
+	BLE_SVC_TYPE_PRIMARY:   "primary",
+	BLE_SVC_TYPE_SECONDARY: "secondary",
+}
+
+func BleSvcTypeToString(svcType BleSvcType) string {
+	s := BleSvcTypeStringMap[svcType]
+	if s == "" {
+		return "???"
+	}
+
+	return s
+}
+
+func BleSvcTypeFromString(s string) (BleSvcType, error) {
+	for svcType, name := range BleSvcTypeStringMap {
+		if s == name {
+			return svcType, nil
+		}
+	}
+
+	return BleSvcType(0),
+		fmt.Errorf("Invalid BleSvcType string: %s", s)
+}
+
+func (a BleSvcType) MarshalJSON() ([]byte, error) {
+	return json.Marshal(BleSvcTypeToString(a))
+}
+
+func (a *BleSvcType) UnmarshalJSON(data []byte) error {
+	var err error
+
+	var s string
+	if err := json.Unmarshal(data, &s); err != nil {
+		return err
+	}
+
+	*a, err = BleSvcTypeFromString(s)
+	return err
+}
+
+type BleChrFlags int
+
+const (
+	BLE_GATT_F_BROADCAST       BleChrFlags = 0x0001
+	BLE_GATT_F_READ                        = 0x0002
+	BLE_GATT_F_WRITE_NO_RSP                = 0x0004
+	BLE_GATT_F_WRITE                       = 0x0008
+	BLE_GATT_F_NOTIFY                      = 0x0010
+	BLE_GATT_F_INDICATE                    = 0x0020
+	BLE_GATT_F_AUTH_SIGN_WRITE             = 0x0040
+	BLE_GATT_F_RELIABLE_WRITE              = 0x0080
+	BLE_GATT_F_AUX_WRITE                   = 0x0100
+	BLE_GATT_F_READ_ENC                    = 0x0200
+	BLE_GATT_F_READ_AUTHEN                 = 0x0400
+	BLE_GATT_F_READ_AUTHOR                 = 0x0800
+	BLE_GATT_F_WRITE_ENC                   = 0x1000
+	BLE_GATT_F_WRITE_AUTHEN                = 0x2000
+	BLE_GATT_F_WRITE_AUTHOR                = 0x4000
+)
+
+type BleAttFlags int
+
+const (
+	BLE_ATT_F_READ         BleAttFlags = 0x01
+	BLE_ATT_F_WRITE                    = 0x02
+	BLE_ATT_F_READ_ENC                 = 0x04
+	BLE_ATT_F_READ_AUTHEN              = 0x08
+	BLE_ATT_F_READ_AUTHOR              = 0x10
+	BLE_ATT_F_WRITE_ENC                = 0x20
+	BLE_ATT_F_WRITE_AUTHEN             = 0x40
+	BLE_ATT_F_WRITE_AUTHOR             = 0x80
+)
+
+type BleGattAccess struct {
+	Op         BleGattOp
+	ConnHandle uint16
+	SvcUuid    BleUuid
+	ChrUuid    BleUuid
+	Data       []byte
+}
+
+type BleGattAccessFn func(access BleGattAccess) (uint8, []byte)
+
+type BleDsc struct {
+	Uuid       BleUuid
+	AttFlags   BleAttFlags
+	MinKeySize int
+}
+
+type BleChr struct {
+	Uuid       BleUuid
+	Flags      BleChrFlags
+	MinKeySize int
+	AccessCb   BleGattAccessFn
+	Dscs       []BleDsc
+}
+
+type BleSvc struct {
+	Uuid    BleUuid
+	SvcType BleSvcType
+	Chrs    []BleChr
+}
+
+type BleChrId struct {
+	SvcUuid BleUuid
+	ChrUuid BleUuid
+}
+
+type BleMgmtChrs struct {
+	NmpReqChr        *BleChrId
+	NmpRspChr        *BleChrId
+	ResPublicReqChr  *BleChrId
+	ResPublicRspChr  *BleChrId
+	ResGwReqChr      *BleChrId
+	ResGwRspChr      *BleChrId
+	ResPrivateReqChr *BleChrId
+	ResPrivateRspChr *BleChrId
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/mgmt/transceiver.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/mgmt/transceiver.go
new file mode 100644
index 0000000..d43f48e
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/mgmt/transceiver.go
@@ -0,0 +1,202 @@
+package mgmt
+
+import (
+	"encoding/hex"
+	"fmt"
+	"sync"
+	"time"
+
+	log "github.com/Sirupsen/logrus"
+	"github.com/runtimeco/go-coap"
+
+	"mynewt.apache.org/newtmgr/nmxact/nmp"
+	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
+	"mynewt.apache.org/newtmgr/nmxact/oic"
+	"mynewt.apache.org/newtmgr/nmxact/omp"
+	"mynewt.apache.org/newtmgr/nmxact/sesn"
+)
+
+type TxFn func(req []byte) error
+
+type Transceiver struct {
+	// Only for plain NMP; nil for OMP transceivers.
+	nd *nmp.Dispatcher
+
+	// Used for OMP and CoAP resource requests.
+	od *omp.Dispatcher
+
+	wg sync.WaitGroup
+}
+
+func NewTransceiver(mgmtProto sesn.MgmtProto, logDepth int) (
+	*Transceiver, error) {
+
+	t := &Transceiver{}
+
+	if mgmtProto == sesn.MGMT_PROTO_NMP {
+		t.nd = nmp.NewDispatcher(logDepth)
+	}
+
+	od, err := omp.NewDispatcher(true, logDepth)
+	if err != nil {
+		return nil, err
+	}
+	t.od = od
+
+	return t, nil
+}
+
+func (t *Transceiver) txPlain(txCb TxFn, req *nmp.NmpMsg,
+	timeout time.Duration) (nmp.NmpRsp, error) {
+
+	nl, err := t.nd.AddListener(req.Hdr.Seq)
+	if err != nil {
+		return nil, err
+	}
+	defer t.nd.RemoveListener(req.Hdr.Seq)
+
+	b, err := nmp.EncodeNmpPlain(req)
+	if err != nil {
+		return nil, err
+	}
+
+	log.Debugf("Tx NMP request: %s", hex.Dump(b))
+
+	if err := txCb(b); err != nil {
+		return nil, err
+	}
+
+	// Now wait for NMP response.
+	for {
+		select {
+		case err := <-nl.ErrChan:
+			return nil, err
+		case rsp := <-nl.RspChan:
+			return rsp, nil
+		case <-nl.AfterTimeout(timeout):
+			return nil, nmxutil.NewRspTimeoutError("NMP timeout")
+		}
+	}
+}
+
+func (t *Transceiver) txOmp(txCb TxFn, req *nmp.NmpMsg, timeout time.Duration) (
+	nmp.NmpRsp, error) {
+
+	nl, err := t.od.AddNmpListener(req.Hdr.Seq)
+	if err != nil {
+		return nil, err
+	}
+	defer t.od.RemoveNmpListener(req.Hdr.Seq)
+
+	b, err := omp.EncodeOmpTcp(req)
+	if err != nil {
+		return nil, err
+	}
+
+	log.Debugf("Tx OMP request: %s", hex.Dump(b))
+
+	if err := txCb(b); err != nil {
+		return nil, err
+	}
+
+	// Now wait for NMP response.
+	for {
+		select {
+		case err := <-nl.ErrChan:
+			return nil, err
+		case rsp := <-nl.RspChan:
+			return rsp, nil
+		case <-nl.AfterTimeout(timeout):
+			return nil, nmxutil.NewRspTimeoutError("NMP timeout")
+		}
+	}
+}
+
+func (t *Transceiver) TxNmp(txCb TxFn, req *nmp.NmpMsg, timeout time.Duration) (
+	nmp.NmpRsp, error) {
+
+	if t.nd != nil {
+		return t.txPlain(txCb, req, timeout)
+	} else {
+		return t.txOmp(txCb, req, timeout)
+	}
+}
+
+func (t *Transceiver) TxOic(txCb TxFn, req coap.Message,
+	timeout time.Duration) (coap.Message, error) {
+
+	b, err := oic.Encode(req)
+	if err != nil {
+		return nil, err
+	}
+
+	var rspExpected bool
+	switch req.Type() {
+	case coap.Confirmable:
+		rspExpected = true
+	case coap.NonConfirmable:
+		rspExpected = req.Code() == coap.GET
+	default:
+		rspExpected = false
+	}
+
+	var ol *oic.Listener
+	if rspExpected {
+		ol, err = t.od.AddOicListener(req.Token())
+		if err != nil {
+			return nil, err
+		}
+		defer t.od.RemoveOicListener(req.Token())
+	}
+
+	log.Debugf("Tx OIC request: %s", hex.Dump(b))
+	if err := txCb(b); err != nil {
+		return nil, err
+	}
+
+	if !rspExpected {
+		return nil, nil
+	}
+
+	for {
+		select {
+		case err := <-ol.ErrChan:
+			return nil, err
+		case rsp := <-ol.RspChan:
+			return rsp, nil
+		case <-ol.AfterTimeout(timeout):
+			return nil, nmxutil.NewRspTimeoutError("OIC timeout")
+		}
+	}
+}
+
+func (t *Transceiver) DispatchNmpRsp(data []byte) {
+	if t.nd != nil {
+		t.nd.Dispatch(data)
+	} else {
+		t.od.Dispatch(data)
+	}
+}
+
+func (t *Transceiver) DispatchCoap(data []byte) {
+	t.od.Dispatch(data)
+}
+
+func (t *Transceiver) ErrorOne(seq uint8, err error) {
+	if t.nd != nil {
+		t.nd.ErrorOne(seq, err)
+	} else {
+		t.od.ErrorOneNmp(seq, err)
+	}
+}
+
+func (t *Transceiver) ErrorAll(err error) {
+	if t.nd != nil {
+		t.nd.ErrorAll(err)
+	}
+	t.od.ErrorAll(err)
+}
+
+func (t *Transceiver) AbortRx(seq uint8) {
+	t.ErrorOne(seq, fmt.Errorf("rx aborted"))
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_act.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_act.go
index 62c30ac..bd97133 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_act.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_act.go
@@ -158,8 +158,57 @@ func connCancel(x *BleXport, bl *Listener, r *BleConnCancelReq) error {
 }
 
 // Blocking.
+func discAllSvcs(x *BleXport, bl *Listener, r *BleDiscAllSvcsReq) (
+	[]*BleDiscSvc, error) {
+
+	const rspType = MSG_TYPE_DISC_ALL_SVCS
+	const evtType = MSG_TYPE_DISC_SVC_EVT
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return nil, err
+	}
+
+	if err := x.Tx(j); err != nil {
+		return nil, err
+	}
+
+	var svcs []*BleDiscSvc
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return nil, err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleDiscAllSvcsRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
+				}
+
+			case *BleDiscSvcEvt:
+				switch msg.Status {
+				case 0:
+					svcs = append(svcs, &msg.Svc)
+				case ERR_CODE_EDONE:
+					return svcs, nil
+				default:
+					return nil, StatusError(MSG_OP_EVT, evtType, msg.Status)
+				}
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return nil, BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
+// Blocking.
 func discSvcUuid(x *BleXport, bl *Listener, r *BleDiscSvcUuidReq) (
-	*BleSvc, error) {
+	*BleDiscSvc, error) {
 
 	const rspType = MSG_TYPE_DISC_SVC_UUID
 	const evtType = MSG_TYPE_DISC_SVC_EVT
@@ -173,7 +222,7 @@ func discSvcUuid(x *BleXport, bl *Listener, r *BleDiscSvcUuidReq) (
 		return nil, err
 	}
 
-	var svc *BleSvc
+	var svc *BleDiscSvc
 	for {
 		select {
 		case err := <-bl.ErrChan:
@@ -214,7 +263,7 @@ func discSvcUuid(x *BleXport, bl *Listener, r *BleDiscSvcUuidReq) (
 
 // Blocking.
 func discAllChrs(x *BleXport, bl *Listener, r *BleDiscAllChrsReq) (
-	[]*BleChr, error) {
+	[]*BleDiscChr, error) {
 
 	const rspType = MSG_TYPE_DISC_ALL_CHRS
 	const evtType = MSG_TYPE_DISC_CHR_EVT
@@ -228,7 +277,7 @@ func discAllChrs(x *BleXport, bl *Listener, r *BleDiscAllChrsReq) (
 		return nil, err
 	}
 
-	chrs := []*BleChr{}
+	chrs := []*BleDiscChr{}
 	for {
 		select {
 		case err := <-bl.ErrChan:
@@ -262,6 +311,101 @@ func discAllChrs(x *BleXport, bl *Listener, r *BleDiscAllChrsReq) (
 }
 
 // Blocking.
+func discAllDscs(x *BleXport, bl *Listener, r *BleDiscAllDscsReq) (
+	[]*BleDiscDsc, error) {
+
+	const rspType = MSG_TYPE_DISC_ALL_DSCS
+	const evtType = MSG_TYPE_DISC_DSC_EVT
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return nil, err
+	}
+
+	if err := x.Tx(j); err != nil {
+		return nil, err
+	}
+
+	dscs := []*BleDiscDsc{}
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return nil, err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleDiscAllDscsRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
+				}
+
+			case *BleDiscDscEvt:
+				switch msg.Status {
+				case 0:
+					dscs = append(dscs, &msg.Dsc)
+				case ERR_CODE_EDONE:
+					return dscs, nil
+				default:
+					return nil, StatusError(MSG_OP_EVT, evtType, msg.Status)
+				}
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return nil, BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
+// Blocking.
+func write(x *BleXport, bl *Listener, r *BleWriteReq) error {
+	const rspType = MSG_TYPE_WRITE_CMD
+	const evtType = MSG_TYPE_WRITE_ACK_EVT
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return err
+	}
+
+	if err := x.Tx(j); err != nil {
+		return err
+	}
+
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleWriteRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return StatusError(MSG_OP_RSP, rspType, msg.Status)
+				} else {
+					return nil
+				}
+
+			case *BleDiscChrEvt:
+				switch msg.Status {
+				case 0:
+					return nil
+				default:
+					return StatusError(MSG_OP_EVT, evtType, msg.Status)
+				}
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
+// Blocking.
 func writeCmd(x *BleXport, bl *Listener, r *BleWriteCmdReq) error {
 	const rspType = MSG_TYPE_WRITE_CMD
 
@@ -299,6 +443,82 @@ func writeCmd(x *BleXport, bl *Listener, r *BleWriteCmdReq) error {
 }
 
 // Blocking.
+func notify(x *BleXport, bl *Listener, r *BleNotifyReq) error {
+	const rspType = MSG_TYPE_NOTIFY
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return err
+	}
+
+	if err := x.Tx(j); err != nil {
+		return err
+	}
+
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleNotifyRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return StatusError(MSG_OP_RSP, rspType, msg.Status)
+				} else {
+					return nil
+				}
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
+// Blocking.
+func findChr(x *BleXport, bl *Listener, r *BleFindChrReq) (
+	uint16, uint16, error) {
+
+	const rspType = MSG_TYPE_NOTIFY
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return 0, 0, err
+	}
+
+	if err := x.Tx(j); err != nil {
+		return 0, 0, err
+	}
+
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return 0, 0, err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleFindChrRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return 0, 0, StatusError(MSG_OP_RSP, rspType, msg.Status)
+				} else {
+					return msg.DefHandle, msg.ValHandle, nil
+				}
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return 0, 0, BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
+// Blocking.
 func exchangeMtu(x *BleXport, bl *Listener, r *BleExchangeMtuReq) (
 	int, error) {
 
@@ -533,37 +753,47 @@ func encInitiate(x *BleXport, bl *Listener,
 }
 
 // Blocking
-func advStart(x *BleXport, bl *Listener, r *BleAdvStartReq) error {
+func advStart(x *BleXport, bl *Listener, r *BleAdvStartReq) (uint16, error) {
 	const rspType = MSG_TYPE_ADV_START
 
 	j, err := json.Marshal(r)
 	if err != nil {
-		return err
+		return 0, err
 	}
 
 	if err := x.Tx(j); err != nil {
-		return err
+		return 0, err
 	}
 
 	for {
 		select {
 		case err := <-bl.ErrChan:
-			return err
+			return 0, err
 
 		case bm := <-bl.MsgChan:
 			switch msg := bm.(type) {
 			case *BleAdvStartRsp:
 				bl.Acked = true
 				if msg.Status != 0 {
-					return StatusError(MSG_OP_RSP, rspType, msg.Status)
+					return 0, StatusError(MSG_OP_RSP, rspType, msg.Status)
+				}
+
+			case *BleConnectEvt:
+				if msg.Status == 0 {
+					return msg.ConnHandle, nil
+				} else {
+					str := fmt.Sprintf("BLE peer failed to connect to us; "+
+						"status=%s (%d)",
+						ErrCodeToString(msg.Status), msg.Status)
+					log.Debugf(str)
+					return 0, nmxutil.NewBleHostError(msg.Status, str)
 				}
-				return nil
 
 			default:
 			}
 
 		case <-bl.AfterTimeout(x.RspTimeout()):
-			return BhdTimeoutError(rspType, r.Seq)
+			return 0, BhdTimeoutError(rspType, r.Seq)
 		}
 	}
 }
@@ -704,7 +934,105 @@ func advFields(x *BleXport, bl *Listener, r *BleAdvFieldsReq) (
 					return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
 				}
 
-				return msg.Data, nil
+				return msg.Data.Bytes, nil
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return nil, BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
+func clearSvcs(x *BleXport, bl *Listener, r *BleClearSvcsReq) error {
+	const rspType = MSG_TYPE_CLEAR_SVCS
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return err
+	}
+
+	x.txNoSync(j)
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleClearSvcsRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return StatusError(MSG_OP_RSP, rspType, msg.Status)
+				}
+				return nil
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
+func addSvcs(x *BleXport, bl *Listener, r *BleAddSvcsReq) error {
+	const rspType = MSG_TYPE_ADD_SVCS
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return err
+	}
+
+	x.txNoSync(j)
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleAddSvcsRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return StatusError(MSG_OP_RSP, rspType, msg.Status)
+				}
+				return nil
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
+func commitSvcs(x *BleXport, bl *Listener, r *BleCommitSvcsReq) (
+	[]BleRegSvc, error) {
+
+	const rspType = MSG_TYPE_COMMIT_SVCS
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return nil, err
+	}
+
+	x.txNoSync(j)
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return nil, err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleCommitSvcsRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
+				}
+				return msg.Svcs, nil
 
 			default:
 			}
@@ -715,6 +1043,38 @@ func advFields(x *BleXport, bl *Listener, r *BleAdvFieldsReq) (
 	}
 }
 
+func accessStatus(x *BleXport, bl *Listener, r *BleAccessStatusReq) error {
+	const rspType = MSG_TYPE_ACCESS_STATUS
+
+	j, err := json.Marshal(r)
+	if err != nil {
+		return err
+	}
+
+	x.Tx(j)
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return err
+
+		case bm := <-bl.MsgChan:
+			switch msg := bm.(type) {
+			case *BleAccessStatusRsp:
+				bl.Acked = true
+				if msg.Status != 0 {
+					return StatusError(MSG_OP_RSP, rspType, msg.Status)
+				}
+				return nil
+
+			default:
+			}
+
+		case <-bl.AfterTimeout(x.RspTimeout()):
+			return BhdTimeoutError(rspType, r.Seq)
+		}
+	}
+}
+
 // Asks the controller to generate a random address.  This is done when the
 // transport is starting up, and therefore does not require the transport to be
 // synced.  Only the transport should call this function.
@@ -821,6 +1181,7 @@ func setPreferredMtu(x *BleXport, bl *Listener,
 
 		case <-bl.AfterTimeout(x.RspTimeout()):
 			return BhdTimeoutError(rspType, r.Seq)
+
 		}
 	}
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_advertiser.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_advertiser.go
new file mode 100644
index 0000000..c6b012d
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_advertiser.go
@@ -0,0 +1,217 @@
+package nmble
+
+import (
+	"fmt"
+
+	log "github.com/Sirupsen/logrus"
+
+	"mynewt.apache.org/newtmgr/nmxact/adv"
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
+	"mynewt.apache.org/newtmgr/nmxact/sesn"
+)
+
+type Advertiser struct {
+	bx          *BleXport
+	stopChan    chan struct{}
+	stoppedChan chan struct{}
+}
+
+func NewAdvertiser(bx *BleXport) *Advertiser {
+	return &Advertiser{
+		bx: bx,
+	}
+}
+
+func (a *Advertiser) fields(f BleAdvFields) ([]byte, error) {
+	r := BleAdvFieldsToReq(f)
+
+	bl, err := a.bx.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return nil, err
+	}
+	defer a.bx.RemoveListener(bl)
+
+	return advFields(a.bx, bl, r)
+}
+
+func (a *Advertiser) setAdvData(data []byte) error {
+	r := NewBleAdvSetDataReq()
+	r.Data = BleBytes{data}
+
+	bl, err := a.bx.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer a.bx.RemoveListener(bl)
+
+	if err := advSetData(a.bx, bl, r); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (a *Advertiser) setRspData(data []byte) error {
+	r := NewBleAdvRspSetDataReq()
+	r.Data = BleBytes{data}
+
+	bl, err := a.bx.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer a.bx.RemoveListener(bl)
+
+	if err := advRspSetData(a.bx, bl, r); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (a *Advertiser) advertise(cfg adv.Cfg) (uint16, *Listener, error) {
+	r := NewBleAdvStartReq()
+
+	r.OwnAddrType = cfg.Ble.OwnAddrType
+	r.DurationMs = 0x7fffffff
+	r.ConnMode = cfg.Ble.ConnMode
+	r.DiscMode = cfg.Ble.DiscMode
+	r.ItvlMin = cfg.Ble.ItvlMin
+	r.ItvlMax = cfg.Ble.ItvlMax
+	r.ChannelMap = cfg.Ble.ChannelMap
+	r.FilterPolicy = cfg.Ble.FilterPolicy
+	r.HighDutyCycle = cfg.Ble.HighDutyCycle
+	r.PeerAddr = cfg.Ble.PeerAddr
+
+	bl, err := a.bx.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return 0, nil, err
+	}
+
+	connHandle, err := advStart(a.bx, bl, r)
+	if err != nil {
+		a.bx.RemoveListener(bl)
+		if !nmxutil.IsXport(err) {
+			// The transport did not restart; always attempt to cancel the
+			// advertise operation.  In some cases, the host has already stopped
+			// advertising and will respond with an "ealready" error that can be
+			// ignored.
+			if err := a.stopAdvertising(); err != nil {
+				log.Errorf("Failed to cancel advertise in progress: %s",
+					err.Error())
+			}
+		}
+		return 0, nil, err
+	}
+
+	return connHandle, bl, nil
+}
+
+func (a *Advertiser) stopAdvertising() error {
+	r := NewBleAdvStopReq()
+
+	bl, err := a.bx.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer a.bx.RemoveListener(bl)
+
+	return advStop(a.bx, bl, r)
+}
+
+func (a *Advertiser) buildSesn(cfg adv.Cfg, connHandle uint16, bl *Listener) (
+	sesn.Sesn, error) {
+
+	s, err := NewBleSesn(a.bx, cfg.Ble.SesnCfg)
+	if err != nil {
+		return nil, err
+	}
+
+	//if err := s.OpenConnected(connHandle, bl); err != nil {
+	//return nil, err
+	//}
+
+	return s, nil
+}
+
+func (a *Advertiser) Start(cfg adv.Cfg) (sesn.Sesn, error) {
+	var advData []byte
+	var rspData []byte
+	var connHandle uint16
+	var bl *Listener
+	var err error
+
+	fns := []func() error{
+		// Convert advertising fields to data.
+		func() error {
+			advData, err = a.fields(cfg.Ble.AdvFields)
+			return err
+		},
+
+		// Set advertising data.
+		func() error {
+			return a.setAdvData(advData)
+		},
+
+		// Convert response fields to data.
+		func() error {
+			rspData, err = a.fields(cfg.Ble.RspFields)
+			return err
+		},
+
+		// Set response data.
+		func() error {
+			return a.setRspData(rspData)
+		},
+
+		// Advertise
+		func() error {
+			connHandle, bl, err = a.advertise(cfg)
+			return err
+		},
+	}
+
+	a.stopChan = make(chan struct{})
+	a.stoppedChan = make(chan struct{})
+
+	defer func() {
+		a.stopChan = nil
+		close(a.stoppedChan)
+	}()
+
+	if err := a.bx.AcquireSlave(a); err != nil {
+		return nil, err
+	}
+	defer a.bx.ReleaseSlave()
+
+	for _, fn := range fns {
+		// Check for abort before each step.
+		select {
+		case <-a.stopChan:
+			return nil, fmt.Errorf("advertise aborted")
+		default:
+		}
+
+		if err := fn(); err != nil {
+			return nil, err
+		}
+	}
+
+	return a.buildSesn(cfg, connHandle, bl)
+}
+
+func (a *Advertiser) Stop() error {
+	stopChan := a.stopChan
+	if stopChan == nil {
+		return fmt.Errorf("advertiser already stopped")
+	}
+	close(stopChan)
+
+	a.bx.StopWaitingForSlave(a, fmt.Errorf("advertise aborted"))
+	a.stopAdvertising()
+
+	// Block until abort is complete.
+	<-a.stoppedChan
+
+	return nil
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_fsm.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_fsm.go
deleted file mode 100644
index 8d2fd1c..0000000
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_fsm.go
+++ /dev/null
@@ -1,815 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package nmble
-
-import (
-	"encoding/hex"
-	"fmt"
-	"strings"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	log "github.com/Sirupsen/logrus"
-	"github.com/runtimeco/go-coap"
-
-	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
-	"mynewt.apache.org/newtmgr/nmxact/nmp"
-	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
-	"mynewt.apache.org/newtmgr/nmxact/oic"
-)
-
-var nextId uint32
-
-func getNextId() uint32 {
-	return atomic.AddUint32(&nextId, 1) - 1
-}
-
-const DFLT_ATT_MTU = 23
-
-type BleSesnState int32
-
-const (
-	SESN_STATE_UNCONNECTED     BleSesnState = 0
-	SESN_STATE_CONNECTING                   = 1
-	SESN_STATE_EXCHANGE_MTU                 = 2
-	SESN_STATE_DISCOVER_SVC                 = 3
-	SESN_STATE_DISCOVER_CHR                 = 4
-	SESN_STATE_SECURITY                     = 5
-	SESN_STATE_SUBSCRIBE                    = 6
-	SESN_STATE_DONE                         = 7
-	SESN_STATE_TERMINATING                  = 8
-	SESN_STATE_CONN_CANCELLING              = 9
-)
-
-type BleFsmDisconnectType int
-
-const (
-	FSM_DISCONNECT_TYPE_UNOPENED BleFsmDisconnectType = iota
-	FSM_DISCONNECT_TYPE_IMMEDIATE_TIMEOUT
-	FSM_DISCONNECT_TYPE_OPENED
-	FSM_DISCONNECT_TYPE_REQUESTED
-)
-
-type BleDisconnectEntry struct {
-	Dt   BleFsmDisconnectType
-	Peer BleDev
-	Err  error
-}
-
-type BleFsmParamsCentral struct {
-	PeerDev     BleDev
-	ConnTries   int
-	ConnTimeout time.Duration
-}
-
-type BleFsmParams struct {
-	Bx          *BleXport
-	OwnAddrType BleAddrType
-	EncryptWhen BleEncryptWhen
-	Central     BleFsmParamsCentral
-	SvcUuids    []BleUuid
-	ReqChrUuid  BleUuid
-	RspChrUuid  BleUuid
-}
-
-type BleFsm struct {
-	params BleFsmParams
-
-	connHandle     uint16
-	peerDev        BleDev
-	nmpSvc         *BleSvc
-	nmpReqChr      *BleChr
-	nmpRspChr      *BleChr
-	prevDisconnect BleDisconnectEntry
-	attMtu         int
-	state          BleSesnState
-	rxer           *Receiver
-	errFunnel      nmxutil.ErrFunnel
-	id             uint32
-	wg             sync.WaitGroup
-
-	encBcast       nmxutil.Bcaster
-	disconnectChan chan struct{}
-	rxNmpChan      chan []byte
-}
-
-func NewBleFsm(p BleFsmParams) *BleFsm {
-	bf := &BleFsm{
-		params: p,
-
-		attMtu: DFLT_ATT_MTU,
-		id:     getNextId(),
-	}
-
-	bf.rxer = NewReceiver(bf.id, p.Bx, 1)
-
-	bf.errFunnel.AccumDelay = 250 * time.Millisecond
-	bf.errFunnel.LessCb = fsmErrorLess
-
-	return bf
-}
-
-func (bf *BleFsm) disconnectError(reason int) error {
-	str := fmt.Sprintf("BLE peer disconnected; "+
-		"reason=\"%s\" (%d) peer=%s handle=%d",
-		ErrCodeToString(reason), reason, bf.peerDev.String(),
-		bf.connHandle)
-	return nmxutil.NewBleSesnDisconnectError(reason, str)
-}
-
-func (bf *BleFsm) closedError(msg string) error {
-	return nmxutil.NewSesnClosedError(
-		fmt.Sprintf("%s; state=%d", msg, bf.state))
-}
-
-func (bf *BleFsm) connInfo() (BleConnDesc, error) {
-	return ConnFindXact(bf.params.Bx, bf.connHandle)
-}
-
-func (bf *BleFsm) logConnection() {
-	desc, err := bf.connInfo()
-	if err != nil {
-		return
-	}
-
-	log.Debugf("BLE connection attempt succeeded; %s", desc.String())
-}
-
-func fsmErrorLess(a error, b error) bool {
-	aIsXport := nmxutil.IsXport(a)
-	bIsXport := nmxutil.IsXport(b)
-	aIsTerm := nmxutil.IsBleSesnDisconnect(a)
-	bIsTerm := nmxutil.IsBleSesnDisconnect(b)
-
-	if aIsXport {
-		return false
-	}
-
-	if aIsTerm {
-		return !bIsXport && !bIsTerm
-	}
-
-	return false
-}
-
-func calcDisconnectType(state BleSesnState) BleFsmDisconnectType {
-	switch state {
-	case SESN_STATE_EXCHANGE_MTU:
-		return FSM_DISCONNECT_TYPE_IMMEDIATE_TIMEOUT
-
-	case SESN_STATE_DONE:
-		return FSM_DISCONNECT_TYPE_OPENED
-
-	case SESN_STATE_TERMINATING, SESN_STATE_CONN_CANCELLING:
-		return FSM_DISCONNECT_TYPE_REQUESTED
-
-	default:
-		return FSM_DISCONNECT_TYPE_UNOPENED
-	}
-}
-
-func (bf *BleFsm) shutdown(err error) {
-	bf.params.Bx.StopWaitingForMaster(bf, err)
-	bf.rxer.RemoveAll("shutdown")
-
-	bf.state = SESN_STATE_UNCONNECTED
-
-	// Wait for all listeners to get removed.
-	bf.rxer.WaitUntilNoListeners()
-	bf.wg.Wait()
-
-	close(bf.rxNmpChan)
-	close(bf.disconnectChan)
-}
-
-// Listens for an error in the state machine.  On error, the session is
-// considered disconnected and the error is reported to the client.
-func (bf *BleFsm) listenForError() {
-	bf.wg.Add(1)
-
-	go func() {
-		err := <-bf.errFunnel.Wait()
-
-		dt := calcDisconnectType(bf.state)
-		bf.prevDisconnect = BleDisconnectEntry{dt, bf.peerDev, err}
-
-		bf.wg.Done()
-		bf.shutdown(err)
-	}()
-}
-
-// Listens for events in the background.
-func (bf *BleFsm) eventListen(bl *Listener, seq BleSeq) error {
-	bf.wg.Add(1)
-
-	go func() {
-		defer bf.wg.Done()
-		defer bf.rxer.RemoveListener("connect", bl)
-
-		for {
-			select {
-			case err := <-bl.ErrChan:
-				bf.errFunnel.Insert(err)
-				return
-
-			case bm := <-bl.MsgChan:
-				switch msg := bm.(type) {
-				case *BleMtuChangeEvt:
-					if msg.Status != 0 {
-						err := StatusError(MSG_OP_EVT,
-							MSG_TYPE_MTU_CHANGE_EVT,
-							msg.Status)
-						log.Debugf(err.Error())
-					} else {
-						log.Debugf("BLE ATT MTU updated; from=%d to=%d",
-							bf.attMtu, msg.Mtu)
-						bf.attMtu = int(msg.Mtu)
-					}
-
-				case *BleEncChangeEvt:
-					var err error
-					if msg.Status != 0 {
-						err = StatusError(MSG_OP_EVT,
-							MSG_TYPE_ENC_CHANGE_EVT,
-							msg.Status)
-						log.Debugf(err.Error())
-					} else {
-						log.Debugf("Connection encrypted; conn_handle=%d",
-							msg.ConnHandle)
-					}
-
-					// Notify any listeners of the encryption change event.
-					bf.encBcast.SendAndClear(err)
-
-				case *BleDisconnectEvt:
-					err := bf.disconnectError(msg.Reason)
-					bf.errFunnel.Insert(err)
-					return
-
-				default:
-				}
-			}
-		}
-	}()
-	return nil
-}
-
-func (bf *BleFsm) nmpRspListen() error {
-	key := TchKey(MSG_TYPE_NOTIFY_RX_EVT, int(bf.connHandle))
-	bl, err := bf.rxer.AddListener("nmp-rsp", key)
-	if err != nil {
-		return err
-	}
-
-	bf.wg.Add(1)
-
-	go func() {
-		defer bf.wg.Done()
-		defer bf.rxer.RemoveListener("nmp-rsp", bl)
-
-		for {
-			select {
-			case err, ok := <-bl.ErrChan:
-				if ok {
-					bf.errFunnel.Insert(err)
-				}
-				return
-			case bm := <-bl.MsgChan:
-				switch msg := bm.(type) {
-				case *BleNotifyRxEvt:
-					if bf.nmpRspChr != nil &&
-						msg.AttrHandle == bf.nmpRspChr.ValHandle {
-
-						bf.rxNmpChan <- msg.Data.Bytes
-					}
-				}
-			}
-		}
-	}()
-	return nil
-}
-
-func (bf *BleFsm) connect() error {
-	bf.peerDev = bf.params.Central.PeerDev
-
-	r := NewBleConnectReq()
-	r.OwnAddrType = bf.params.OwnAddrType
-	r.PeerAddrType = bf.peerDev.AddrType
-	r.PeerAddr = bf.peerDev.Addr
-
-	// Initiating a connection requires dedicated master privileges.
-	if err := bf.params.Bx.AcquireMaster(bf); err != nil {
-		return err
-	}
-	defer bf.params.Bx.ReleaseMaster()
-
-	bl, err := bf.rxer.AddListener("connect", SeqKey(r.Seq))
-	if err != nil {
-		return err
-	}
-
-	// Connection operation now in progress.
-	bf.state = SESN_STATE_CONNECTING
-
-	// Tell blehostd to initiate connection.
-	if bf.connHandle, err = connect(bf.params.Bx, bl, r,
-		bf.params.Central.ConnTimeout); err != nil {
-
-		bhe := nmxutil.ToBleHost(err)
-		if bhe != nil && bhe.Status == ERR_CODE_EDONE {
-			// Already connected.
-			bf.rxer.RemoveListener("connect", bl)
-			return nil
-		} else if !nmxutil.IsXport(err) {
-			// The transport did not restart; always attempt to cancel the
-			// connect operation.  In most cases, the host has already stopped
-			// connecting and will respond with an "ealready" error that can be
-			// ignored.
-			if err := bf.connCancel(); err != nil {
-				log.Errorf("Failed to cancel connect in progress: %s",
-					err.Error())
-			}
-		}
-
-		bf.rxer.RemoveListener("connect", bl)
-		return err
-	}
-
-	// Listen for events in the background.
-	if err := bf.eventListen(bl, r.Seq); err != nil {
-		return err
-	}
-
-	// Listen for NMP responses in the background.
-	if err := bf.nmpRspListen(); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (bf *BleFsm) terminateSetState() error {
-	switch bf.state {
-	case SESN_STATE_UNCONNECTED,
-		SESN_STATE_CONNECTING,
-		SESN_STATE_CONN_CANCELLING:
-		return fmt.Errorf("BLE terminate failed; not connected")
-	case SESN_STATE_TERMINATING:
-		return fmt.Errorf(
-			"BLE terminate failed; session already being closed")
-	default:
-		bf.state = SESN_STATE_TERMINATING
-	}
-
-	return nil
-}
-
-func (bf *BleFsm) terminate() error {
-	if err := bf.terminateSetState(); err != nil {
-		return err
-	}
-
-	r := NewBleTerminateReq()
-	r.ConnHandle = bf.connHandle
-	r.HciReason = ERR_CODE_HCI_REM_USER_CONN_TERM
-
-	bl, err := bf.rxer.AddListener("terminate", SeqKey(r.Seq))
-	if err != nil {
-		return err
-	}
-	defer bf.rxer.RemoveListener("terminate", bl)
-
-	if err := terminate(bf.params.Bx, bl, r); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (bf *BleFsm) connCancel() error {
-	r := NewBleConnCancelReq()
-
-	bl, err := bf.rxer.AddListener("conn-cancel", SeqKey(r.Seq))
-	if err != nil {
-		return err
-	}
-	defer bf.rxer.RemoveListener("conn-cancel", bl)
-
-	if err := connCancel(bf.params.Bx, bl, r); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (bf *BleFsm) discSvcUuidOnce(uuid BleUuid) (*BleSvc, error) {
-	r := NewBleDiscSvcUuidReq()
-	r.ConnHandle = bf.connHandle
-	r.Uuid = uuid
-
-	bl, err := bf.rxer.AddListener("disc-svc-uuid", SeqKey(r.Seq))
-	if err != nil {
-		return nil, err
-	}
-	defer bf.rxer.RemoveListener("disc-svc-uuid", bl)
-
-	svc, err := discSvcUuid(bf.params.Bx, bl, r)
-	if err != nil {
-		bhe := nmxutil.ToBleHost(err)
-		if bhe != nil && bhe.Status == ERR_CODE_EDONE {
-			return nil, nil
-		} else {
-			return nil, err
-		}
-	}
-
-	return svc, nil
-}
-
-func (bf *BleFsm) discSvcUuid() error {
-	for _, uuid := range bf.params.SvcUuids {
-		svc, err := bf.discSvcUuidOnce(uuid)
-		if err != nil {
-			return err
-		}
-
-		if svc != nil {
-			bf.nmpSvc = svc
-			return nil
-		}
-	}
-
-	strs := []string{}
-	for _, uuid := range bf.params.SvcUuids {
-		strs = append(strs, uuid.String())
-	}
-
-	return fmt.Errorf("Peer does not support any required services: %s",
-		strings.Join(strs, ", "))
-}
-
-func (bf *BleFsm) encInitiate() error {
-	r := NewBleSecurityInitiateReq()
-	r.ConnHandle = bf.connHandle
-
-	bl, err := bf.rxer.AddListener("enc-initiate", SeqKey(r.Seq))
-	if err != nil {
-		return err
-	}
-	defer bf.rxer.RemoveListener("enc-initiate", bl)
-
-	// Initiate the encryption procedure.
-	if err := encInitiate(bf.params.Bx, bl, r); err != nil {
-		return err
-	}
-
-	// Block until the procedure completes.
-	itf := <-bf.encBcast.Listen()
-	return itf.(error)
-}
-
-func (bf *BleFsm) discAllChrs() error {
-	r := NewBleDiscAllChrsReq()
-	r.ConnHandle = bf.connHandle
-	r.StartHandle = bf.nmpSvc.StartHandle
-	r.EndHandle = bf.nmpSvc.EndHandle
-
-	bl, err := bf.rxer.AddListener("disc-all-chrs", SeqKey(r.Seq))
-	if err != nil {
-		return err
-	}
-	defer bf.rxer.RemoveListener("disc-all-chrs", bl)
-
-	chrs, err := discAllChrs(bf.params.Bx, bl, r)
-	if err != nil {
-		return err
-	}
-
-	for _, c := range chrs {
-		if CompareUuids(bf.params.ReqChrUuid, c.Uuid) == 0 {
-			bf.nmpReqChr = c
-		}
-		if CompareUuids(bf.params.RspChrUuid, c.Uuid) == 0 {
-			bf.nmpRspChr = c
-		}
-	}
-
-	if bf.nmpReqChr == nil {
-		return fmt.Errorf(
-			"Peer doesn't support required characteristic: %s",
-			bf.params.ReqChrUuid.String())
-	}
-
-	if bf.nmpRspChr == nil {
-		return fmt.Errorf(
-			"Peer doesn't support required characteristic: %s",
-			bf.params.RspChrUuid.String())
-	}
-
-	return nil
-}
-
-func (bf *BleFsm) exchangeMtu() error {
-	r := NewBleExchangeMtuReq()
-	r.ConnHandle = bf.connHandle
-
-	bl, err := bf.rxer.AddListener("exchange-mtu", SeqKey(r.Seq))
-	if err != nil {
-		return err
-	}
-	defer bf.rxer.RemoveListener("exchange-mtu", bl)
-
-	mtu, err := exchangeMtu(bf.params.Bx, bl, r)
-	if err != nil {
-		return err
-	}
-
-	bf.attMtu = mtu
-	return nil
-}
-
-func (bf *BleFsm) writeCmd(data []byte) error {
-	r := NewBleWriteCmdReq()
-	r.ConnHandle = bf.connHandle
-	r.AttrHandle = bf.nmpReqChr.ValHandle
-	r.Data.Bytes = data
-
-	bl, err := bf.rxer.AddListener("write-cmd", SeqKey(r.Seq))
-	if err != nil {
-		return err
-	}
-	defer bf.rxer.RemoveListener("write-cmd", bl)
-
-	if err := writeCmd(bf.params.Bx, bl, r); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (bf *BleFsm) subscribe() error {
-	r := NewBleWriteCmdReq()
-	r.ConnHandle = bf.connHandle
-	r.AttrHandle = bf.nmpRspChr.ValHandle + 1
-	r.Data.Bytes = []byte{1, 0}
-
-	bl, err := bf.rxer.AddListener("subscribe", SeqKey(r.Seq))
-	if err != nil {
-		return err
-	}
-	defer bf.rxer.RemoveListener("subscribe", bl)
-
-	if err := writeCmd(bf.params.Bx, bl, r); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (bf *BleFsm) shouldEncrypt() bool {
-	switch bf.params.EncryptWhen {
-	case BLE_ENCRYPT_NEVER:
-		return false
-
-	case BLE_ENCRYPT_ALWAYS:
-		return true
-
-	case BLE_ENCRYPT_PRIV_ONLY:
-		return bf.peerDev.AddrType == BLE_ADDR_TYPE_RPA_PUB ||
-			bf.peerDev.AddrType == BLE_ADDR_TYPE_RPA_RND
-
-	default:
-		log.Errorf("Invalid BleEncryptWhen value: %d",
-			bf.params.EncryptWhen)
-		return false
-	}
-}
-
-func (bf *BleFsm) executeState() (bool, error) {
-	switch bf.state {
-	case SESN_STATE_UNCONNECTED:
-		if err := bf.connect(); err != nil {
-			return false, err
-		}
-		bf.state = SESN_STATE_EXCHANGE_MTU
-
-	case SESN_STATE_EXCHANGE_MTU:
-		if err := bf.exchangeMtu(); err != nil {
-			bhe := nmxutil.ToBleHost(err)
-			retry := bhe != nil && bhe.Status == ERR_CODE_ENOTCONN
-			return retry, err
-		}
-		bf.state = SESN_STATE_DISCOVER_SVC
-
-	case SESN_STATE_DISCOVER_SVC:
-		if err := bf.discSvcUuid(); err != nil {
-			return false, err
-		}
-		bf.state = SESN_STATE_DISCOVER_CHR
-
-	case SESN_STATE_DISCOVER_CHR:
-		if err := bf.discAllChrs(); err != nil {
-			return false, err
-		}
-		if bf.shouldEncrypt() {
-			bf.state = SESN_STATE_SECURITY
-		} else {
-			bf.state = SESN_STATE_SUBSCRIBE
-		}
-
-	case SESN_STATE_SECURITY:
-		if err := bf.encInitiate(); err != nil {
-			return false, err
-		}
-		bf.state = SESN_STATE_SUBSCRIBE
-
-	case SESN_STATE_SUBSCRIBE:
-		if err := bf.subscribe(); err != nil {
-			return false, err
-		}
-		bf.state = SESN_STATE_DONE
-
-	case SESN_STATE_DONE:
-		/* Open complete. */
-		return false, fmt.Errorf("BleFsm already done being opened")
-
-	default:
-		return false, fmt.Errorf("BleFsm already being opened")
-	}
-
-	return false, nil
-}
-
-func (bf *BleFsm) DisconnectChan() <-chan struct{} {
-	return bf.disconnectChan
-}
-
-func (bf *BleFsm) RxNmpChan() <-chan []byte {
-	return bf.rxNmpChan
-}
-
-func (bf *BleFsm) PrevDisconnect() BleDisconnectEntry {
-	return bf.prevDisconnect
-}
-
-func (bf *BleFsm) startOnce() (bool, error) {
-	if !bf.IsClosed() {
-		return false, nmxutil.NewSesnAlreadyOpenError(fmt.Sprintf(
-			"Attempt to open an already-open BLE session (state=%d)",
-			bf.state))
-	}
-
-	bf.disconnectChan = make(chan struct{})
-	bf.rxNmpChan = make(chan []byte)
-
-	bf.listenForError()
-
-	for {
-		retry, err := bf.executeState()
-		if err != nil {
-			// If stop fails, assume the connection wasn't established and
-			// force an error.
-			if bf.Stop() != nil {
-				bf.errFunnel.Insert(err)
-			}
-			<-bf.disconnectChan
-			return retry, err
-		} else if bf.state == SESN_STATE_DONE {
-			// We are fully connected.  Listen for errors in the background.
-			return false, nil
-		}
-	}
-}
-
-// @return bool                 Whether another start attempt should be made;
-//         error                The error that caused the start attempt to
-//                                  fail; nil on success.
-func (bf *BleFsm) Start() error {
-	var err error
-
-	for i := 0; i < bf.params.Central.ConnTries; i++ {
-		var retry bool
-		retry, err = bf.startOnce()
-		if !retry {
-			break
-		}
-	}
-
-	if err != nil {
-		nmxutil.Assert(!bf.IsOpen())
-		nmxutil.Assert(bf.IsClosed())
-		return err
-	}
-
-	return nil
-}
-
-// @return bool                 true if stop complete;
-//                              false if disconnect is now pending.
-func (bf *BleFsm) Stop() error {
-	state := bf.state
-
-	switch state {
-	case SESN_STATE_UNCONNECTED,
-		SESN_STATE_TERMINATING,
-		SESN_STATE_CONN_CANCELLING:
-
-		return bf.closedError("Attempt to close an unopened BLE session")
-
-	case SESN_STATE_CONNECTING:
-		bf.connCancel()
-		bf.errFunnel.Insert(fmt.Errorf("Connection attempt cancelled"))
-		return nil
-
-	default:
-		if err := bf.terminate(); err != nil {
-			return err
-		}
-		return nil
-	}
-}
-
-func (bf *BleFsm) IsOpen() bool {
-	return bf.state == SESN_STATE_DONE
-}
-
-func (bf *BleFsm) IsClosed() bool {
-	return bf.state == SESN_STATE_UNCONNECTED
-}
-
-func (bf *BleFsm) TxNmp(payload []byte, nl *nmp.Listener,
-	timeout time.Duration) (nmp.NmpRsp, error) {
-
-	log.Debugf("Tx NMP request: %s", hex.Dump(payload))
-	if err := bf.writeCmd(payload); err != nil {
-		return nil, err
-	}
-
-	// Now wait for NMP response.
-	for {
-		select {
-		case err := <-nl.ErrChan:
-			return nil, err
-		case rsp := <-nl.RspChan:
-			// Only accept NMP responses if the session is still open.  This is
-			// to help prevent race conditions in client code.
-			if bf.IsOpen() {
-				return rsp, nil
-			}
-		case <-nl.AfterTimeout(timeout):
-			msg := fmt.Sprintf(
-				"NMP timeout; op=%d group=%d id=%d seq=%d peer=%#v",
-				payload[0], payload[4]+payload[5]<<8,
-				payload[7], payload[6], bf.peerDev)
-
-			return nil, nmxutil.NewRspTimeoutError(msg)
-		}
-	}
-}
-
-func (bf *BleFsm) TxOic(payload []byte, ol *oic.Listener,
-	timeout time.Duration) (*coap.Message, error) {
-
-	log.Debugf("Tx OIC request: %s", hex.Dump(payload))
-	if err := bf.writeCmd(payload); err != nil {
-		return nil, err
-	}
-
-	// Don't wait for a response if no listener was provided.
-	if ol == nil {
-		return nil, nil
-	}
-
-	for {
-		select {
-		case err := <-ol.ErrChan:
-			return nil, err
-		case m := <-ol.RspChan:
-			// Only accept messages if the session is still open.  This is
-			// to help prevent race conditions in client code.
-			if bf.IsOpen() {
-				return m, nil
-			}
-		case <-ol.AfterTimeout(timeout):
-			return nil, nmxutil.NewRspTimeoutError("OIC timeout")
-		}
-	}
-}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_sesn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_sesn.go
deleted file mode 100644
index 46d2f07..0000000
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_sesn.go
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package nmble
-
-import (
-	"fmt"
-	"sync"
-	"time"
-
-	"github.com/runtimeco/go-coap"
-
-	"mynewt.apache.org/newt/util"
-	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
-	"mynewt.apache.org/newtmgr/nmxact/nmp"
-	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
-	"mynewt.apache.org/newtmgr/nmxact/oic"
-	"mynewt.apache.org/newtmgr/nmxact/omp"
-	"mynewt.apache.org/newtmgr/nmxact/sesn"
-)
-
-type BleOicSesn struct {
-	bf           *BleFsm
-	d            *omp.Dispatcher
-	closeTimeout time.Duration
-	onCloseCb    sesn.OnCloseFn
-	wg           sync.WaitGroup
-	closeBlocker nmxutil.Blocker
-}
-
-func NewBleOicSesn(bx *BleXport, cfg sesn.SesnCfg) *BleOicSesn {
-	bos := &BleOicSesn{
-		closeTimeout: cfg.Ble.CloseTimeout,
-		onCloseCb:    cfg.OnCloseCb,
-	}
-
-	iotUuid, _ := ParseUuid(OmpUnsecSvcUuid)
-	svcUuids := []BleUuid{
-		iotUuid,
-	}
-
-	reqChrUuid, _ := ParseUuid(OmpUnsecReqChrUuid)
-	rspChrUuid, _ := ParseUuid(OmpUnsecRspChrUuid)
-
-	bos.bf = NewBleFsm(BleFsmParams{
-		Bx:          bx,
-		OwnAddrType: cfg.Ble.OwnAddrType,
-		Central: BleFsmParamsCentral{
-			PeerDev:     cfg.PeerSpec.Ble,
-			ConnTries:   cfg.Ble.Central.ConnTries,
-			ConnTimeout: cfg.Ble.Central.ConnTimeout,
-		},
-		SvcUuids:    svcUuids,
-		ReqChrUuid:  reqChrUuid,
-		RspChrUuid:  rspChrUuid,
-		EncryptWhen: cfg.Ble.EncryptWhen,
-	})
-
-	return bos
-}
-
-func (bos *BleOicSesn) AbortRx(seq uint8) error {
-	return bos.d.ErrorOneNmp(seq, fmt.Errorf("Rx aborted"))
-}
-
-func (bos *BleOicSesn) Open() error {
-	// Ensure subsequent calls to Close() block.
-	bos.closeBlocker.Block()
-
-	if err := bos.bf.Start(); err != nil {
-		if !nmxutil.IsSesnAlreadyOpen(err) {
-			bos.closeBlocker.Unblock()
-		}
-		return err
-	}
-
-	d, err := omp.NewDispatcher(true, 3)
-	if err != nil {
-		bos.closeBlocker.Unblock()
-		return err
-	}
-	bos.d = d
-
-	// Listen for disconnect in the background.
-	bos.wg.Add(1)
-	go func() {
-		// If the session is being closed, unblock the close() call.
-		defer bos.closeBlocker.Unblock()
-
-		// Block until disconnect.
-		<-bos.bf.DisconnectChan()
-		nmxutil.Assert(!bos.IsOpen())
-		pd := bos.bf.PrevDisconnect()
-
-		// Signal error to all listeners.
-		bos.d.ErrorAll(pd.Err)
-		bos.d.Stop()
-		bos.wg.Done()
-		bos.wg.Wait()
-
-		// Only execute the client's disconnect callback if the disconnect was
-		// unsolicited.
-		if pd.Dt != FSM_DISCONNECT_TYPE_REQUESTED && bos.onCloseCb != nil {
-			bos.onCloseCb(bos, pd.Err)
-		}
-	}()
-
-	// Listen for NMP responses in the background.
-	bos.wg.Add(1)
-	go func() {
-		defer bos.wg.Done()
-
-		for {
-			data, ok := <-bos.bf.RxNmpChan()
-			if !ok {
-				// Disconnected.
-				return
-			} else {
-				bos.d.Dispatch(data)
-			}
-		}
-	}()
-
-	return nil
-}
-
-func (bos *BleOicSesn) Close() error {
-	err := bos.bf.Stop()
-	if err != nil {
-		return err
-	}
-
-	// Block until close completes.
-	bos.closeBlocker.Wait()
-	return nil
-}
-
-func (bos *BleOicSesn) IsOpen() bool {
-	return bos.bf.IsOpen()
-}
-
-func (bos *BleOicSesn) EncodeNmpMsg(m *nmp.NmpMsg) ([]byte, error) {
-	return omp.EncodeOmpTcp(m)
-}
-
-// Blocking.
-func (bos *BleOicSesn) TxNmpOnce(m *nmp.NmpMsg, opt sesn.TxOptions) (
-	nmp.NmpRsp, error) {
-
-	if !bos.IsOpen() {
-		return nil, bos.bf.closedError(
-			"Attempt to transmit over closed BLE session")
-	}
-
-	nl, err := bos.d.AddNmpListener(m.Hdr.Seq)
-	if err != nil {
-		return nil, err
-	}
-	defer bos.d.RemoveNmpListener(m.Hdr.Seq)
-
-	b, err := bos.EncodeNmpMsg(m)
-	if err != nil {
-		return nil, err
-	}
-
-	return bos.bf.TxNmp(b, nl, opt.Timeout)
-}
-
-func (bos *BleOicSesn) MtuIn() int {
-	return bos.bf.attMtu -
-		NOTIFY_CMD_BASE_SZ -
-		omp.OMP_MSG_OVERHEAD -
-		nmp.NMP_HDR_SIZE
-}
-
-func (bos *BleOicSesn) MtuOut() int {
-	mtu := bos.bf.attMtu -
-		WRITE_CMD_BASE_SZ -
-		omp.OMP_MSG_OVERHEAD -
-		nmp.NMP_HDR_SIZE
-	return util.IntMin(mtu, BLE_ATT_ATTR_MAX_LEN)
-}
-
-func (bos *BleOicSesn) ConnInfo() (BleConnDesc, error) {
-	return bos.bf.connInfo()
-}
-
-func (bos *BleOicSesn) GetResourceOnce(uri string, opt sesn.TxOptions) (
-	[]byte, error) {
-
-	token := nmxutil.NextToken()
-
-	ol, err := bos.d.AddOicListener(token)
-	if err != nil {
-		return nil, err
-	}
-	defer bos.d.RemoveOicListener(token)
-
-	req, err := oic.EncodeGet(uri, token)
-	if err != nil {
-		return nil, err
-	}
-
-	rsp, err := bos.bf.TxOic(req, ol, opt.Timeout)
-	if err != nil {
-		return nil, err
-	}
-
-	if rsp.Code != coap.Content {
-		return nil, fmt.Errorf("UNEXPECTED OIC ACK: %#v", rsp)
-	}
-
-	return rsp.Payload, nil
-}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_svr.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_svr.go
new file mode 100644
index 0000000..b892d3d
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_oic_svr.go
@@ -0,0 +1,59 @@
+package nmble
+
+import (
+	log "github.com/Sirupsen/logrus"
+
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+	"mynewt.apache.org/newtmgr/nmxact/oic"
+)
+
+type BleOicSvr struct {
+	s          oic.Server
+	x          *BleXport
+	rspSvcUuid BleUuid
+	rspChrUuid BleUuid
+}
+
+func NewBleOicSvr(x *BleXport,
+	rspSvcUuid BleUuid, rspChrUuid BleUuid) BleOicSvr {
+
+	return BleOicSvr{
+		s:          oic.NewServer(true),
+		x:          x,
+		rspSvcUuid: rspSvcUuid,
+		rspChrUuid: rspChrUuid,
+	}
+}
+
+func (b *BleOicSvr) AddResource(r oic.Resource) error {
+	return b.s.AddResource(r)
+}
+
+func (b *BleOicSvr) Rx(access BleGattAccess) uint8 {
+	ml, err := b.s.Rx(access.Data)
+	if err != nil {
+		log.Debugf("Error processing incoming CoAP message: %s", err.Error())
+		return 0
+	}
+
+	if ml == nil {
+		// Partial CoAP message; remainder forthcoming.
+		return 0
+	}
+
+	data, err := ml.MarshalBinary()
+	if err != nil {
+		return ERR_CODE_ATT_UNLIKELY
+	}
+
+	_, valHandle, err := FindChrXact(b.x, b.rspSvcUuid, b.rspChrUuid)
+	if err != nil {
+		return ERR_CODE_ATT_UNLIKELY
+	}
+
+	if err := NotifyXact(b.x, access.ConnHandle, valHandle, data); err != nil {
+		return ERR_CODE_ATT_UNLIKELY
+	}
+
+	return 0
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go
deleted file mode 100644
index be8c900..0000000
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go
+++ /dev/null
@@ -1,188 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package nmble
-
-import (
-	"fmt"
-	"sync"
-	"time"
-
-	"mynewt.apache.org/newt/util"
-	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
-	"mynewt.apache.org/newtmgr/nmxact/nmp"
-	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
-	"mynewt.apache.org/newtmgr/nmxact/sesn"
-)
-
-type BlePlainSesn struct {
-	bf           *BleFsm
-	d            *nmp.Dispatcher
-	closeTimeout time.Duration
-	onCloseCb    sesn.OnCloseFn
-	wg           sync.WaitGroup
-	closeBlocker nmxutil.Blocker
-}
-
-func NewBlePlainSesn(bx *BleXport, cfg sesn.SesnCfg) *BlePlainSesn {
-	bps := &BlePlainSesn{
-		closeTimeout: cfg.Ble.CloseTimeout,
-		onCloseCb:    cfg.OnCloseCb,
-	}
-
-	svcUuid, _ := ParseUuid(NmpPlainSvcUuid)
-	chrUuid, _ := ParseUuid(NmpPlainChrUuid)
-
-	bps.bf = NewBleFsm(BleFsmParams{
-		Bx:          bx,
-		OwnAddrType: cfg.Ble.OwnAddrType,
-		Central: BleFsmParamsCentral{
-			PeerDev:     cfg.PeerSpec.Ble,
-			ConnTries:   cfg.Ble.Central.ConnTries,
-			ConnTimeout: cfg.Ble.Central.ConnTimeout,
-		},
-		SvcUuids:    []BleUuid{svcUuid},
-		ReqChrUuid:  chrUuid,
-		RspChrUuid:  chrUuid,
-		EncryptWhen: cfg.Ble.EncryptWhen,
-	})
-
-	return bps
-}
-
-func (bps *BlePlainSesn) AbortRx(seq uint8) error {
-	return bps.d.ErrorOne(seq, fmt.Errorf("Rx aborted"))
-}
-
-func (bps *BlePlainSesn) Open() error {
-	// Ensure subsequent calls to Close() block.
-	bps.closeBlocker.Block()
-
-	if err := bps.bf.Start(); err != nil {
-		if !nmxutil.IsSesnAlreadyOpen(err) {
-			bps.closeBlocker.Unblock()
-		}
-		return err
-	}
-
-	bps.d = nmp.NewDispatcher(3)
-
-	// Listen for disconnect in the background.
-	bps.wg.Add(1)
-	go func() {
-		// If the session is being closed, unblock the close() call.
-		defer bps.closeBlocker.Unblock()
-
-		// Block until disconnect.
-		<-bps.bf.DisconnectChan()
-		nmxutil.Assert(!bps.IsOpen())
-
-		pd := bps.bf.PrevDisconnect()
-
-		// Signal error to all listeners.
-		bps.d.ErrorAll(pd.Err)
-		bps.wg.Done()
-		bps.wg.Wait()
-
-		// Only execute the client's disconnect callback if the disconnect was
-		// unsolicited.
-		if pd.Dt != FSM_DISCONNECT_TYPE_REQUESTED && bps.onCloseCb != nil {
-			bps.onCloseCb(bps, pd.Err)
-		}
-	}()
-
-	// Listen for NMP responses in the background.
-	bps.wg.Add(1)
-	go func() {
-		defer bps.wg.Done()
-
-		for {
-			data, ok := <-bps.bf.RxNmpChan()
-			if !ok {
-				// Disconnected.
-				return
-			} else {
-				bps.d.Dispatch(data)
-			}
-		}
-	}()
-
-	return nil
-}
-
-func (bps *BlePlainSesn) Close() error {
-	err := bps.bf.Stop()
-	if err != nil {
-		return err
-	}
-
-	// Block until close completes.
-	bps.closeBlocker.Wait()
-	return nil
-}
-
-func (bps *BlePlainSesn) IsOpen() bool {
-	return bps.bf.IsOpen()
-}
-
-func (bps *BlePlainSesn) EncodeNmpMsg(m *nmp.NmpMsg) ([]byte, error) {
-	return nmp.EncodeNmpPlain(m)
-}
-
-// Blocking.
-func (bps *BlePlainSesn) TxNmpOnce(msg *nmp.NmpMsg, opt sesn.TxOptions) (
-	nmp.NmpRsp, error) {
-
-	if !bps.IsOpen() {
-		return nil, bps.bf.closedError(
-			"Attempt to transmit over closed BLE session")
-	}
-
-	nl, err := bps.d.AddListener(msg.Hdr.Seq)
-	if err != nil {
-		return nil, err
-	}
-	defer bps.d.RemoveListener(msg.Hdr.Seq)
-
-	b, err := bps.EncodeNmpMsg(msg)
-	if err != nil {
-		return nil, err
-	}
-
-	return bps.bf.TxNmp(b, nl, opt.Timeout)
-}
-
-func (bps *BlePlainSesn) MtuIn() int {
-	return bps.bf.attMtu - NOTIFY_CMD_BASE_SZ - nmp.NMP_HDR_SIZE
-}
-
-func (bps *BlePlainSesn) MtuOut() int {
-	mtu := bps.bf.attMtu - WRITE_CMD_BASE_SZ - nmp.NMP_HDR_SIZE
-	return util.IntMin(mtu, BLE_ATT_ATTR_MAX_LEN)
-}
-
-func (bps *BlePlainSesn) ConnInfo() (BleConnDesc, error) {
-	return bps.bf.connInfo()
-}
-
-func (bps *BlePlainSesn) GetResourceOnce(uri string, opt sesn.TxOptions) (
-	[]byte, error) {
-
-	return nil, fmt.Errorf("BlePlainSesn.GetResourceOnce() unsupported")
-}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_proto.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_proto.go
index aa8dc9c..61c086a 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_proto.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_proto.go
@@ -38,6 +38,8 @@ type BleBytes struct {
 	Bytes []byte
 }
 
+const BLE_CONN_HANDLE_NONE uint16 = 0xffff
+
 const BLE_SEQ_MIN BleSeq = 0
 const BLE_SEQ_EVT_MIN BleSeq = 0xffffff00
 const BLE_SEQ_NONE BleSeq = 0xffffffff
@@ -226,6 +228,46 @@ var HciErrCodeStringMap = map[int]string{
 	ERR_CODE_HCI_COARSE_CLK_ADJ:      "coarse clk adj",
 }
 
+const (
+	ERR_CODE_ATT_INVALID_HANDLE         int = 0x01
+	ERR_CODE_ATT_READ_NOT_PERMITTED         = 0x02
+	ERR_CODE_ATT_WRITE_NOT_PERMITTED        = 0x03
+	ERR_CODE_ATT_INVALID_PDU                = 0x04
+	ERR_CODE_ATT_INSUFFICIENT_AUTHEN        = 0x05
+	ERR_CODE_ATT_REQ_NOT_SUPPORTED          = 0x06
+	ERR_CODE_ATT_INVALID_OFFSET             = 0x07
+	ERR_CODE_ATT_INSUFFICIENT_AUTHOR        = 0x08
+	ERR_CODE_ATT_PREPARE_QUEUE_FULL         = 0x09
+	ERR_CODE_ATT_ATTR_NOT_FOUND             = 0x0a
+	ERR_CODE_ATT_ATTR_NOT_LONG              = 0x0b
+	ERR_CODE_ATT_INSUFFICIENT_KEY_SZ        = 0x0c
+	ERR_CODE_ATT_INVALID_ATTR_VALUE_LEN     = 0x0d
+	ERR_CODE_ATT_UNLIKELY                   = 0x0e
+	ERR_CODE_ATT_INSUFFICIENT_ENC           = 0x0f
+	ERR_CODE_ATT_UNSUPPORTED_GROUP          = 0x10
+	ERR_CODE_ATT_INSUFFICIENT_RES           = 0x11
+)
+
+var AttErrCodeStringMap = map[int]string{
+	ERR_CODE_ATT_INVALID_HANDLE:         "invalid handle",
+	ERR_CODE_ATT_READ_NOT_PERMITTED:     "read not permitted",
+	ERR_CODE_ATT_WRITE_NOT_PERMITTED:    "write not permitted",
+	ERR_CODE_ATT_INVALID_PDU:            "invalid pdu",
+	ERR_CODE_ATT_INSUFFICIENT_AUTHEN:    "insufficient authentication",
+	ERR_CODE_ATT_REQ_NOT_SUPPORTED:      "request not supported",
+	ERR_CODE_ATT_INVALID_OFFSET:         "invalid offset",
+	ERR_CODE_ATT_INSUFFICIENT_AUTHOR:    "insufficient authorization",
+	ERR_CODE_ATT_PREPARE_QUEUE_FULL:     "prepare queue full",
+	ERR_CODE_ATT_ATTR_NOT_FOUND:         "attribute not found",
+	ERR_CODE_ATT_ATTR_NOT_LONG:          "attribute not long",
+	ERR_CODE_ATT_INSUFFICIENT_KEY_SZ:    "insufficient key size",
+	ERR_CODE_ATT_INVALID_ATTR_VALUE_LEN: "invalid attribute value length",
+	ERR_CODE_ATT_UNLIKELY:               "unlikely error",
+	ERR_CODE_ATT_INSUFFICIENT_ENC:       "insufficient encryption",
+	ERR_CODE_ATT_UNSUPPORTED_GROUP:      "unsupported group",
+	ERR_CODE_ATT_INSUFFICIENT_RES:       "insufficient resources",
+}
+
 // These values never get transmitted or received, so their precise values
 // don't matter.  We specify them explicitly here to match the blehostd source.
 const (
@@ -245,36 +287,45 @@ const (
 	MSG_TYPE_DISC_SVC_UUID             = 6
 	MSG_TYPE_DISC_ALL_CHRS             = 7
 	MSG_TYPE_DISC_CHR_UUID             = 8
-	MSG_TYPE_WRITE                     = 9
-	MSG_TYPE_WRITE_CMD                 = 10
-	MSG_TYPE_EXCHANGE_MTU              = 11
-	MSG_TYPE_GEN_RAND_ADDR             = 12
-	MSG_TYPE_SET_RAND_ADDR             = 13
-	MSG_TYPE_CONN_CANCEL               = 14
-	MSG_TYPE_SCAN                      = 15
-	MSG_TYPE_SCAN_CANCEL               = 16
-	MSG_TYPE_SET_PREFERRED_MTU         = 17
-	MSG_TYPE_SECURITY_INITIATE         = 18
-	MSG_TYPE_CONN_FIND                 = 19
-	MSG_TYPE_RESET                     = 20
-	MSG_TYPE_ADV_START                 = 21
-	MSG_TYPE_ADV_STOP                  = 22
-	MSG_TYPE_ADV_SET_DATA              = 23
-	MSG_TYPE_ADV_RSP_SET_DATA          = 24
-	MSG_TYPE_ADV_FIELDS                = 25
+	MSG_TYPE_DISC_ALL_DSCS             = 9
+	MSG_TYPE_WRITE                     = 10
+	MSG_TYPE_WRITE_CMD                 = 11
+	MSG_TYPE_EXCHANGE_MTU              = 12
+	MSG_TYPE_GEN_RAND_ADDR             = 13
+	MSG_TYPE_SET_RAND_ADDR             = 14
+	MSG_TYPE_CONN_CANCEL               = 15
+	MSG_TYPE_SCAN                      = 16
+	MSG_TYPE_SCAN_CANCEL               = 17
+	MSG_TYPE_SET_PREFERRED_MTU         = 18
+	MSG_TYPE_SECURITY_INITIATE         = 19
+	MSG_TYPE_CONN_FIND                 = 20
+	MSG_TYPE_RESET                     = 21
+	MSG_TYPE_ADV_START                 = 22
+	MSG_TYPE_ADV_STOP                  = 23
+	MSG_TYPE_ADV_SET_DATA              = 24
+	MSG_TYPE_ADV_RSP_SET_DATA          = 25
+	MSG_TYPE_ADV_FIELDS                = 26
+	MSG_TYPE_CLEAR_SVCS                = 27
+	MSG_TYPE_ADD_SVCS                  = 28
+	MSG_TYPE_COMMIT_SVCS               = 29
+	MSG_TYPE_ACCESS_STATUS             = 30
+	MSG_TYPE_NOTIFY                    = 31
+	MSG_TYPE_FIND_CHR                  = 32
 
 	MSG_TYPE_SYNC_EVT       = 2049
 	MSG_TYPE_CONNECT_EVT    = 2050
 	MSG_TYPE_DISCONNECT_EVT = 2051
 	MSG_TYPE_DISC_SVC_EVT   = 2052
 	MSG_TYPE_DISC_CHR_EVT   = 2053
-	MSG_TYPE_WRITE_ACK_EVT  = 2054
-	MSG_TYPE_NOTIFY_RX_EVT  = 2055
-	MSG_TYPE_MTU_CHANGE_EVT = 2056
-	MSG_TYPE_SCAN_EVT       = 2057
-	MSG_TYPE_SCAN_TMO_EVT   = 2058
-	MSG_TYPE_ENC_CHANGE_EVT = 2059
-	MSG_TYPE_RESET_EVT      = 2060
+	MSG_TYPE_DISC_DSC_EVT   = 2054
+	MSG_TYPE_WRITE_ACK_EVT  = 2055
+	MSG_TYPE_NOTIFY_RX_EVT  = 2056
+	MSG_TYPE_MTU_CHANGE_EVT = 2057
+	MSG_TYPE_SCAN_EVT       = 2058
+	MSG_TYPE_SCAN_TMO_EVT   = 2059
+	MSG_TYPE_ENC_CHANGE_EVT = 2060
+	MSG_TYPE_RESET_EVT      = 2061
+	MSG_TYPE_ACCESS_EVT     = 2062
 )
 
 var MsgOpStringMap = map[MsgOp]string{
@@ -288,9 +339,12 @@ var MsgTypeStringMap = map[MsgType]string{
 	MSG_TYPE_SYNC:              "sync",
 	MSG_TYPE_CONNECT:           "connect",
 	MSG_TYPE_TERMINATE:         "terminate",
+	MSG_TYPE_DISC_ALL_SVCS:     "disc_all_svcs",
 	MSG_TYPE_DISC_SVC_UUID:     "disc_svc_uuid",
-	MSG_TYPE_DISC_CHR_UUID:     "disc_chr_uuid",
 	MSG_TYPE_DISC_ALL_CHRS:     "disc_all_chrs",
+	MSG_TYPE_DISC_CHR_UUID:     "disc_chr_uuid",
+	MSG_TYPE_DISC_ALL_DSCS:     "disc_all_dscs",
+	MSG_TYPE_WRITE:             "write",
 	MSG_TYPE_WRITE_CMD:         "write_cmd",
 	MSG_TYPE_EXCHANGE_MTU:      "exchange_mtu",
 	MSG_TYPE_GEN_RAND_ADDR:     "gen_rand_addr",
@@ -307,18 +361,27 @@ var MsgTypeStringMap = map[MsgType]string{
 	MSG_TYPE_ADV_SET_DATA:      "adv_set_data",
 	MSG_TYPE_ADV_RSP_SET_DATA:  "adv_rsp_set_data",
 	MSG_TYPE_ADV_FIELDS:        "adv_fields",
+	MSG_TYPE_CLEAR_SVCS:        "clear_svcs",
+	MSG_TYPE_ADD_SVCS:          "add_svcs",
+	MSG_TYPE_COMMIT_SVCS:       "commit_svcs",
+	MSG_TYPE_ACCESS_STATUS:     "access_status",
+	MSG_TYPE_NOTIFY:            "notify",
+	MSG_TYPE_FIND_CHR:          "find_chr",
 
 	MSG_TYPE_SYNC_EVT:       "sync_evt",
 	MSG_TYPE_CONNECT_EVT:    "connect_evt",
 	MSG_TYPE_DISCONNECT_EVT: "disconnect_evt",
 	MSG_TYPE_DISC_SVC_EVT:   "disc_svc_evt",
 	MSG_TYPE_DISC_CHR_EVT:   "disc_chr_evt",
+	MSG_TYPE_DISC_DSC_EVT:   "disc_dsc_evt",
+	MSG_TYPE_WRITE_ACK_EVT:  "write_ack_evt",
 	MSG_TYPE_NOTIFY_RX_EVT:  "notify_rx_evt",
 	MSG_TYPE_MTU_CHANGE_EVT: "mtu_change_evt",
 	MSG_TYPE_SCAN_EVT:       "scan_evt",
 	MSG_TYPE_SCAN_TMO_EVT:   "scan_tmo_evt",
 	MSG_TYPE_ENC_CHANGE_EVT: "enc_change_evt",
 	MSG_TYPE_RESET_EVT:      "reset_evt",
+	MSG_TYPE_ACCESS_EVT:     "access_evt",
 }
 
 type BleHdr struct {
@@ -329,19 +392,24 @@ type BleHdr struct {
 
 type Msg interface{}
 
-type BleSvc struct {
+type BleDiscSvc struct {
 	StartHandle int     `json:"start_handle"`
 	EndHandle   int     `json:"end_handle"`
 	Uuid        BleUuid `json:"uuid"`
 }
 
-type BleChr struct {
+type BleDiscChr struct {
 	DefHandle  int     `json:"def_handle"`
 	ValHandle  int     `json:"val_handle"`
 	Properties int     `json:"properties"`
 	Uuid       BleUuid `json:"uuid"`
 }
 
+type BleDiscDsc struct {
+	Handle uint16  `json:"handle"`
+	Uuid   BleUuid `json:"uuid"`
+}
+
 type BleSyncReq struct {
 	// Header
 	Op   MsgOp   `json:"op"`
@@ -441,6 +509,26 @@ type BleDisconnectEvt struct {
 	ConnHandle uint16 `json:"conn_handle"`
 }
 
+type BleDiscAllSvcsReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	ConnHandle uint16 `json:"conn_handle"`
+}
+
+type BleDiscAllSvcsRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
 type BleDiscSvcUuidReq struct {
 	// Header
 	Op   MsgOp   `json:"op"`
@@ -469,8 +557,30 @@ type BleDiscSvcEvt struct {
 	Seq  BleSeq  `json:"seq"`
 
 	// Mandatory
-	Status int    `json:"status"`
-	Svc    BleSvc `json:"service"`
+	Status int        `json:"status"`
+	Svc    BleDiscSvc `json:"service"`
+}
+
+type BleDiscAllChrsReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	ConnHandle  uint16 `json:"conn_handle"`
+	StartHandle int    `json:"start_handle"`
+	EndHandle   int    `json:"end_handle"`
+}
+
+type BleDiscAllChrsRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
 }
 
 type BleDiscChrUuidReq struct {
@@ -486,7 +596,28 @@ type BleDiscChrUuidReq struct {
 	Uuid        BleUuid `json:"chr_uuid"`
 }
 
-type BleDiscAllChrsReq struct {
+type BleDiscChrUuidRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleDiscChrEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int        `json:"status"`
+	Chr    BleDiscChr `json:"characteristic"`
+}
+
+type BleDiscAllDscsReq struct {
 	// Header
 	Op   MsgOp   `json:"op"`
 	Type MsgType `json:"type"`
@@ -498,7 +629,7 @@ type BleDiscAllChrsReq struct {
 	EndHandle   int    `json:"end_handle"`
 }
 
-type BleDiscAllChrsRsp struct {
+type BleDiscAllDscsRsp struct {
 	// Header
 	Op   MsgOp   `json:"op"`
 	Type MsgType `json:"type"`
@@ -508,6 +639,18 @@ type BleDiscAllChrsRsp struct {
 	Status int `json:"status"`
 }
 
+type BleDiscDscEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status       int        `json:"status"`
+	ChrDefHandle uint16     `json:"chr_def_handle"`
+	Dsc          BleDiscDsc `json:"descriptor"`
+}
+
 type BleErrRsp struct {
 	// Header
 	Op   MsgOp   `json:"op"`
@@ -529,7 +672,19 @@ type BleSyncRsp struct {
 	Synced bool `json:"synced"`
 }
 
-type BleDiscChrUuidRsp struct {
+type BleWriteReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	ConnHandle uint16   `json:"conn_handle"`
+	AttrHandle int      `json:"attr_handle"`
+	Data       BleBytes `json:"data"`
+}
+
+type BleWriteRsp struct {
 	// Header
 	Op   MsgOp   `json:"op"`
 	Type MsgType `json:"type"`
@@ -539,15 +694,14 @@ type BleDiscChrUuidRsp struct {
 	Status int `json:"status"`
 }
 
-type BleDiscChrEvt struct {
+type BleWriteAckEvt struct {
 	// Header
 	Op   MsgOp   `json:"op"`
 	Type MsgType `json:"type"`
 	Seq  BleSeq  `json:"seq"`
 
 	// Mandatory
-	Status int    `json:"status"`
-	Chr    BleChr `json:"characteristic"`
+	Status int `json:"status"`
 }
 
 type BleWriteCmdReq struct {
@@ -870,7 +1024,7 @@ type BleAdvStartReq struct {
 	HighDutyCycle bool               `json:"high_duty_cycle"`
 
 	// Only required for direct advertisements
-	PeerAddr *BleAddr `json:"peer_addr"`
+	PeerAddr *BleAddr `json:"peer_addr,omitempty"`
 }
 
 type BleAdvStartRsp struct {
@@ -907,7 +1061,7 @@ type BleAdvSetDataReq struct {
 	Seq  BleSeq  `json:"seq"`
 
 	// Mandatory
-	Data []byte `json:"data"`
+	Data BleBytes `json:"data"`
 }
 
 type BleAdvSetDataRsp struct {
@@ -927,7 +1081,7 @@ type BleAdvRspSetDataReq struct {
 	Seq  BleSeq  `json:"seq"`
 
 	// Mandatory
-	Data []byte `json:"data"`
+	Data BleBytes `json:"data"`
 }
 
 type BleAdvRspSetDataRsp struct {
@@ -950,51 +1104,51 @@ type BleAdvFieldsReq struct {
 	Flags *uint8 `json:"flags,omitempty"`
 
 	/*** 0x02,0x03 - 16-bit service class UUIDs. */
-	Uuids16           []BleUuid16 `json:"uuids16"`
+	Uuids16           []BleUuid16 `json:"uuids16,omitempty"`
 	Uuids16IsComplete bool        `json:"uuids16_is_complete"`
 
 	/*** 0x04,0x05 - 32-bit service class UUIDs. */
-	Uuids32           []uint32 `json:"uuids32"`
+	Uuids32           []uint32 `json:"uuids32,omitempty"`
 	Uuids32IsComplete bool     `json:"uuids32_is_complete"`
 
 	/*** 0x06,0x07 - 128-bit service class UUIDs. */
-	Uuids128           []BleUuid128 `json:"uuids128"`
+	Uuids128           []BleUuid128 `json:"uuids128,omitempty"`
 	Uuids128IsComplete bool         `json:"uuids128_is_complete"`
 
 	/*** 0x08,0x09 - Local name. */
-	Name           *string `json:"name,omitempty"`
+	Name           *string `json:"name,omitempty,omitempty"`
 	NameIsComplete bool    `json:"name_is_complete"`
 
 	/*** 0x0a - Tx power level. */
-	TxPwrLvl *int8 `json:"tx_pwr_lvl"`
+	TxPwrLvl *int8 `json:"tx_pwr_lvl,omitempty"`
 
 	/*** 0x0d - Slave connection interval range. */
-	SlaveItvlMin *uint16 `json:"slave_itvl_min"`
-	SlaveItvlMax *uint16 `json:"slave_itvl_max"`
+	SlaveItvlMin *uint16 `json:"slave_itvl_min,omitempty"`
+	SlaveItvlMax *uint16 `json:"slave_itvl_max,omitempty"`
 
 	/*** 0x16 - Service data - 16-bit UUID. */
-	SvcDataUuid16 []byte `json:"svc_data_uuid16"`
+	SvcDataUuid16 BleBytes `json:"svc_data_uuid16,omitempty"`
 
 	/*** 0x17 - Public target address. */
-	PublicTgtAddrs []BleAddr `json:"public_tgt_addrs"`
+	PublicTgtAddrs []BleAddr `json:"public_tgt_addrs,omitempty"`
 
 	/*** 0x19 - Appearance. */
-	Appearance *uint16 `json:"appearance"`
+	Appearance *uint16 `json:"appearance,omitempty"`
 
 	/*** 0x1a - Advertising interval. */
-	AdvItvl *uint16 `json:"adv_itvl"`
+	AdvItvl *uint16 `json:"adv_itvl,omitempty"`
 
 	/*** 0x20 - Service data - 32-bit UUID. */
-	SvcDataUuid32 []byte `json:"svc_data_uuid32"`
+	SvcDataUuid32 BleBytes `json:"svc_data_uuid32,omitempty"`
 
 	/*** 0x21 - Service data - 128-bit UUID. */
-	SvcDataUuid128 []byte `json:"svc_data_uuid128"`
+	SvcDataUuid128 BleBytes `json:"svc_data_uuid128,omitempty"`
 
 	/*** 0x24 - URI. */
 	Uri *string `json:"uri,omitempty"`
 
 	/*** 0xff - Manufacturer specific data. */
-	MfgData []byte `json:"mfg_data"`
+	MfgData BleBytes `json:"mfg_data,omitempty"`
 }
 
 type BleAdvFieldsRsp struct {
@@ -1004,8 +1158,8 @@ type BleAdvFieldsRsp struct {
 	Seq  BleSeq  `json:"seq"`
 
 	// Mandatory
-	Status int    `json:"status"`
-	Data   []byte `json:"data"`
+	Status int      `json:"status"`
+	Data   BleBytes `json:"data"`
 }
 
 type BleResetEvt struct {
@@ -1018,6 +1172,178 @@ type BleResetEvt struct {
 	Reason int `json:"reason"`
 }
 
+type BleClearSvcsReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+}
+
+type BleClearSvcsRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleAddDsc struct {
+	Uuid       BleUuid     `json:"uuid"`
+	AttFlags   BleAttFlags `json:"att_flags"`
+	MinKeySize int         `json:"min_key_size"`
+}
+
+type BleAddChr struct {
+	Uuid       BleUuid     `json:"uuid"`
+	Flags      BleChrFlags `json:"flags"`
+	MinKeySize int         `json:"min_key_size"`
+	Dscs       []BleAddDsc `json:"descriptors,omitempty"`
+}
+
+type BleAddSvc struct {
+	Uuid    BleUuid     `json:"uuid"`
+	SvcType BleSvcType  `json:"type"`
+	Chrs    []BleAddChr `json:"characteristics,omitempty"`
+}
+
+type BleAddSvcsReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	Svcs []BleAddSvc `json:"services"`
+}
+
+type BleAddSvcsRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleRegDsc struct {
+	Uuid   BleUuid `json:"uuid"`
+	Handle uint16  `json:"handle"`
+}
+
+type BleRegChr struct {
+	Uuid      BleUuid     `json:"uuid"`
+	DefHandle uint16      `json:"def_handle"`
+	ValHandle uint16      `json:"val_handle"`
+	Dscs      []BleRegDsc `json:"descriptors"`
+}
+
+type BleRegSvc struct {
+	Uuid   BleUuid     `json:"uuid"`
+	Handle uint16      `json:"handle"`
+	Chrs   []BleRegChr `json:"characteristics"`
+}
+
+type BleCommitSvcsReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+}
+
+type BleCommitSvcsRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+
+	// Optional
+	Svcs []BleRegSvc `json:"services"`
+}
+
+type BleAccessEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	GattOp     BleGattOp `json:"gatt_op"`
+	ConnHandle uint16    `json:"conn_handle"`
+	AttHandle  uint16    `json:"att_handle"`
+	Data       BleBytes  `json:"data"`
+}
+
+type BleAccessStatusReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	AttStatus uint8    `json:"att_status"`
+	Data      BleBytes `json:"data"`
+}
+
+type BleAccessStatusRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleNotifyReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	ConnHandle uint16   `json:"conn_handle"`
+	AttrHandle uint16   `json:"attr_handle"`
+	Data       BleBytes `json:"data"`
+}
+
+type BleNotifyRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleFindChrReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	SvcUuid BleUuid `json:"svc_uuid"`
+	ChrUuid BleUuid `json:"chr_uuid"`
+}
+
+type BleFindChrRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  BleSeq  `json:"seq"`
+
+	// Mandatory
+	Status    int    `json:"status"`
+	DefHandle uint16 `json:"def_handle"`
+	ValHandle uint16 `json:"val_handle"`
+}
+
 func ErrCodeToString(e int) string {
 	var s string
 
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_scanner.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_scanner.go
index 5e44d39..b93a5e9 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_scanner.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_scanner.go
@@ -40,7 +40,7 @@ type BleScanner struct {
 	bx           *BleXport
 	discoverer   *Discoverer
 	reportedDevs map[BleDev]string
-	bos          *BleOicSesn
+	bos          *BleSesn
 	enabled      bool
 
 	// Protects accesses to the reported devices map.
@@ -96,7 +96,7 @@ func (s *BleScanner) connect(dev BleDev) error {
 	}
 
 	s.mtx.Lock()
-	s.bos = session.(*BleOicSesn)
+	s.bos = session.(*BleSesn)
 	s.mtx.Unlock()
 
 	if err := s.bos.Open(); err != nil {
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_sesn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_sesn.go
new file mode 100644
index 0000000..0918e58
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_sesn.go
@@ -0,0 +1,342 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package nmble
+
+import (
+	"fmt"
+	"sync"
+
+	"github.com/runtimeco/go-coap"
+
+	"mynewt.apache.org/newt/util"
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+	"mynewt.apache.org/newtmgr/nmxact/mgmt"
+	"mynewt.apache.org/newtmgr/nmxact/nmp"
+	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
+	"mynewt.apache.org/newtmgr/nmxact/oic"
+	"mynewt.apache.org/newtmgr/nmxact/omp"
+	"mynewt.apache.org/newtmgr/nmxact/sesn"
+)
+
+var dummyNotifyListener = NewNotifyListener()
+
+type BleSesn struct {
+	cfg      sesn.SesnCfg
+	bx       *BleXport
+	conn     *Conn
+	mgmtChrs BleMgmtChrs
+	txvr     *mgmt.Transceiver
+
+	wg           sync.WaitGroup
+	closeBlocker nmxutil.Blocker
+	stopChan     chan struct{}
+}
+
+func (s *BleSesn) init() error {
+	s.conn = NewConn(s.bx)
+
+	s.stopChan = make(chan struct{})
+
+	txvr, err := mgmt.NewTransceiver(s.cfg.MgmtProto, 3)
+	if err != nil {
+		return err
+	}
+	s.txvr = txvr
+	return nil
+}
+
+func NewBleSesn(bx *BleXport, cfg sesn.SesnCfg) (*BleSesn, error) {
+	mgmtChrs, err := BuildMgmtChrs(cfg.MgmtProto)
+	if err != nil {
+		return nil, err
+	}
+
+	s := &BleSesn{
+		cfg:      cfg,
+		bx:       bx,
+		mgmtChrs: mgmtChrs,
+	}
+
+	if err := s.init(); err != nil {
+		return nil, err
+	}
+
+	return s, nil
+}
+
+func (s *BleSesn) AbortRx(seq uint8) error {
+	s.txvr.AbortRx(seq)
+	return nil
+}
+
+func (s *BleSesn) disconnectListen() {
+	// Listen for disconnect in the background.
+	s.wg.Add(1)
+	go func() {
+		// If the session is being closed, unblock the close() call.
+		defer s.closeBlocker.Unblock()
+
+		// Block until disconnect.
+		err := <-s.conn.DisconnectChan()
+		nmxutil.Assert(!s.IsOpen())
+
+		// Signal error to all listeners.
+		close(s.stopChan)
+		s.wg.Done()
+		s.wg.Wait()
+
+		if s.cfg.OnCloseCb != nil {
+			s.cfg.OnCloseCb(s, err)
+		}
+	}()
+}
+
+func (s *BleSesn) getChr(chrId *BleChrId) (*Characteristic, error) {
+	if chrId == nil {
+		return nil, fmt.Errorf("BLE session not configured with required "+
+			"characteristic: %s", *chrId)
+	}
+
+	chr := s.conn.Profile().FindChrByUuid(*chrId)
+	if chr == nil {
+		return nil, fmt.Errorf("BLE peer doesn't support required "+
+			"characteristic: %s", *chrId)
+	}
+
+	return chr, nil
+}
+
+func (s *BleSesn) createNotifyListener(chrId *BleChrId) *NotifyListener {
+	chr, _ := s.getChr(chrId)
+	if chr == nil {
+		return dummyNotifyListener
+	}
+
+	nl := s.conn.ListenForNotifications(chr)
+	if nl == nil {
+		return dummyNotifyListener
+	}
+
+	return nl
+}
+
+func (s *BleSesn) notifyListen() {
+	nmpRspNl := s.createNotifyListener(s.mgmtChrs.NmpRspChr)
+
+	s.wg.Add(1)
+	go func() {
+		defer s.wg.Done()
+
+		for {
+			select {
+			case err := <-nmpRspNl.ErrChan:
+				s.txvr.ErrorAll(err)
+				return
+
+			case n, ok := <-nmpRspNl.NotifyChan:
+				if ok {
+					s.txvr.DispatchNmpRsp(n.Data)
+				}
+
+			case <-s.stopChan:
+				return
+			}
+		}
+	}()
+}
+
+func (s *BleSesn) openOnce() (bool, error) {
+	if s.IsOpen() {
+		return false, nmxutil.NewSesnAlreadyOpenError(
+			"Attempt to open an already-open bll session")
+	}
+
+	if err := s.init(); err != nil {
+		return false, err
+	}
+
+	// Ensure subsequent calls to Close() block.
+	s.closeBlocker.Block()
+
+	// Listen for disconnect in the background.
+	s.disconnectListen()
+
+	if err := s.conn.Connect(
+		s.bx,
+		s.cfg.Ble.OwnAddrType,
+		s.cfg.PeerSpec.Ble,
+		s.cfg.Ble.Central.ConnTimeout); err != nil {
+
+		return false, err
+	}
+
+	if err := s.conn.ExchangeMtu(); err != nil {
+		bhdErr := nmxutil.ToBleHost(err)
+		retry := bhdErr != nil && bhdErr.Status == ERR_CODE_ENOTCONN
+		return retry, err
+	}
+
+	if err := s.conn.DiscoverSvcs(); err != nil {
+		return false, err
+	}
+
+	if chr, _ := s.getChr(s.mgmtChrs.NmpRspChr); chr != nil {
+		if chr.SubscribeType() != 0 {
+			if err := s.conn.Subscribe(chr); err != nil {
+				return false, err
+			}
+		}
+	}
+
+	// Listen for incoming notifications in the background.
+	s.notifyListen()
+
+	return false, nil
+}
+
+func (s *BleSesn) Open() error {
+	var err error
+	for i := 0; i < s.cfg.Ble.Central.ConnTries; i++ {
+		var retry bool
+
+		retry, err = s.openOnce()
+		if err != nil {
+			s.Close()
+		}
+
+		if !retry {
+			break
+		}
+	}
+
+	return err
+}
+
+func (s *BleSesn) OpenConnected(
+	connHandle uint16, eventListener *Listener) error {
+
+	if err := s.conn.Inherit(connHandle, eventListener); err != nil {
+		if !nmxutil.IsSesnAlreadyOpen(err) {
+			s.closeBlocker.Unblock()
+		}
+		return err
+	}
+
+	// Ensure subsequent calls to Close() block.
+	s.closeBlocker.Block()
+
+	// Listen for disconnect in the background.
+	s.disconnectListen()
+
+	// Listen for incoming notifications in the background.
+	s.notifyListen()
+
+	return nil
+}
+
+func (s *BleSesn) Close() error {
+	if err := s.conn.Stop(); err != nil {
+		return err
+	}
+
+	// Block until close completes.
+	s.closeBlocker.Wait()
+	return nil
+}
+
+func (s *BleSesn) IsOpen() bool {
+	return s.conn.IsConnected()
+}
+
+func (s *BleSesn) EncodeNmpMsg(m *nmp.NmpMsg) ([]byte, error) {
+	switch s.cfg.MgmtProto {
+	case sesn.MGMT_PROTO_NMP:
+		return nmp.EncodeNmpPlain(m)
+
+	case sesn.MGMT_PROTO_OMP:
+		return omp.EncodeOmpTcp(m)
+
+	default:
+		return nil,
+			fmt.Errorf("invalid management protocol: %+v", s.cfg.MgmtProto)
+	}
+}
+
+// Blocking.
+func (s *BleSesn) TxNmpOnce(req *nmp.NmpMsg, opt sesn.TxOptions) (
+	nmp.NmpRsp, error) {
+
+	chr, err := s.getChr(s.mgmtChrs.NmpReqChr)
+	if err != nil {
+		return nil, err
+	}
+
+	txRaw := func(b []byte) error {
+		return s.conn.WriteChrNoRsp(chr, b, "nmp")
+	}
+
+	return s.txvr.TxNmp(txRaw, req, opt.Timeout)
+}
+
+func (s *BleSesn) MtuIn() int {
+	return s.conn.AttMtu() -
+		NOTIFY_CMD_BASE_SZ -
+		omp.OMP_MSG_OVERHEAD -
+		nmp.NMP_HDR_SIZE
+}
+
+func (s *BleSesn) MtuOut() int {
+	mtu := s.conn.AttMtu() -
+		WRITE_CMD_BASE_SZ -
+		omp.OMP_MSG_OVERHEAD -
+		nmp.NMP_HDR_SIZE
+	return util.IntMin(mtu, BLE_ATT_ATTR_MAX_LEN)
+}
+
+func (s *BleSesn) ConnInfo() (BleConnDesc, error) {
+	return s.conn.ConnInfo(), nil
+}
+
+func (s *BleSesn) GetResourceOnce(resType sesn.ResourceType, uri string,
+	opt sesn.TxOptions) (coap.COAPCode, []byte, error) {
+
+	token := nmxutil.NextToken()
+	req, err := oic.CreateGet(true, uri, token)
+	if err != nil {
+		return 0, nil, err
+	}
+
+	chrId := ResChrIdLookup(s.mgmtChrs, resType)
+	chr, err := s.getChr(chrId)
+	if err != nil {
+		return 0, nil, err
+	}
+
+	txRaw := func(b []byte) error {
+		return s.conn.WriteChrNoRsp(chr, b, "oic")
+	}
+
+	rsp, err := s.txvr.TxOic(txRaw, req, opt.Timeout)
+	if err != nil {
+		return 0, nil, err
+	}
+
+	return rsp.Code(), rsp.Payload(), nil
+}
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 a469a55..2630536 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
@@ -26,9 +26,12 @@ import (
 	"time"
 
 	log "github.com/Sirupsen/logrus"
+	"github.com/runtimeco/go-coap"
 
 	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
 	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
+	"mynewt.apache.org/newtmgr/nmxact/oic"
+	"mynewt.apache.org/newtmgr/nmxact/sesn"
 )
 
 const WRITE_CMD_BASE_SZ = 3
@@ -167,6 +170,14 @@ func NewBleConnCancelReq() *BleConnCancelReq {
 	}
 }
 
+func NewBleDiscAllSvcsReq() *BleDiscAllSvcsReq {
+	return &BleDiscAllSvcsReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_DISC_ALL_SVCS,
+		Seq:  NextSeq(),
+	}
+}
+
 func NewBleDiscSvcUuidReq() *BleDiscSvcUuidReq {
 	return &BleDiscSvcUuidReq{
 		Op:   MSG_OP_REQ,
@@ -186,6 +197,14 @@ func NewBleDiscAllChrsReq() *BleDiscAllChrsReq {
 	}
 }
 
+func NewBleDiscAllDscsReq() *BleDiscAllDscsReq {
+	return &BleDiscAllDscsReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_DISC_ALL_DSCS,
+		Seq:  NextSeq(),
+	}
+}
+
 func NewBleExchangeMtuReq() *BleExchangeMtuReq {
 	return &BleExchangeMtuReq{
 		Op:   MSG_OP_REQ,
@@ -217,10 +236,14 @@ func NewBleWriteCmdReq() *BleWriteCmdReq {
 		Op:   MSG_OP_REQ,
 		Type: MSG_TYPE_WRITE_CMD,
 		Seq:  NextSeq(),
+	}
+}
 
-		ConnHandle: 0,
-		AttrHandle: 0,
-		Data:       BleBytes{},
+func NewBleWriteReq() *BleWriteReq {
+	return &BleWriteReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_WRITE,
+		Seq:  NextSeq(),
 	}
 }
 
@@ -312,6 +335,54 @@ func NewBleAdvStopReq() *BleAdvStopReq {
 	}
 }
 
+func NewBleClearSvcsReq() *BleClearSvcsReq {
+	return &BleClearSvcsReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_CLEAR_SVCS,
+		Seq:  NextSeq(),
+	}
+}
+
+func NewBleAddSvcsReq() *BleAddSvcsReq {
+	return &BleAddSvcsReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_ADD_SVCS,
+		Seq:  NextSeq(),
+	}
+}
+
+func NewBleCommitSvcsReq() *BleCommitSvcsReq {
+	return &BleCommitSvcsReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_COMMIT_SVCS,
+		Seq:  NextSeq(),
+	}
+}
+
+func NewAccessStatusReq() *BleAccessStatusReq {
+	return &BleAccessStatusReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_ACCESS_STATUS,
+		Seq:  NextSeq(),
+	}
+}
+
+func NewNotifyReq() *BleNotifyReq {
+	return &BleNotifyReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_NOTIFY,
+		Seq:  NextSeq(),
+	}
+}
+
+func NewFindChrReq() *BleFindChrReq {
+	return &BleFindChrReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_FIND_CHR,
+		Seq:  NextSeq(),
+	}
+}
+
 func ConnFindXact(x *BleXport, connHandle uint16) (BleConnDesc, error) {
 	r := NewBleConnFindReq()
 	r.ConnHandle = connHandle
@@ -380,6 +451,90 @@ func ResetXact(x *BleXport) error {
 	return reset(x, bl, r)
 }
 
+func ClearSvcsXact(x *BleXport) error {
+	r := NewBleClearSvcsReq()
+
+	bl, err := x.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer x.RemoveListener(bl)
+
+	return clearSvcs(x, bl, r)
+}
+
+func AddSvcsXact(x *BleXport, svcs []BleAddSvc) error {
+	r := NewBleAddSvcsReq()
+	r.Svcs = svcs
+
+	bl, err := x.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer x.RemoveListener(bl)
+
+	return addSvcs(x, bl, r)
+}
+
+func CommitSvcsXact(x *BleXport) ([]BleRegSvc, error) {
+	r := NewBleCommitSvcsReq()
+
+	bl, err := x.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return nil, err
+	}
+	defer x.RemoveListener(bl)
+
+	return commitSvcs(x, bl, r)
+}
+
+func AccessStatusXact(x *BleXport, attStatus uint8, data []byte) error {
+	r := NewAccessStatusReq()
+	r.AttStatus = attStatus
+	r.Data.Bytes = data
+
+	bl, err := x.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer x.RemoveListener(bl)
+
+	return accessStatus(x, bl, r)
+}
+
+func NotifyXact(x *BleXport, connHandle uint16, attrHandle uint16,
+	data []byte) error {
+
+	r := NewNotifyReq()
+	r.ConnHandle = connHandle
+	r.AttrHandle = attrHandle
+	r.Data.Bytes = data
+
+	bl, err := x.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer x.RemoveListener(bl)
+
+	return notify(x, bl, r)
+}
+
+func FindChrXact(x *BleXport, svcUuid BleUuid, chrUuid BleUuid) (
+	uint16, uint16, error) {
+
+	r := NewFindChrReq()
+	r.SvcUuid = svcUuid
+	r.ChrUuid = chrUuid
+
+	bl, err := x.AddListener(SeqKey(r.Seq))
+	if err != nil {
+		return 0, 0, err
+	}
+	defer x.RemoveListener(bl)
+
+	return findChr(x, bl, r)
+}
+
 func DiscoverDeviceWithName(
 	bx *BleXport,
 	ownAddrType BleAddrType,
@@ -392,3 +547,230 @@ func DiscoverDeviceWithName(
 
 	return DiscoverDevice(bx, ownAddrType, timeout, advPred)
 }
+
+func BleAdvFieldsToReq(f BleAdvFields) *BleAdvFieldsReq {
+	r := NewBleAdvFieldsReq()
+
+	r.Flags = f.Flags
+	r.Uuids16 = f.Uuids16
+	r.Uuids16IsComplete = f.Uuids16IsComplete
+	r.Uuids32 = f.Uuids32
+	r.Uuids32IsComplete = f.Uuids32IsComplete
+	r.Uuids128 = f.Uuids128
+	r.Uuids128IsComplete = f.Uuids128IsComplete
+	r.Name = f.Name
+	r.NameIsComplete = f.NameIsComplete
+	r.TxPwrLvl = f.TxPwrLvl
+	r.SlaveItvlMin = f.SlaveItvlMin
+	r.SlaveItvlMax = f.SlaveItvlMax
+	r.SvcDataUuid16 = BleBytes{f.SvcDataUuid16}
+	r.PublicTgtAddrs = f.PublicTgtAddrs
+	r.Appearance = f.Appearance
+	r.AdvItvl = f.AdvItvl
+	r.SvcDataUuid32 = BleBytes{f.SvcDataUuid32}
+	r.SvcDataUuid128 = BleBytes{f.SvcDataUuid128}
+	r.Uri = f.Uri
+	r.MfgData = BleBytes{f.MfgData}
+
+	return r
+}
+
+func BleSvcToAddSvc(svc BleSvc) BleAddSvc {
+	as := BleAddSvc{
+		Uuid:    svc.Uuid,
+		SvcType: svc.SvcType,
+	}
+
+	for _, chr := range svc.Chrs {
+		ac := BleAddChr{
+			Uuid:       chr.Uuid,
+			Flags:      chr.Flags,
+			MinKeySize: chr.MinKeySize,
+		}
+
+		for _, dsc := range chr.Dscs {
+			ad := BleAddDsc{
+				Uuid:       dsc.Uuid,
+				AttFlags:   dsc.AttFlags,
+				MinKeySize: dsc.MinKeySize,
+			}
+
+			ac.Dscs = append(ac.Dscs, ad)
+		}
+
+		as.Chrs = append(as.Chrs, ac)
+	}
+
+	return as
+}
+
+func GapService(devName string) BleSvc {
+	return BleSvc{
+		Uuid:    BleUuid{0x1800, [16]byte{}},
+		SvcType: BLE_SVC_TYPE_PRIMARY,
+		Chrs: []BleChr{
+			// Device name.
+			BleChr{
+				Uuid:       BleUuid{0x2a00, [16]byte{}},
+				Flags:      BLE_GATT_F_READ,
+				MinKeySize: 0,
+				AccessCb: func(access BleGattAccess) (uint8, []byte) {
+					return 0, []byte(devName)
+				},
+			},
+
+			// Appearance.
+			BleChr{
+				Uuid:       BleUuid{0x2a01, [16]byte{}},
+				Flags:      BLE_GATT_F_READ,
+				MinKeySize: 0,
+				AccessCb: func(access BleGattAccess) (uint8, []byte) {
+					return 0, []byte{0, 0}
+				},
+			},
+
+			// Peripheral privacy flag.
+			BleChr{
+				Uuid:       BleUuid{0x2a02, [16]byte{}},
+				Flags:      BLE_GATT_F_READ,
+				MinKeySize: 0,
+				AccessCb: func(access BleGattAccess) (uint8, []byte) {
+					return 0, []byte{0}
+				},
+			},
+
+			// Reconnection address.
+			BleChr{
+				Uuid:       BleUuid{0x2a03, [16]byte{}},
+				Flags:      BLE_GATT_F_READ,
+				MinKeySize: 0,
+				AccessCb: func(access BleGattAccess) (uint8, []byte) {
+					return 0, []byte{0, 0, 0, 0, 0, 0}
+				},
+			},
+
+			// Peripheral preferred connection parameters.
+			BleChr{
+				Uuid:       BleUuid{0x2a04, [16]byte{}},
+				Flags:      BLE_GATT_F_READ,
+				MinKeySize: 0,
+				AccessCb: func(access BleGattAccess) (uint8, []byte) {
+					return 0, []byte{0, 0, 0, 0, 0, 0, 0, 0}
+				},
+			},
+		},
+	}
+}
+
+func GattService() BleSvc {
+	return BleSvc{
+		Uuid:    BleUuid{0x1801, [16]byte{}},
+		SvcType: BLE_SVC_TYPE_PRIMARY,
+		Chrs: []BleChr{
+			// Device name.
+			BleChr{
+				Uuid:       BleUuid{0x2a05, [16]byte{}},
+				Flags:      BLE_GATT_F_INDICATE,
+				MinKeySize: 0,
+				AccessCb: func(access BleGattAccess) (uint8, []byte) {
+					return 0, []byte{0, 0, 0, 0}
+				},
+			},
+		},
+	}
+}
+
+func GenCoapService(x *BleXport, svcUuid BleUuid, reqChrUuid BleUuid,
+	rspChrUuid BleUuid, resources []oic.Resource) (BleSvc, error) {
+
+	svr := NewBleOicSvr(x, svcUuid, rspChrUuid)
+	for _, r := range resources {
+		if err := svr.AddResource(r); err != nil {
+			return BleSvc{}, err
+		}
+	}
+
+	svc := BleSvc{
+		Uuid:    svcUuid,
+		SvcType: BLE_SVC_TYPE_PRIMARY,
+		Chrs: []BleChr{
+			BleChr{
+				Uuid:       reqChrUuid,
+				Flags:      BLE_GATT_F_WRITE_NO_RSP, /* XXX: Security */
+				MinKeySize: 0,
+				AccessCb: func(access BleGattAccess) (uint8, []byte) {
+					return svr.Rx(access), nil
+				},
+			},
+			BleChr{
+				Uuid:       rspChrUuid,
+				Flags:      BLE_GATT_F_NOTIFY, /* XXX: Security */
+				MinKeySize: 0,
+				AccessCb:   nil,
+			},
+		},
+	}
+
+	return svc, nil
+}
+
+func GwService(x *BleXport) (BleSvc, error) {
+	svcUuid, _ := ParseUuid(GwSvcUuid)
+	reqChrUuid, _ := ParseUuid(GwReqChrUuid)
+	rspChrUuid, _ := ParseUuid(GwRspChrUuid)
+
+	resources := []oic.Resource{
+		oic.Resource{
+			Name: "mynewt.yourmom",
+			ReadCb: func(uri string, data []byte) (coap.COAPCode, []byte) {
+				return coap.Content, []byte{1, 2, 3, 4}
+			},
+		},
+	}
+
+	return GenCoapService(x, svcUuid, reqChrUuid, rspChrUuid, resources)
+}
+
+func ResChrIdLookup(mgmtChrs BleMgmtChrs, resType sesn.ResourceType) *BleChrId {
+	m := map[sesn.ResourceType]*BleChrId{
+		sesn.RES_TYPE_PUBLIC:  mgmtChrs.ResPublicReqChr,
+		sesn.RES_TYPE_UNAUTH: mgmtChrs.ResGwReqChr,
+		sesn.RES_TYPE_SECURE: mgmtChrs.ResPrivateReqChr,
+	}
+
+	return m[resType]
+}
+
+func BuildMgmtChrs(mgmtProto sesn.MgmtProto) (BleMgmtChrs, error) {
+	mgmtChrs := BleMgmtChrs{}
+
+	nmpSvcUuid, _ := ParseUuid(NmpPlainSvcUuid)
+	nmpChrUuid, _ := ParseUuid(NmpPlainChrUuid)
+
+	ompSvcUuid, _ := ParseUuid(OmpUnsecSvcUuid)
+	ompReqChrUuid, _ := ParseUuid(OmpUnsecReqChrUuid)
+	ompRspChrUuid, _ := ParseUuid(OmpUnsecRspChrUuid)
+
+	gwSvcUuid, _ := ParseUuid(GwSvcUuid)
+	gwReqChrUuid, _ := ParseUuid(GwReqChrUuid)
+	gwRspChrUuid, _ := ParseUuid(GwRspChrUuid)
+
+	switch mgmtProto {
+	case sesn.MGMT_PROTO_NMP:
+		mgmtChrs.NmpReqChr = &BleChrId{nmpSvcUuid, nmpChrUuid}
+		mgmtChrs.NmpRspChr = &BleChrId{nmpSvcUuid, nmpChrUuid}
+
+	case sesn.MGMT_PROTO_OMP:
+		mgmtChrs.NmpReqChr = &BleChrId{ompSvcUuid, ompReqChrUuid}
+		mgmtChrs.NmpRspChr = &BleChrId{ompSvcUuid, ompRspChrUuid}
+
+	default:
+		return mgmtChrs,
+			fmt.Errorf("invalid management protocol: %+v", mgmtProto)
+	}
+
+	mgmtChrs.ResGwReqChr = &BleChrId{gwSvcUuid, gwReqChrUuid}
+	mgmtChrs.ResGwRspChr = &BleChrId{gwSvcUuid, gwRspChrUuid}
+
+	return mgmtChrs, nil
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go
index 0e622da..da7cf30 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go
@@ -29,6 +29,7 @@ import (
 	log "github.com/Sirupsen/logrus"
 
 	"mynewt.apache.org/newt/util/unixchild"
+	"mynewt.apache.org/newtmgr/nmxact/adv"
 	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
 	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
 	"mynewt.apache.org/newtmgr/nmxact/scan"
@@ -115,6 +116,8 @@ type BleXport struct {
 	randAddr     *BleAddr
 	stateMtx     sync.Mutex
 	scanner      *BleScanner
+	advertiser   *Advertiser
+	cm           ChrMgr
 }
 
 func NewBleXport(cfg XportCfg) (*BleXport, error) {
@@ -168,17 +171,18 @@ func (bx *BleXport) BuildScanner() (scan.Scanner, error) {
 	return bx.scanner, nil
 }
 
-func (bx *BleXport) BuildSesn(cfg sesn.SesnCfg) (sesn.Sesn, error) {
-	switch cfg.MgmtProto {
-	case sesn.MGMT_PROTO_NMP:
-		return NewBlePlainSesn(bx, cfg), nil
-	case sesn.MGMT_PROTO_OMP:
-		return NewBleOicSesn(bx, cfg), nil
-	default:
-		return nil, fmt.Errorf(
-			"Invalid management protocol: %d; expected NMP or OMP",
-			cfg.MgmtProto)
+func (bx *BleXport) BuildAdvertiser() (adv.Advertiser, error) {
+	// The transport only allows a single advertiser.  This is because the
+	// slave privileges need to managed among all the advertise operations.
+	if bx.advertiser == nil {
+		bx.advertiser = NewAdvertiser(bx)
 	}
+
+	return bx.advertiser, nil
+}
+
+func (bx *BleXport) BuildSesn(cfg sesn.SesnCfg) (sesn.Sesn, error) {
+	return NewBleSesn(bx, cfg)
 }
 
 func (bx *BleXport) addSyncListener() (*Listener, error) {
@@ -193,6 +197,12 @@ func (bx *BleXport) addResetListener() (*Listener, error) {
 	return bx.AddListener(key)
 }
 
+func (bx *BleXport) addAccessListener() (*Listener, error) {
+	key := TchKey(MSG_TYPE_ACCESS_EVT, -1)
+	nmxutil.LogAddListener(3, key, 0, "access")
+	return bx.AddListener(key)
+}
+
 func (bx *BleXport) querySyncStatus() (bool, error) {
 	req := &BleSyncReq{
 		Op:   MSG_OP_REQ,
@@ -432,12 +442,16 @@ func (bx *BleXport) startOnce() error {
 					"Timeout waiting for host <-> controller sync")
 				bx.shutdown(true, err)
 				return err
+			case <-bx.stopChan:
+				return nmxutil.NewXportError("Transport startup aborted")
 			}
 		}
 	}
 
-	// Host and controller are synced.  Listen for sync loss and stack reset in
-	// the background.
+	// Host and controller are synced.  Listen for events in the background:
+	//     * sync loss
+	//     * stack reset
+	//     * GATT access
 	go func() {
 		resetl, err := bx.addResetListener()
 		if err != nil {
@@ -446,6 +460,13 @@ func (bx *BleXport) startOnce() error {
 		}
 		defer bx.RemoveListener(resetl)
 
+		accessl, err := bx.addAccessListener()
+		if err != nil {
+			bx.shutdown(true, err)
+			return
+		}
+		defer bx.RemoveListener(accessl)
+
 		for {
 			select {
 			case err := <-syncl.ErrChan:
@@ -481,6 +502,18 @@ func (bx *BleXport) startOnce() error {
 					}
 				}
 
+			case err := <-accessl.ErrChan:
+				bx.shutdown(true, err)
+				return
+			case bm := <-accessl.MsgChan:
+				switch msg := bm.(type) {
+				case *BleAccessEvt:
+					if err := bx.cm.Access(bx, msg); err != nil {
+						log.Debugf("Error sending access status: %s",
+							err.Error())
+					}
+				}
+
 			case <-bx.stopChan:
 				return
 			}
@@ -583,6 +616,10 @@ func (bx *BleXport) Tx(data []byte) error {
 	return bx.txNoSync(data)
 }
 
+func (bx *BleXport) SetServices(svcs []BleSvc) error {
+	return bx.cm.SetServices(bx, svcs)
+}
+
 func (bx *BleXport) AddListener(key ListenerKey) (*Listener, error) {
 	listener := NewListener()
 	if err := bx.d.AddListener(key, listener); err != nil {
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/chrmgr.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/chrmgr.go
new file mode 100644
index 0000000..4bc78c8
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/chrmgr.go
@@ -0,0 +1,123 @@
+package nmble
+
+import (
+	"fmt"
+
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+)
+
+type chrMgrElem struct {
+	AttHandle uint16
+	SvcUuid   BleUuid
+	ChrUuid   BleUuid
+	Cb        BleGattAccessFn
+}
+
+type ChrMgr struct {
+	chrs map[uint16]chrMgrElem
+}
+
+func (cm *ChrMgr) Clear() {
+	cm.chrs = map[uint16]chrMgrElem{}
+}
+
+func (cm *ChrMgr) add(chr chrMgrElem) error {
+	if _, ok := cm.chrs[chr.AttHandle]; ok {
+		return fmt.Errorf("Characteristic with duplicate ATT handle: %d",
+			chr.AttHandle)
+	}
+
+	cm.chrs[chr.AttHandle] = chr
+	return nil
+}
+
+func (cm *ChrMgr) SetServices(x *BleXport, svcs []BleSvc) error {
+	if err := ClearSvcsXact(x); err != nil {
+		return err
+	}
+	cm.Clear()
+
+	addSvcs := make([]BleAddSvc, len(svcs))
+	for i, svc := range svcs {
+		addSvcs[i] = BleSvcToAddSvc(svc)
+	}
+
+	if err := AddSvcsXact(x, addSvcs); err != nil {
+		return err
+	}
+
+	regSvcs, err := CommitSvcsXact(x)
+	if err != nil {
+		return err
+	}
+
+	//               [uuid => svc]
+	//              /             \
+	// [uuid => chr]               [uuid => chr]
+	svcMap := map[BleUuid]map[BleUuid]BleChr{}
+
+	for _, svc := range svcs {
+		m := map[BleUuid]BleChr{}
+		svcMap[svc.Uuid] = m
+
+		for _, chr := range svc.Chrs {
+			m[chr.Uuid] = chr
+		}
+	}
+
+	for _, rs := range regSvcs {
+		srcSvc, ok := svcMap[rs.Uuid]
+		if !ok {
+			// XXX: Log
+			continue
+		}
+
+		for _, rc := range rs.Chrs {
+			srcChr, ok := srcSvc[rc.Uuid]
+			if !ok {
+				// XXX: Log
+				continue
+			}
+
+			cm.add(chrMgrElem{
+				AttHandle: rc.ValHandle,
+				SvcUuid:   rs.Uuid,
+				ChrUuid:   rc.Uuid,
+				Cb:        srcChr.AccessCb,
+			})
+		}
+	}
+
+	return nil
+}
+
+func (cm *ChrMgr) findByAttHandle(handle uint16) *chrMgrElem {
+	chr, ok := cm.chrs[handle]
+	if !ok {
+		return nil
+	} else {
+		return &chr
+	}
+}
+
+func (cm *ChrMgr) Access(x *BleXport, evt *BleAccessEvt) error {
+	chr := cm.findByAttHandle(evt.AttHandle)
+	if chr == nil {
+		return AccessStatusXact(x, uint8(ERR_CODE_ATT_INVALID_HANDLE), nil)
+	}
+
+	if chr.Cb == nil {
+		return AccessStatusXact(x, 0, nil)
+	}
+
+	access := BleGattAccess{
+		Op:         evt.GattOp,
+		ConnHandle: evt.ConnHandle,
+		SvcUuid:    chr.SvcUuid,
+		ChrUuid:    chr.ChrUuid,
+		Data:       evt.Data.Bytes,
+	}
+
+	status, val := chr.Cb(access)
+	return AccessStatusXact(x, status, val)
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/conn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/conn.go
new file mode 100644
index 0000000..bf8fd10
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/conn.go
@@ -0,0 +1,713 @@
+package nmble
+
+import (
+	"fmt"
+	"sync"
+	"time"
+
+	log "github.com/Sirupsen/logrus"
+
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
+)
+
+type Notification struct {
+	Chr        *Characteristic
+	Data       []byte
+	Indication bool
+}
+
+type NotifyListener struct {
+	NotifyChan chan Notification
+	ErrChan    chan error
+}
+
+func NewNotifyListener() *NotifyListener {
+	return &NotifyListener{
+		NotifyChan: make(chan Notification),
+		ErrChan:    make(chan error),
+	}
+}
+
+type Conn struct {
+	bx      *BleXport
+	rxvr    *Receiver
+	attMtu  int
+	profile Profile
+	desc    BleConnDesc
+
+	connHandle     uint16
+	connecting     bool
+	disconnectChan chan error
+	wg             sync.WaitGroup
+
+	// Terminates all go routines.  Gets set to null after disconnect.
+	stopChan chan struct{}
+
+	notifyMap map[*Characteristic][](*NotifyListener)
+
+	// Protects:
+	// * connHandle
+	// * connecting
+	// * notifyMap
+	// * stopChan
+	mtx sync.Mutex
+}
+
+func NewConn(bx *BleXport) *Conn {
+	return &Conn{
+		bx:             bx,
+		rxvr:           NewReceiver(nmxutil.GetNextId(), bx, 1),
+		connHandle:     BLE_CONN_HANDLE_NONE,
+		attMtu:         BLE_ATT_MTU_DFLT,
+		disconnectChan: make(chan error, 1),
+		stopChan:       make(chan struct{}),
+		notifyMap:      map[*Characteristic][](*NotifyListener){},
+	}
+}
+
+func (c *Conn) DisconnectChan() <-chan error {
+	return c.disconnectChan
+}
+
+func (c *Conn) initiateShutdown() bool {
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+
+	if c.stopChan == nil {
+		return false
+	}
+
+	close(c.stopChan)
+	c.stopChan = nil
+
+	return true
+}
+
+func (c *Conn) abortNotifyListeners(err error) {
+	// No need to lock mutex; this should only be called after all go routines
+	// have terminated.
+	for _, nls := range c.notifyMap {
+		for _, nl := range nls {
+			nl.ErrChan <- err
+			close(nl.NotifyChan)
+			close(nl.ErrChan)
+		}
+	}
+}
+
+func (c *Conn) shutdown(err error) {
+	if !c.initiateShutdown() {
+		return
+	}
+
+	c.connecting = false
+	c.connHandle = BLE_CONN_HANDLE_NONE
+
+	c.bx.StopWaitingForMaster(c, err)
+
+	c.rxvr.RemoveAll("shutdown")
+	c.rxvr.WaitUntilNoListeners()
+
+	c.wg.Wait()
+
+	c.abortNotifyListeners(err)
+
+	c.disconnectChan <- err
+	close(c.disconnectChan)
+}
+
+func (c *Conn) newDisconnectError(reason int) error {
+	str := fmt.Sprintf("BLE peer disconnected; "+
+		"reason=\"%s\" (%d) connection=%s",
+		ErrCodeToString(reason), reason, c.desc.String())
+
+	return nmxutil.NewBleSesnDisconnectError(reason, str)
+}
+
+// Listens for events in the background.
+func (c *Conn) eventListen(bl *Listener) error {
+	c.wg.Add(1)
+
+	go func() {
+		defer c.wg.Done()
+		defer c.rxvr.RemoveListener("connect", bl)
+
+		for {
+			select {
+			case <-c.stopChan:
+				return
+
+			case err := <-bl.ErrChan:
+				go c.shutdown(err)
+				return
+
+			case bm := <-bl.MsgChan:
+				switch msg := bm.(type) {
+				case *BleMtuChangeEvt:
+					if msg.Status != 0 {
+						err := StatusError(MSG_OP_EVT,
+							MSG_TYPE_MTU_CHANGE_EVT,
+							msg.Status)
+						log.Debugf(err.Error())
+					} else {
+						log.Debugf("BLE ATT MTU updated; from=%d to=%d",
+							c.attMtu, msg.Mtu)
+						c.attMtu = int(msg.Mtu)
+					}
+
+				case *BleEncChangeEvt:
+					var err error
+					if msg.Status != 0 {
+						err = StatusError(MSG_OP_EVT,
+							MSG_TYPE_ENC_CHANGE_EVT,
+							msg.Status)
+						log.Debugf(err.Error())
+					} else {
+						log.Debugf("Connection encrypted; conn_handle=%d",
+							msg.ConnHandle)
+					}
+
+				case *BleDisconnectEvt:
+					go c.shutdown(c.newDisconnectError(msg.Reason))
+					return
+
+				default:
+				}
+			}
+		}
+	}()
+	return nil
+}
+
+func (c *Conn) rxNotify(msg *BleNotifyRxEvt) {
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+
+	chr := c.profile.FindChrByHandle(uint16(msg.AttrHandle))
+	if chr == nil {
+		return
+	}
+
+	nls := c.notifyMap[chr]
+	if nls == nil {
+		return
+	}
+
+	n := Notification{
+		Chr:        chr,
+		Data:       msg.Data.Bytes,
+		Indication: msg.Indication,
+	}
+	for _, nl := range nls {
+		nl.NotifyChan <- n
+	}
+}
+
+// Listens for incoming notifications and indications.
+func (c *Conn) notifyListen() error {
+	key := TchKey(MSG_TYPE_NOTIFY_RX_EVT, int(c.connHandle))
+	bl, err := c.rxvr.AddListener("notifications", key)
+	if err != nil {
+		return err
+	}
+
+	c.wg.Add(1)
+	go func() {
+		defer c.wg.Done()
+		defer c.rxvr.RemoveListener("notifications", bl)
+
+		for {
+			select {
+			case <-c.stopChan:
+				return
+
+			case <-bl.ErrChan:
+				return
+
+			case bm := <-bl.MsgChan:
+				switch msg := bm.(type) {
+				case *BleNotifyRxEvt:
+					c.rxNotify(msg)
+				}
+			}
+		}
+	}()
+
+	return nil
+}
+
+func (c *Conn) startConnecting() error {
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+
+	if c.stopChan == nil {
+		return fmt.Errorf("Attempt to re-use conn object")
+	}
+
+	if c.connHandle != BLE_CONN_HANDLE_NONE {
+		return nmxutil.NewSesnAlreadyOpenError(
+			"BLE connection already established")
+	}
+	if c.connecting {
+		return nmxutil.NewSesnAlreadyOpenError(
+			"BLE connection already being established")
+	}
+
+	c.connecting = true
+	return nil
+}
+
+func (c *Conn) stopConnecting() {
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+
+	c.connecting = false
+}
+
+func (c *Conn) finalizeConnection(connHandle uint16,
+	eventListener *Listener) error {
+
+	c.mtx.Lock()
+	c.connecting = false
+	c.connHandle = connHandle
+	c.mtx.Unlock()
+
+	// Listen for events in the background.
+	if err := c.eventListen(eventListener); err != nil {
+		return err
+	}
+
+	// Listen for notifications in the background.
+	if err := c.notifyListen(); err != nil {
+		return err
+	}
+
+	d, err := ConnFindXact(c.bx, c.connHandle)
+	if err != nil {
+		return err
+	}
+	c.desc = d
+
+	return nil
+}
+
+func (c *Conn) IsConnected() bool {
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+
+	return c.connHandle != BLE_CONN_HANDLE_NONE
+}
+
+func (c *Conn) Connect(bx *BleXport, ownAddrType BleAddrType, peer BleDev,
+	timeout time.Duration) error {
+
+	if err := c.startConnecting(); err != nil {
+		return err
+	}
+	defer c.stopConnecting()
+
+	r := NewBleConnectReq()
+	r.OwnAddrType = ownAddrType
+	r.PeerAddrType = peer.AddrType
+	r.PeerAddr = peer.Addr
+
+	// Initiating a connection requires dedicated master privileges.
+	if err := c.bx.AcquireMaster(c); err != nil {
+		return err
+	}
+	defer c.bx.ReleaseMaster()
+
+	bl, err := c.rxvr.AddListener("connect", SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+
+	// Tell blehostd to initiate connection.
+	connHandle, err := connect(c.bx, bl, r, timeout)
+	if err != nil {
+		bhe := nmxutil.ToBleHost(err)
+		if bhe != nil && bhe.Status == ERR_CODE_EDONE {
+			// Already connected.
+			c.rxvr.RemoveListener("connect", bl)
+			return fmt.Errorf("Already connected to peer %s", peer)
+		} else if !nmxutil.IsXport(err) {
+			// The transport did not restart; always attempt to cancel the
+			// connect operation.  In most cases, the host has already stopped
+			// connecting and will respond with an "ealready" error that can be
+			// ignored.
+			if err := c.connCancel(); err != nil {
+				log.Errorf("Failed to cancel connect in progress: %s",
+					err.Error())
+			}
+		}
+
+		c.rxvr.RemoveListener("connect", bl)
+		return err
+	}
+
+	if err := c.finalizeConnection(connHandle, bl); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *Conn) Inherit(connHandle uint16, bl *Listener) error {
+	if err := c.startConnecting(); err != nil {
+		return err
+	}
+
+	if err := c.finalizeConnection(connHandle, bl); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *Conn) ConnInfo() BleConnDesc {
+	return c.desc
+}
+
+func (c *Conn) AttMtu() int {
+	return c.attMtu
+}
+
+func (c *Conn) discAllDscsOnce(startHandle uint16, endHandle uint16) (
+	[]*Descriptor, error) {
+
+	r := NewBleDiscAllDscsReq()
+	r.ConnHandle = c.connHandle
+	r.StartHandle = int(startHandle)
+	r.EndHandle = int(endHandle)
+
+	bl, err := c.rxvr.AddListener("disc-all-dscs", SeqKey(r.Seq))
+	if err != nil {
+		return nil, err
+	}
+	defer c.rxvr.RemoveListener("disc-all-dscs", bl)
+
+	rawDscs, err := discAllDscs(c.bx, bl, r)
+	if err != nil {
+		return nil, err
+	}
+
+	dscs := make([]*Descriptor, len(rawDscs))
+	for i, rd := range rawDscs {
+		dscs[i] = &Descriptor{
+			Uuid:   rd.Uuid,
+			Handle: uint16(rd.Handle),
+		}
+	}
+
+	return dscs, nil
+}
+
+func (c *Conn) discAllDscs(chrs []*Characteristic, svcEndHandle uint16) error {
+	for i, _ := range chrs {
+		chr := chrs[i]
+
+		// Only discover descriptors if this characteristic has a CCCD.
+		if chr.SubscribeType() != 0 {
+			var endHandle uint16
+			if i < len(chrs)-1 {
+				endHandle = chrs[i+1].DefHandle - 1
+			} else {
+				endHandle = svcEndHandle
+			}
+
+			dscs, err := c.discAllDscsOnce(chrs[i].ValHandle, endHandle)
+			if err != nil {
+				return err
+			}
+
+			chr.Dscs = dscs
+		}
+	}
+
+	return nil
+}
+
+func (c *Conn) discAllChrsOnce(svc Service) ([]*Characteristic, error) {
+	r := NewBleDiscAllChrsReq()
+	r.ConnHandle = c.connHandle
+	r.StartHandle = int(svc.StartHandle)
+	r.EndHandle = int(svc.EndHandle)
+
+	bl, err := c.rxvr.AddListener("disc-all-chrs", SeqKey(r.Seq))
+	if err != nil {
+		return nil, err
+	}
+	defer c.rxvr.RemoveListener("disc-all-chrs", bl)
+
+	rawChrs, err := discAllChrs(c.bx, bl, r)
+	if err != nil {
+		return nil, err
+	}
+
+	chrs := make([]*Characteristic, len(rawChrs))
+	for i, rc := range rawChrs {
+		chrs[i] = &Characteristic{
+			Uuid:       rc.Uuid,
+			DefHandle:  uint16(rc.DefHandle),
+			ValHandle:  uint16(rc.ValHandle),
+			Properties: BleChrFlags(rc.Properties),
+		}
+	}
+
+	if err := c.discAllDscs(chrs, svc.EndHandle); err != nil {
+		return nil, err
+	}
+
+	return chrs, nil
+}
+
+func (c *Conn) discAllChrs(svcs []Service) error {
+	for i, _ := range svcs {
+		chrs, err := c.discAllChrsOnce(svcs[i])
+		if err != nil {
+			return err
+		}
+
+		svcs[i].Chrs = chrs
+	}
+
+	return nil
+}
+
+func (c *Conn) discAllSvcs() ([]Service, error) {
+	r := NewBleDiscAllSvcsReq()
+	r.ConnHandle = c.connHandle
+
+	bl, err := c.rxvr.AddListener("disc-all-svcs", SeqKey(r.Seq))
+	if err != nil {
+		return nil, err
+	}
+	defer c.rxvr.RemoveListener("disc-all-svcs", bl)
+
+	rawSvcs, err := discAllSvcs(c.bx, bl, r)
+	if err != nil {
+		return nil, err
+	}
+
+	svcs := make([]Service, len(rawSvcs))
+	for i, rs := range rawSvcs {
+		svcs[i] = Service{
+			Uuid:        rs.Uuid,
+			StartHandle: uint16(rs.StartHandle),
+			EndHandle:   uint16(rs.EndHandle),
+		}
+	}
+
+	return svcs, nil
+}
+
+func (c *Conn) DiscoverSvcs() error {
+	svcs, err := c.discAllSvcs()
+	if err != nil {
+		return err
+	}
+
+	if err := c.discAllChrs(svcs); err != nil {
+		return err
+	}
+
+	c.profile.SetServices(svcs)
+
+	return nil
+}
+
+func (c *Conn) Profile() *Profile {
+	return &c.profile
+}
+
+func isExchangeMtuError(err error) bool {
+	if err == nil {
+		return false
+	}
+
+	// If the operation failed because the peer already initiated the
+	// exchange, just pretend it was successful.
+	bhe := nmxutil.ToBleHost(err)
+	if bhe == nil {
+		return true
+	}
+
+	switch bhe.Status {
+	case ERR_CODE_EALREADY:
+		return false
+	case ERR_CODE_ATT_BASE + ERR_CODE_ATT_REQ_NOT_SUPPORTED:
+		return false
+	default:
+		return true
+	}
+}
+
+func (c *Conn) ExchangeMtu() error {
+	r := NewBleExchangeMtuReq()
+	r.ConnHandle = c.connHandle
+
+	bl, err := c.rxvr.AddListener("exchange-mtu", SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer c.rxvr.RemoveListener("exchange-mtu", bl)
+
+	mtu, err := exchangeMtu(c.bx, bl, r)
+	if isExchangeMtuError(err) {
+		return err
+	}
+
+	c.attMtu = mtu
+	return nil
+}
+
+func (c *Conn) WriteHandle(handle uint16, payload []byte,
+	name string) error {
+
+	r := NewBleWriteReq()
+	r.ConnHandle = c.connHandle
+	r.AttrHandle = int(handle)
+	r.Data.Bytes = payload
+
+	bl, err := c.rxvr.AddListener(name, SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer c.rxvr.RemoveListener(name, bl)
+
+	if err := write(c.bx, bl, r); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *Conn) WriteHandleNoRsp(handle uint16, payload []byte,
+	name string) error {
+
+	r := NewBleWriteCmdReq()
+	r.ConnHandle = c.connHandle
+	r.AttrHandle = int(handle)
+	r.Data.Bytes = payload
+
+	bl, err := c.rxvr.AddListener(name, SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer c.rxvr.RemoveListener(name, bl)
+
+	if err := writeCmd(c.bx, bl, r); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (c *Conn) WriteChr(chr *Characteristic, payload []byte,
+	name string) error {
+
+	return c.WriteHandle(chr.ValHandle, payload, name)
+}
+
+func (c *Conn) WriteChrNoRsp(chr *Characteristic, payload []byte,
+	name string) error {
+
+	return c.WriteHandleNoRsp(chr.ValHandle, payload, name)
+}
+
+func (c *Conn) Subscribe(chr *Characteristic) error {
+	uuid := BleUuid{CccdUuid, [16]byte{}}
+	dsc := FindDscByUuid(chr, uuid)
+	if dsc == nil {
+		return fmt.Errorf("Cannot subscribe to characteristic %s; no CCCD",
+			chr.Uuid.String())
+	}
+
+	var payload []byte
+	switch chr.SubscribeType() {
+	case BLE_GATT_F_NOTIFY:
+		payload = []byte{1, 0}
+	case BLE_GATT_F_INDICATE:
+		payload = []byte{2, 0}
+	default:
+		return fmt.Errorf("Cannot subscribe to characteristic %s; "+
+			"properties indicate unsubscribable", chr.Uuid.String())
+	}
+
+	return c.WriteHandle(dsc.Handle, payload, "subscribe")
+}
+
+func (c *Conn) ListenForNotifications(chr *Characteristic) *NotifyListener {
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+
+	nl := NewNotifyListener()
+	slice := c.notifyMap[chr]
+
+	slice = append(slice, nl)
+	c.notifyMap[chr] = slice
+
+	return nl
+}
+
+func (c *Conn) terminate() error {
+	r := NewBleTerminateReq()
+	r.ConnHandle = c.connHandle
+	r.HciReason = ERR_CODE_HCI_REM_USER_CONN_TERM
+
+	bl, err := c.rxvr.AddListener("terminate", SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer c.rxvr.RemoveListener("terminate", bl)
+
+	if err := terminate(c.bx, bl, r); err != nil {
+		// Ignore ealready errors.
+		bhdErr := nmxutil.ToBleHost(err)
+		if bhdErr == nil || bhdErr.Status != ERR_CODE_EALREADY {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (c *Conn) connCancel() error {
+	r := NewBleConnCancelReq()
+
+	bl, err := c.rxvr.AddListener("conn-cancel", SeqKey(r.Seq))
+	if err != nil {
+		return err
+	}
+	defer c.rxvr.RemoveListener("conn-cancel", bl)
+
+	if err := connCancel(c.bx, bl, r); err != nil {
+		// Ignore ealready errors.
+		bhdErr := nmxutil.ToBleHost(err)
+		if bhdErr == nil || bhdErr.Status != ERR_CODE_EALREADY {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (c *Conn) Stop() error {
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+
+	var err error
+	if c.connHandle != BLE_CONN_HANDLE_NONE {
+		err = c.terminate()
+	} else if c.connecting {
+		err = c.connCancel()
+	}
+
+	if err != nil {
+		// Something went unexpectedly wrong.  Just force a shutdown.
+		go c.shutdown(err)
+	}
+
+	return nil
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/dispatch.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/dispatch.go
index 10e6fee..ffdb1d4 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/dispatch.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/dispatch.go
@@ -57,9 +57,12 @@ func errRspCtor() Msg              { return &BleErrRsp{} }
 func syncRspCtor() Msg             { return &BleSyncRsp{} }
 func connectRspCtor() Msg          { return &BleConnectRsp{} }
 func terminateRspCtor() Msg        { return &BleTerminateRsp{} }
+func discAllSvcsRspCtor() Msg      { return &BleDiscAllSvcsRsp{} }
 func discSvcUuidRspCtor() Msg      { return &BleDiscSvcUuidRsp{} }
 func discAllChrsRspCtor() Msg      { return &BleDiscAllChrsRsp{} }
 func discChrUuidRspCtor() Msg      { return &BleDiscChrUuidRsp{} }
+func discAllDscsRspCtor() Msg      { return &BleDiscAllDscsRsp{} }
+func writeRspCtor() Msg            { return &BleWriteRsp{} }
 func writeCmdRspCtor() Msg         { return &BleWriteCmdRsp{} }
 func exchangeMtuRspCtor() Msg      { return &BleExchangeMtuRsp{} }
 func genRandAddrRspCtor() Msg      { return &BleGenRandAddrRsp{} }
@@ -71,27 +74,44 @@ func setPreferredMtuRspCtor() Msg  { return &BleSetPreferredMtuRsp{} }
 func securityInitiateRspCtor() Msg { return &BleSecurityInitiateRsp{} }
 func connFindRspCtor() Msg         { return &BleConnFindRsp{} }
 func resetRspCtor() Msg            { return &BleResetRsp{} }
+func advStartRspCtor() Msg         { return &BleAdvStartRsp{} }
+func advStopRspCtor() Msg          { return &BleAdvStopRsp{} }
+func advSetDataRspCtor() Msg       { return &BleAdvSetDataRsp{} }
+func advRspSetDataRspCtor() Msg    { return &BleAdvRspSetDataRsp{} }
+func advFieldsRspCtor() Msg        { return &BleAdvFieldsRsp{} }
+func clearSvcsRspCtor() Msg        { return &BleClearSvcsRsp{} }
+func addSvcsRspCtor() Msg          { return &BleAddSvcsRsp{} }
+func commitSvcsRspCtor() Msg       { return &BleCommitSvcsRsp{} }
+func accessStatusRspCtor() Msg     { return &BleAccessStatusRsp{} }
+func notifyRspCtor() Msg           { return &BleNotifyRsp{} }
+func findChrRspCtor() Msg          { return &BleFindChrRsp{} }
 
 func syncEvtCtor() Msg       { return &BleSyncEvt{} }
 func connectEvtCtor() Msg    { return &BleConnectEvt{} }
 func disconnectEvtCtor() Msg { return &BleDisconnectEvt{} }
 func discSvcEvtCtor() Msg    { return &BleDiscSvcEvt{} }
 func discChrEvtCtor() Msg    { return &BleDiscChrEvt{} }
+func discDscEvtCtor() Msg    { return &BleDiscDscEvt{} }
+func writeAckEvtCtor() Msg   { return &BleWriteAckEvt{} }
 func notifyRxEvtCtor() Msg   { return &BleNotifyRxEvt{} }
 func mtuChangeEvtCtor() Msg  { return &BleMtuChangeEvt{} }
 func scanEvtCtor() Msg       { return &BleScanEvt{} }
 func scanTmoEvtCtor() Msg    { return &BleScanTmoEvt{} }
 func encChangeEvtCtor() Msg  { return &BleEncChangeEvt{} }
 func resetEvtCtor() Msg      { return &BleResetEvt{} }
+func accessEvtCtor() Msg     { return &BleAccessEvt{} }
 
 var msgCtorMap = map[OpTypePair]msgCtor{
 	{MSG_OP_RSP, MSG_TYPE_ERR}:               errRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_SYNC}:              syncRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_CONNECT}:           connectRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_TERMINATE}:         terminateRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_DISC_ALL_SVCS}:     discAllSvcsRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_DISC_SVC_UUID}:     discSvcUuidRspCtor,
-	{MSG_OP_RSP, MSG_TYPE_DISC_CHR_UUID}:     discChrUuidRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_DISC_ALL_CHRS}:     discAllChrsRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_DISC_CHR_UUID}:     discChrUuidRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_DISC_ALL_DSCS}:     discAllDscsRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_WRITE}:             writeRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_WRITE_CMD}:         writeCmdRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_EXCHANGE_MTU}:      exchangeMtuRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_GEN_RAND_ADDR}:     genRandAddrRspCtor,
@@ -103,18 +123,32 @@ var msgCtorMap = map[OpTypePair]msgCtor{
 	{MSG_OP_RSP, MSG_TYPE_SECURITY_INITIATE}: securityInitiateRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_CONN_FIND}:         connFindRspCtor,
 	{MSG_OP_RSP, MSG_TYPE_RESET}:             resetRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_ADV_START}:         advStartRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_ADV_STOP}:          advStopRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_ADV_SET_DATA}:      advSetDataRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_ADV_RSP_SET_DATA}:  advRspSetDataRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_ADV_FIELDS}:        advFieldsRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_CLEAR_SVCS}:        clearSvcsRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_ADD_SVCS}:          addSvcsRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_COMMIT_SVCS}:       commitSvcsRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_ACCESS_STATUS}:     accessStatusRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_NOTIFY}:            notifyRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_FIND_CHR}:          findChrRspCtor,
 
 	{MSG_OP_EVT, MSG_TYPE_SYNC_EVT}:       syncEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_CONNECT_EVT}:    connectEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_DISCONNECT_EVT}: disconnectEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_DISC_SVC_EVT}:   discSvcEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_DISC_CHR_EVT}:   discChrEvtCtor,
+	{MSG_OP_EVT, MSG_TYPE_DISC_DSC_EVT}:   discDscEvtCtor,
+	{MSG_OP_EVT, MSG_TYPE_WRITE_ACK_EVT}:  writeAckEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_NOTIFY_RX_EVT}:  notifyRxEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_MTU_CHANGE_EVT}: mtuChangeEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_SCAN_EVT}:       scanEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_SCAN_TMO_EVT}:   scanTmoEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_ENC_CHANGE_EVT}: encChangeEvtCtor,
 	{MSG_OP_EVT, MSG_TYPE_RESET_EVT}:      resetEvtCtor,
+	{MSG_OP_EVT, MSG_TYPE_ACCESS_EVT}:     accessEvtCtor,
 }
 
 func NewDispatcher() *Dispatcher {
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/profile.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/profile.go
new file mode 100644
index 0000000..0e98740
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/profile.go
@@ -0,0 +1,82 @@
+package nmble
+
+import (
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+)
+
+type Descriptor struct {
+	Uuid     BleUuid
+	Handle   uint16
+	AttFlags BleAttFlags
+}
+
+type Characteristic struct {
+	Uuid       BleUuid
+	DefHandle  uint16
+	ValHandle  uint16
+	Properties BleChrFlags
+	Dscs       []*Descriptor
+}
+
+type Service struct {
+	Uuid        BleUuid
+	StartHandle uint16
+	EndHandle   uint16
+	Chrs        []*Characteristic
+}
+
+type Profile struct {
+	svcs  []Service
+	chrs  map[BleChrId]*Characteristic
+	attrs map[uint16]*Characteristic
+}
+
+func (c *Characteristic) SubscribeType() BleChrFlags {
+	if c.Properties&BLE_GATT_F_NOTIFY != 0 {
+		return BLE_GATT_F_NOTIFY
+	} else {
+		return c.Properties & BLE_GATT_F_INDICATE
+	}
+}
+
+func NewProfile() Profile {
+	return Profile{
+		chrs:  map[BleChrId]*Characteristic{},
+		attrs: map[uint16]*Characteristic{},
+	}
+}
+
+func (p *Profile) Services() []Service {
+	return p.svcs
+}
+
+func (p *Profile) SetServices(svcs []Service) {
+	p.svcs = svcs
+	p.chrs = map[BleChrId]*Characteristic{}
+	p.attrs = map[uint16]*Characteristic{}
+
+	for _, s := range svcs {
+		for _, c := range s.Chrs {
+			p.chrs[BleChrId{s.Uuid, c.Uuid}] = c
+			p.attrs[uint16(c.ValHandle)] = c
+		}
+	}
+}
+
+func (p *Profile) FindChrByUuid(id BleChrId) *Characteristic {
+	return p.chrs[id]
+}
+
+func (p *Profile) FindChrByHandle(handle uint16) *Characteristic {
+	return p.attrs[handle]
+}
+
+func FindDscByUuid(chr *Characteristic, uuid BleUuid) *Descriptor {
+	for _, d := range chr.Dscs {
+		if CompareUuids(uuid, d.Uuid) == 0 {
+			return d
+		}
+	}
+
+	return nil
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_oic_sesn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_oic_sesn.go
index 0ab7fc0..8279065 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_oic_sesn.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_oic_sesn.go
@@ -152,37 +152,34 @@ func (sos *SerialOicSesn) TxNmpOnce(m *nmp.NmpMsg, opt sesn.TxOptions) (
 	}
 }
 
-func (sos *SerialOicSesn) GetResourceOnce(uri string, opt sesn.TxOptions) (
-	[]byte, error) {
+func (sos *SerialOicSesn) GetResourceOnce(resType sesn.ResourceType,
+	uri string, opt sesn.TxOptions) (coap.COAPCode, []byte, error) {
 
 	token := nmxutil.NextToken()
 
 	ol, err := sos.d.AddOicListener(token)
 	if err != nil {
-		return nil, err
+		return 0, nil, err
 	}
 	defer sos.d.RemoveOicListener(token)
 
-	req, err := oic.EncodeGet(uri, token)
+	req, err := oic.EncodeGet(false, uri, token)
 	if err != nil {
-		return nil, err
+		return 0, nil, err
 	}
 
 	if err := sos.sx.Tx(req); err != nil {
-		return nil, err
+		return 0, nil, err
 	}
 
 	for {
 		select {
 		case err := <-ol.ErrChan:
-			return nil, err
+			return 0, nil, err
 		case rsp := <-ol.RspChan:
-			if rsp.Code != coap.Content {
-				return nil, fmt.Errorf("UNEXPECTED OIC ACK: %#v", rsp)
-			}
-			return rsp.Payload, nil
+			return rsp.Code(), rsp.Payload(), nil
 		case <-ol.AfterTimeout(opt.Timeout):
-			return nil, nmxutil.NewRspTimeoutError("OIC timeout")
+			return 0, nil, nmxutil.NewRspTimeoutError("OIC timeout")
 		}
 	}
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_plain_sesn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_plain_sesn.go
index 9abd00c..5f219da 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_plain_sesn.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_plain_sesn.go
@@ -23,6 +23,8 @@ import (
 	"fmt"
 	"sync"
 
+	"github.com/runtimeco/go-coap"
+
 	"mynewt.apache.org/newtmgr/nmxact/nmp"
 	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
 	"mynewt.apache.org/newtmgr/nmxact/sesn"
@@ -155,8 +157,8 @@ func (sps *SerialPlainSesn) TxNmpOnce(m *nmp.NmpMsg, opt sesn.TxOptions) (
 	}
 }
 
-func (sps *SerialPlainSesn) GetResourceOnce(uri string, opt sesn.TxOptions) (
-	[]byte, error) {
+func (sps *SerialPlainSesn) GetResourceOnce(resType sesn.ResourceType,
+	uri string, opt sesn.TxOptions) (coap.COAPCode, []byte, error) {
 
-	return nil, fmt.Errorf("SerialPlainSesn.GetResourceOnce() unsupported")
+	return 0, nil, fmt.Errorf("SerialPlainSesn.GetResourceOnce() unsupported")
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_xport.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_xport.go
index 1c8cb98..9d6dca9 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_xport.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmserial/serial_xport.go
@@ -32,6 +32,7 @@ import (
 	"github.com/tarm/serial"
 
 	"mynewt.apache.org/newt/util"
+	"mynewt.apache.org/newtmgr/nmxact/adv"
 	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
 	"mynewt.apache.org/newtmgr/nmxact/scan"
 	"mynewt.apache.org/newtmgr/nmxact/sesn"
@@ -239,3 +240,7 @@ func (sx *SerialXport) Rx() ([]byte, error) {
 	}
 	return nil, err
 }
+
+func (sx *SerialXport) BuildAdvertiser() (adv.Advertiser, error) {
+	return nil, fmt.Errorf("SerialXport#BuildAdvertiser unsupported")
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmxutil/nmxutil.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmxutil/nmxutil.go
index dc6b462..d95c368 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmxutil/nmxutil.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmxutil/nmxutil.go
@@ -27,6 +27,7 @@ import (
 	"path"
 	"runtime"
 	"sync"
+	"sync/atomic"
 	"time"
 
 	log "github.com/Sirupsen/logrus"
@@ -84,6 +85,10 @@ func NextNmpSeq() uint8 {
 	return val
 }
 
+func SeqToToken(seq uint8) []byte {
+	return []byte{seq}
+}
+
 func NextToken() []byte {
 	seqMutex.Lock()
 	defer seqMutex.Unlock()
@@ -93,7 +98,7 @@ func NextToken() []byte {
 		oicSeqBeenRead = true
 	}
 
-	token := []byte{nextOicSeq}
+	token := SeqToToken(nextOicSeq)
 	nextOicSeq++
 
 	return token
@@ -111,6 +116,12 @@ func DecodeCborMap(cbor []byte) (map[string]interface{}, error) {
 	return m, nil
 }
 
+var nextId uint32
+
+func GetNextId() uint32 {
+	return atomic.AddUint32(&nextId, 1) - 1
+}
+
 func LogListener(parentLevel int, title string, extra string) {
 	_, file, line, _ := runtime.Caller(parentLevel)
 	file = path.Base(file)
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/dispatch.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/dispatch.go
index 33f0ac9..e8388ba 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/dispatch.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/dispatch.go
@@ -50,7 +50,7 @@ func NewToken(rawToken []byte) (Token, error) {
 }
 
 type Listener struct {
-	RspChan chan *coap.Message
+	RspChan chan coap.Message
 	ErrChan chan error
 	tmoChan chan time.Time
 	timer   *time.Timer
@@ -58,7 +58,7 @@ type Listener struct {
 
 func NewListener() *Listener {
 	return &Listener{
-		RspChan: make(chan *coap.Message, 1),
+		RspChan: make(chan coap.Message, 1),
 		ErrChan: make(chan error, 1),
 		tmoChan: make(chan time.Time, 1),
 	}
@@ -86,7 +86,7 @@ func (ol *Listener) Close() {
 // dispatcher writes to these listeners.
 type Dispatcher struct {
 	tokenListenerMap map[Token]*Listener
-	reassembler      *Reassembler
+	rxer             Receiver
 	logDepth         int
 	mtx              sync.Mutex
 }
@@ -94,13 +94,10 @@ type Dispatcher struct {
 func NewDispatcher(isTcp bool, logDepth int) *Dispatcher {
 	d := &Dispatcher{
 		tokenListenerMap: map[Token]*Listener{},
+		rxer:             NewReceiver(isTcp),
 		logDepth:         logDepth + 2,
 	}
 
-	if isTcp {
-		d.reassembler = NewReassembler()
-	}
-
 	return d
 }
 
@@ -146,7 +143,7 @@ func (d *Dispatcher) RemoveListener(token []byte) *Listener {
 	return ol
 }
 
-func (d *Dispatcher) dispatchRsp(ot Token, msg *coap.Message) bool {
+func (d *Dispatcher) dispatchRsp(ot Token, msg coap.Message) bool {
 	d.mtx.Lock()
 	defer d.mtx.Unlock()
 
@@ -163,32 +160,17 @@ func (d *Dispatcher) dispatchRsp(ot Token, msg *coap.Message) bool {
 
 // Returns true if the response was dispatched.
 func (d *Dispatcher) Dispatch(data []byte) bool {
-	var msg *coap.Message
-
-	if d.reassembler != nil {
-		// TCP.
-		tm := d.reassembler.RxFrag(data)
-		if tm == nil {
-			return false
-		}
-
-		msg = &tm.Message
-	} else {
-		// UDP.
-		m, err := coap.ParseMessage(data)
-		if err != nil {
-			log.Printf("CoAP parse failure: %s", err.Error())
-			return false
-		}
-		msg = &m
+	m := d.rxer.Rx(data)
+	if m == nil {
+		return false
 	}
 
-	ot, err := NewToken(msg.Token)
+	ot, err := NewToken(m.Token())
 	if err != nil {
 		return false
 	}
 
-	return d.dispatchRsp(ot, msg)
+	return d.dispatchRsp(ot, m)
 }
 
 func (d *Dispatcher) ErrorOne(token Token, err error) error {
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/frag.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/frag.go
index 6c76a95..53128e5 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/frag.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/frag.go
@@ -43,9 +43,10 @@ func (r *Reassembler) RxFrag(frag []byte) *coap.TcpMessage {
 		return nil
 	}
 
-	if tm != nil {
-		r.cur = nil
+	if tm == nil {
+		return nil
 	}
 
+	r.cur = nil
 	return tm
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/oic.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/oic.go
index 7cf925d..f5052ed 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/oic.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/oic.go
@@ -21,28 +21,64 @@ package oic
 
 import (
 	"fmt"
+	"sync"
 
 	"github.com/runtimeco/go-coap"
 )
 
-func EncodeGet(resUri string, token []byte) ([]byte, error) {
+var messageIdMtx sync.Mutex
+var nextMessageId uint16
+
+func NextMessageId() uint16 {
+	messageIdMtx.Lock()
+	defer messageIdMtx.Unlock()
+
+	id := nextMessageId
+	nextMessageId++
+	return id
+}
+
+func Encode(m coap.Message) ([]byte, error) {
+	b, err := m.MarshalBinary()
+	if err != nil {
+		return nil, fmt.Errorf("Failed to encode CoAP: %s\n", err.Error())
+	}
+
+	return b, nil
+}
+
+func CreateGet(isTcp bool, resUri string, token []byte) (coap.Message, error) {
 	if len(token) > 8 {
 		return nil,
 			fmt.Errorf("Invalid token; len=%d, must be < 8", len(token))
 	}
 
-	req := &coap.TcpMessage{
-		Message: coap.Message{
-			Type:  coap.Confirmable,
-			Code:  coap.GET,
-			Token: token,
-		},
+	p := coap.MessageParams{
+		Type:  coap.Confirmable,
+		Code:  coap.GET,
+		Token: token,
+	}
+
+	var m coap.Message
+	if isTcp {
+		m = coap.NewTcpMessage(p)
+	} else {
+		m = coap.NewDgramMessage(p)
 	}
-	req.SetPathString(resUri)
+	m.SetPathString(resUri)
+
+	return m, nil
+}
 
-	b, err := req.MarshalBinary()
+func EncodeGet(isTcp bool, resUri string, token []byte) ([]byte, error) {
+	m, err := CreateGet(isTcp, resUri, token)
 	if err != nil {
-		return nil, fmt.Errorf("Failed to encode CoAP: %s\n", err.Error())
+		return nil, err
+	}
+
+	b, err := Encode(m)
+	if err != nil {
+		return nil, err
 	}
 
 	return b, nil
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/receiver.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/receiver.go
new file mode 100644
index 0000000..48de0fd
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/receiver.go
@@ -0,0 +1,40 @@
+package oic
+
+import (
+	log "github.com/Sirupsen/logrus"
+	"github.com/runtimeco/go-coap"
+)
+
+type Receiver struct {
+	reassembler *Reassembler
+}
+
+func NewReceiver(isTcp bool) Receiver {
+	r := Receiver{}
+
+	if isTcp {
+		r.reassembler = NewReassembler()
+	}
+
+	return r
+}
+
+func (r *Receiver) Rx(data []byte) coap.Message {
+	if r.reassembler != nil {
+		// TCP.
+		tm := r.reassembler.RxFrag(data)
+		if tm == nil {
+			return nil
+		}
+		return tm
+	} else {
+		// UDP.
+		m, err := coap.ParseDgramMessage(data)
+		if err != nil {
+			log.Printf("CoAP parse failure: %s", err.Error())
+			return nil
+		}
+
+		return m
+	}
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/resmgr.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/resmgr.go
new file mode 100644
index 0000000..467204d
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/resmgr.go
@@ -0,0 +1,73 @@
+package oic
+
+import (
+	"fmt"
+
+	log "github.com/Sirupsen/logrus"
+	"github.com/runtimeco/go-coap"
+)
+
+type ResWriteFn func(uri string, data []byte) coap.COAPCode
+type ResReadFn func(uri string, data []byte) (coap.COAPCode, []byte)
+
+type Resource struct {
+	Name    string
+	WriteCb ResWriteFn
+	ReadCb  ResReadFn
+}
+
+type ResMgr struct {
+	nameResMap map[string]Resource
+}
+
+func NewResMgr() ResMgr {
+	return ResMgr{
+		nameResMap: map[string]Resource{},
+	}
+}
+
+func (rm *ResMgr) Add(r Resource) error {
+	if _, ok := rm.nameResMap[r.Name]; ok {
+		return fmt.Errorf("Registration of duplicate CoAP resource: %s",
+			r.Name)
+	}
+
+	rm.nameResMap[r.Name] = r
+	return nil
+}
+
+func (rm *ResMgr) Access(m coap.Message) (coap.COAPCode, []byte) {
+	paths := m.Path()
+	if len(paths) == 0 {
+		log.Debugf("Incoming CoAP message does not specify a URI path")
+		return coap.NotFound, nil
+	}
+	path := paths[0]
+
+	r, ok := rm.nameResMap[path]
+	if !ok {
+		log.Debugf("Incoming CoAP message specifies unknown resource: %s", path)
+		return coap.NotFound, nil
+	}
+
+	switch m.Code() {
+	case coap.GET:
+		if r.ReadCb == nil {
+			return coap.MethodNotAllowed, nil
+		} else {
+			return r.ReadCb(path, m.Payload())
+		}
+
+	case coap.PUT:
+		if r.WriteCb == nil {
+			return coap.MethodNotAllowed, nil
+		} else {
+			return r.WriteCb(path, m.Payload()), nil
+		}
+
+	default:
+		log.Debugf("Don't know how to handle CoAP message with code=%d (%s)",
+			m.Code(), m.Code().String())
+		return coap.MethodNotAllowed, nil
+	}
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/server.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/server.go
new file mode 100644
index 0000000..0e8ee69
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/oic/server.go
@@ -0,0 +1,64 @@
+package oic
+
+import (
+	"fmt"
+
+	"github.com/runtimeco/go-coap"
+)
+
+type Server struct {
+	rxer  Receiver
+	rm    ResMgr
+	isTcp bool
+}
+
+func NewServer(isTcp bool) Server {
+	s := Server{
+		rxer:  NewReceiver(isTcp),
+		rm:    NewResMgr(),
+		isTcp: isTcp,
+	}
+
+	return s
+}
+
+func (s *Server) AddResource(r Resource) error {
+	return s.rm.Add(r)
+}
+
+// @return                      Response to send back, if any.
+func (s *Server) Rx(data []byte) (coap.Message, error) {
+	m := s.rxer.Rx(data)
+	if m == nil {
+		return nil, nil
+	}
+
+	var typ coap.COAPType
+	switch m.Type() {
+	case coap.Confirmable:
+		typ = coap.Acknowledgement
+
+	case coap.NonConfirmable:
+		typ = coap.NonConfirmable
+
+	default:
+		return nil, fmt.Errorf("Don't know how to handle CoAP message with "+
+			"type=%d (%s)", m.Type(), m.Type().String())
+	}
+
+	code, payload := s.rm.Access(m)
+
+	p := coap.MessageParams{
+		Type:      typ,
+		Code:      code,
+		MessageID: NextMessageId(),
+		Token:     m.Token(),
+		Payload:   payload,
+	}
+
+	if !s.isTcp {
+		return coap.NewDgramMessage(p), nil
+	} else {
+		return coap.NewTcpMessage(p), nil
+	}
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/omp/omp.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/omp/omp.go
index 74c662b..b8e3b14 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/omp/omp.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/omp/omp.go
@@ -44,22 +44,22 @@ type OicMsg struct {
  * codec.  So we need to decode the whole response, and then re-encode the
  * newtmgr response part.
  */
-func DecodeOmp(tm *coap.Message) (nmp.NmpRsp, error) {
+func DecodeOmp(m coap.Message) (nmp.NmpRsp, error) {
 	// Ignore non-responses.
-	if tm.Code == coap.GET || tm.Code == coap.PUT {
+	if m.Code() == coap.GET || m.Code() == coap.PUT {
 		return nil, nil
 	}
 
-	if tm.Code != coap.Created && tm.Code != coap.Deleted &&
-		tm.Code != coap.Valid && tm.Code != coap.Changed &&
-		tm.Code != coap.Content {
+	if m.Code() != coap.Created && m.Code() != coap.Deleted &&
+		m.Code() != coap.Valid && m.Code() != coap.Changed &&
+		m.Code() != coap.Content {
 		return nil, fmt.Errorf(
-			"OMP response specifies unexpected code: %d (%s)", int(tm.Code),
-			tm.Code.String())
+			"OMP response specifies unexpected code: %d (%s)", int(m.Code()),
+			m.Code().String())
 	}
 
 	var om OicMsg
-	err := codec.NewDecoderBytes(tm.Payload, new(codec.CborHandle)).Decode(&om)
+	err := codec.NewDecoderBytes(m.Payload(), new(codec.CborHandle)).Decode(&om)
 	if err != nil {
 		return nil, fmt.Errorf("Invalid incoming cbor: %s", err.Error())
 	}
@@ -73,7 +73,7 @@ func DecodeOmp(tm *coap.Message) (nmp.NmpRsp, error) {
 		return nil, err
 	}
 
-	rsp, err := nmp.DecodeRspBody(hdr, tm.Payload)
+	rsp, err := nmp.DecodeRspBody(hdr, m.Payload())
 	if err != nil {
 		return nil, fmt.Errorf("Error decoding OMP response: %s", err.Error())
 	}
@@ -85,19 +85,19 @@ func DecodeOmp(tm *coap.Message) (nmp.NmpRsp, error) {
 }
 
 type encodeRecord struct {
-	m        coap.Message
+	tm       *coap.TcpMessage
 	hdrBytes []byte
 	fieldMap map[string]interface{}
 }
 
 func encodeOmpBase(nmr *nmp.NmpMsg) (encodeRecord, error) {
 	er := encodeRecord{
-		m: coap.Message{
+		tm: coap.NewTcpMessage(coap.MessageParams{
 			Type: coap.Confirmable,
 			Code: coap.PUT,
-		},
+		}),
 	}
-	er.m.SetPathString("/omgr")
+	er.tm.SetPathString("/omgr")
 
 	payload := []byte{}
 	enc := codec.NewEncoderBytes(&payload, new(codec.CborHandle))
@@ -117,7 +117,7 @@ func encodeOmpBase(nmr *nmp.NmpMsg) (encodeRecord, error) {
 	if err := enc.Encode(er.fieldMap); err != nil {
 		return er, err
 	}
-	er.m.Payload = payload
+	er.tm.SetPayload(payload)
 
 	return er, nil
 }
@@ -128,16 +128,14 @@ func EncodeOmpTcp(nmr *nmp.NmpMsg) ([]byte, error) {
 		return nil, err
 	}
 
-	tm := coap.TcpMessage{er.m}
-
-	data, err := tm.MarshalBinary()
+	data, err := er.tm.MarshalBinary()
 	if err != nil {
 		return nil, fmt.Errorf("Failed to encode: %s\n", err.Error())
 	}
 
 	log.Debugf("Serialized OMP TCP request:\n"+
 		"Hdr %+v:\n%s\nPayload:%s\nData:\n%s",
-		nmr.Hdr, hex.Dump(er.hdrBytes), hex.Dump(tm.Payload),
+		nmr.Hdr, hex.Dump(er.hdrBytes), hex.Dump(er.tm.Payload()),
 		hex.Dump(data))
 
 	return data, nil
@@ -149,14 +147,14 @@ func EncodeOmpDgram(nmr *nmp.NmpMsg) ([]byte, error) {
 		return nil, err
 	}
 
-	data, err := er.m.MarshalBinary()
+	data, err := er.tm.MarshalBinary()
 	if err != nil {
 		return nil, fmt.Errorf("Failed to encode: %s\n", err.Error())
 	}
 
 	log.Debugf("Serialized OMP datagram request:\n"+
 		"Hdr %+v:\n%s\nPayload:%s\nData:\n%s",
-		nmr.Hdr, hex.Dump(er.hdrBytes), hex.Dump(er.m.Payload),
+		nmr.Hdr, hex.Dump(er.hdrBytes), hex.Dump(er.tm.Payload()),
 		hex.Dump(data))
 
 	return data, nil
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/scan/scan.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/scan/scan.go
index aa56930..db1ade2 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/scan/scan.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/scan/scan.go
@@ -61,7 +61,6 @@ type Scanner interface {
 func BleOmpScanCfg(ScanCb ScanFn) Cfg {
 	sc := sesn.NewSesnCfg()
 	sc.MgmtProto = sesn.MGMT_PROTO_OMP
-	sc.Ble.IsCentral = true
 	sc.Ble.EncryptWhen = bledefs.BLE_ENCRYPT_PRIV_ONLY
 	sc.Ble.OwnAddrType = bledefs.BLE_ADDR_TYPE_RANDOM
 
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn.go
index 3a064b5..8db9438 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn.go
@@ -22,6 +22,8 @@ package sesn
 import (
 	"time"
 
+	"github.com/runtimeco/go-coap"
+
 	"mynewt.apache.org/newtmgr/nmxact/nmp"
 )
 
@@ -79,6 +81,8 @@ type Sesn interface {
 	// separate thread, as sesn receive operations are blocking.
 	AbortRx(nmpSeq uint8) error
 
+	// XXX AbortResource(seq uint8) error
+
 	////// Internal to nmxact:
 
 	EncodeNmpMsg(msg *nmp.NmpMsg) ([]byte, error)
@@ -90,6 +94,8 @@ type Sesn interface {
 	//     * other error
 	TxNmpOnce(m *nmp.NmpMsg, opt TxOptions) (nmp.NmpRsp, error)
 
-	GetResourceOnce(uri string, opt TxOptions) ([]byte, error)
+	GetResourceOnce(resType ResourceType, uri string, opt TxOptions) (
+		coap.COAPCode, []byte, error)
+
 	//SetResource(uri string, value []byte, opt TxOptions) error
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go
index da84b06..c3e84f4 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_cfg.go
@@ -20,6 +20,7 @@
 package sesn
 
 import (
+	"fmt"
 	"time"
 
 	"mynewt.apache.org/newtmgr/nmxact/bledefs"
@@ -32,6 +33,34 @@ const (
 	MGMT_PROTO_OMP
 )
 
+type ResourceType int
+
+const (
+	RES_TYPE_PUBLIC ResourceType = iota
+	RES_TYPE_UNAUTH
+	RES_TYPE_SECURE
+)
+
+var resTypeMap = map[ResourceType]string{
+	RES_TYPE_PUBLIC: "public",
+	RES_TYPE_UNAUTH: "unauth",
+	RES_TYPE_SECURE: "secure",
+}
+
+func (r ResourceType) String() string {
+	return resTypeMap[r]
+}
+
+func ParseResType(s string) (ResourceType, error) {
+	for r, n := range resTypeMap {
+		if s == n {
+			return r, nil
+		}
+	}
+
+	return ResourceType(0), fmt.Errorf("Unknown resource type: %s", s)
+}
+
 type OnCloseFn func(s Sesn, err error)
 
 type PeerSpec struct {
@@ -45,31 +74,14 @@ type SesnCfgBleCentral struct {
 	// XXX: Missing fields.
 }
 
-type SesnCfgBlePeriph struct {
-	Duration      time.Duration
-	ConnMode      bledefs.BleAdvConnMode
-	DiscMode      bledefs.BleAdvDiscMode
-	ItvlMin       uint16
-	ItvlMax       uint16
-	ChannelMap    uint8
-	FilterPolicy  bledefs.BleAdvFilterPolicy
-	HighDutyCycle bool
-	AdvFields     bledefs.BleAdvFields
-	RspFields     bledefs.BleAdvFields
-}
-
 type SesnCfgBle struct {
 	// General configuration.
-	IsCentral    bool
 	OwnAddrType  bledefs.BleAddrType
 	EncryptWhen  bledefs.BleEncryptWhen
 	CloseTimeout time.Duration
 
 	// Central configuration.
 	Central SesnCfgBleCentral
-
-	// Peripheral configuration.
-	Periph SesnCfgBlePeriph
 }
 
 type SesnCfg struct {
@@ -88,7 +100,6 @@ func NewSesnCfg() SesnCfg {
 		// future, there will need to be some global default, or something that
 		// gets read from blehostd.
 		Ble: SesnCfgBle{
-			IsCentral:    true,
 			OwnAddrType:  bledefs.BLE_ADDR_TYPE_RANDOM,
 			CloseTimeout: 30 * time.Second,
 
@@ -96,7 +107,6 @@ func NewSesnCfg() SesnCfg {
 				ConnTries:   3,
 				ConnTimeout: 10 * time.Second,
 			},
-			Periph: SesnCfgBlePeriph{},
 		},
 	}
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_util.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_util.go
index 9bcbd02..6399ee9 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_util.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/sesn/sesn_util.go
@@ -20,6 +20,8 @@
 package sesn
 
 import (
+	"github.com/runtimeco/go-coap"
+
 	"mynewt.apache.org/newtmgr/nmxact/nmp"
 	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
 )
@@ -38,16 +40,18 @@ func TxNmp(s Sesn, m *nmp.NmpMsg, o TxOptions) (nmp.NmpRsp, error) {
 	}
 }
 
-func GetResource(s Sesn, uri string, o TxOptions) ([]byte, error) {
+func GetResource(s Sesn, resType ResourceType, uri string, o TxOptions) (
+	coap.COAPCode, []byte, error) {
+
 	retries := o.Tries - 1
 	for i := 0; ; i++ {
-		r, err := s.GetResourceOnce(uri, o)
+		code, r, err := s.GetResourceOnce(resType, uri, o)
 		if err == nil {
-			return r, nil
+			return code, r, nil
 		}
 
 		if !nmxutil.IsRspTimeout(err) || i >= retries {
-			return nil, err
+			return code, nil, err
 		}
 	}
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_oic_sesn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_oic_sesn.go
index c464255..9690221 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_oic_sesn.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_oic_sesn.go
@@ -145,37 +145,34 @@ func (uos *UdpOicSesn) AbortRx(seq uint8) error {
 	return nil
 }
 
-func (uos *UdpOicSesn) GetResourceOnce(uri string, opt sesn.TxOptions) (
-	[]byte, error) {
+func (uos *UdpOicSesn) GetResourceOnce(resType sesn.ResourceType, uri string,
+	opt sesn.TxOptions) (coap.COAPCode, []byte, error) {
 
 	token := nmxutil.NextToken()
 
 	ol, err := uos.d.AddOicListener(token)
 	if err != nil {
-		return nil, err
+		return 0, nil, err
 	}
 	defer uos.d.RemoveOicListener(token)
 
-	req, err := oic.EncodeGet(uri, token)
+	req, err := oic.EncodeGet(false, uri, token)
 	if err != nil {
-		return nil, err
+		return 0, nil, err
 	}
 
 	if _, err := uos.conn.WriteToUDP(req, uos.addr); err != nil {
-		return nil, err
+		return 0, nil, err
 	}
 
 	for {
 		select {
 		case err := <-ol.ErrChan:
-			return nil, err
+			return 0, nil, err
 		case rsp := <-ol.RspChan:
-			if rsp.Code != coap.Content {
-				return nil, fmt.Errorf("UNEXPECTED OIC ACK: %#v", rsp)
-			}
-			return rsp.Payload, nil
+			return rsp.Code(), rsp.Payload(), nil
 		case <-ol.AfterTimeout(opt.Timeout):
-			return nil, nmxutil.NewRspTimeoutError("OIC timeout")
+			return 0, nil, nmxutil.NewRspTimeoutError("OIC timeout")
 		}
 	}
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_plain_sesn.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_plain_sesn.go
index a8a1b4f..4f79310 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_plain_sesn.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_plain_sesn.go
@@ -23,6 +23,8 @@ import (
 	"fmt"
 	"net"
 
+	"github.com/runtimeco/go-coap"
+
 	"mynewt.apache.org/newtmgr/nmxact/nmp"
 	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
 	"mynewt.apache.org/newtmgr/nmxact/omp"
@@ -132,8 +134,8 @@ func (ups *UdpPlainSesn) AbortRx(seq uint8) error {
 	return ups.d.ErrorOne(seq, fmt.Errorf("Rx aborted"))
 }
 
-func (ups *UdpPlainSesn) GetResourceOnce(uri string, opt sesn.TxOptions) (
-	[]byte, error) {
+func (ups *UdpPlainSesn) GetResourceOnce(resType sesn.ResourceType,
+	uri string, opt sesn.TxOptions) (coap.COAPCode, []byte, error) {
 
-	return nil, fmt.Errorf("UdpPlainSesn.GetResourceOnce() unsupported")
+	return 0, nil, fmt.Errorf("UdpPlainSesn.GetResourceOnce() unsupported")
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_xport.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_xport.go
index 2147dcc..954ab9f 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_xport.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/udp/udp_xport.go
@@ -22,6 +22,7 @@ package udp
 import (
 	"fmt"
 
+	"mynewt.apache.org/newtmgr/nmxact/adv"
 	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
 	"mynewt.apache.org/newtmgr/nmxact/scan"
 	"mynewt.apache.org/newtmgr/nmxact/sesn"
@@ -71,3 +72,7 @@ func (ux *UdpXport) Stop() error {
 func (ux *UdpXport) Tx(bytes []byte) error {
 	return fmt.Errorf("unsupported")
 }
+
+func (ux *UdpXport) BuildAdvertiser() (adv.Advertiser, error) {
+	return nil, fmt.Errorf("UdpXport#BuildAdvertiser unsupported")
+}
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/omp/frag.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/xact/getres.go
similarity index 57%
rename from newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/omp/frag.go
rename to newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/xact/getres.go
index 0ad8e91..e56067d 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/omp/frag.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/xact/getres.go
@@ -17,35 +17,51 @@
  * under the License.
  */
 
-package omp
+package xact
 
 import (
-	log "github.com/Sirupsen/logrus"
 	"github.com/runtimeco/go-coap"
+
+	"mynewt.apache.org/newtmgr/nmxact/sesn"
 )
 
-type Reassembler struct {
-	cur []byte
+type GetResCmd struct {
+	CmdBase
+	Uri string
+	Typ sesn.ResourceType
 }
 
-func NewReassembler() *Reassembler {
-	return &Reassembler{}
+func NewGetResCmd() *GetResCmd {
+	return &GetResCmd{
+		CmdBase: NewCmdBase(),
+	}
 }
 
-func (r *Reassembler) RxFrag(frag []byte) *coap.TcpMessage {
-	r.cur = append(r.cur, frag...)
+type GetResResult struct {
+	Code  coap.COAPCode
+	Value []byte
+}
 
-	var tm *coap.TcpMessage
-	var err error
-	tm, r.cur, err = coap.PullTcp(r.cur)
-	if err != nil {
-		log.Debugf("received invalid CoAP-TCP packet: %s", err.Error())
-		return nil
+func newGetResResult() *GetResResult {
+	return &GetResResult{}
+}
+
+func (r *GetResResult) Status() int {
+	if r.Code == coap.Content {
+		return 0
+	} else {
+		return int(r.Code)
 	}
+}
 
-	if tm != nil {
-		r.cur = nil
+func (c *GetResCmd) Run(s sesn.Sesn) (Result, error) {
+	status, val, err := sesn.GetResource(s, c.Typ, c.Uri, c.TxOptions())
+	if err != nil {
+		return nil, err
 	}
 
-	return tm
+	res := newGetResResult()
+	res.Code = status
+	res.Value = val
+	return res, nil
 }
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/xport/xport.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/xport/xport.go
index 865bfb2..0cca2a4 100644
--- a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/xport/xport.go
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/xport/xport.go
@@ -20,6 +20,7 @@
 package xport
 
 import (
+	"mynewt.apache.org/newtmgr/nmxact/adv"
 	"mynewt.apache.org/newtmgr/nmxact/scan"
 	"mynewt.apache.org/newtmgr/nmxact/sesn"
 )
@@ -32,6 +33,7 @@ type Xport interface {
 
 	BuildSesn(cfg sesn.SesnCfg) (sesn.Sesn, error)
 	BuildScanner() (scan.Scanner, error)
+	BuildAdvertiser() (adv.Advertiser, error)
 
 	Tx(data []byte) error
 }

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