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/03/28 22:42:01 UTC

[64/67] [abbrv] incubator-mynewt-newtmgr git commit: newtmgr - use newtmgr repo, not newt repo.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..a8a46d6
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_plain_sesn.go
@@ -0,0 +1,186 @@
+package nmble
+
+import (
+	"fmt"
+	"sync"
+	"time"
+
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+	"mynewt.apache.org/newtmgr/nmxact/nmp"
+	"mynewt.apache.org/newtmgr/nmxact/sesn"
+	"mynewt.apache.org/newt/util"
+)
+
+type BlePlainSesn struct {
+	bf           *BleFsm
+	nls          map[*nmp.NmpListener]struct{}
+	nd           *nmp.NmpDispatcher
+	closeTimeout time.Duration
+	onCloseCb    sesn.BleOnCloseFn
+
+	closeChan chan error
+	mx        sync.Mutex
+}
+
+func NewBlePlainSesn(bx *BleXport, cfg sesn.SesnCfg) *BlePlainSesn {
+	bps := &BlePlainSesn{
+		nls:          map[*nmp.NmpListener]struct{}{},
+		nd:           nmp.NewNmpDispatcher(),
+		closeTimeout: cfg.Ble.CloseTimeout,
+		onCloseCb:    cfg.Ble.OnCloseCb,
+	}
+
+	svcUuid, err := ParseUuid(NmpPlainSvcUuid)
+	if err != nil {
+		panic(err.Error())
+	}
+
+	chrUuid, err := ParseUuid(NmpPlainChrUuid)
+	if err != nil {
+		panic(err.Error())
+	}
+
+	bps.bf = NewBleFsm(BleFsmParams{
+		Bx:           bx,
+		OwnAddrType:  cfg.Ble.OwnAddrType,
+		PeerSpec:     cfg.Ble.PeerSpec,
+		SvcUuid:      svcUuid,
+		ReqChrUuid:   chrUuid,
+		RspChrUuid:   chrUuid,
+		RxNmpCb:      func(d []byte) { bps.onRxNmp(d) },
+		DisconnectCb: func(p BleDev, e error) { bps.onDisconnect(p, e) },
+	})
+
+	return bps
+}
+
+func (bps *BlePlainSesn) addNmpListener(seq uint8) (*nmp.NmpListener, error) {
+	nl := nmp.NewNmpListener()
+	bps.nls[nl] = struct{}{}
+
+	if err := bps.nd.AddListener(seq, nl); err != nil {
+		delete(bps.nls, nl)
+		return nil, err
+	}
+
+	return nl, nil
+}
+
+func (bps *BlePlainSesn) removeNmpListener(seq uint8) {
+	listener := bps.nd.RemoveListener(seq)
+	if listener != nil {
+		delete(bps.nls, listener)
+	}
+}
+
+// Returns true if a new channel was assigned.
+func (bps *BlePlainSesn) setCloseChan() bool {
+	bps.mx.Lock()
+	defer bps.mx.Unlock()
+
+	if bps.closeChan != nil {
+		return false
+	}
+
+	bps.closeChan = make(chan error, 1)
+	return true
+}
+
+func (bps *BlePlainSesn) clearCloseChan() {
+	bps.mx.Lock()
+	defer bps.mx.Unlock()
+
+	bps.closeChan = nil
+}
+
+func (bps *BlePlainSesn) AbortRx(seq uint8) error {
+	return bps.nd.FakeRxError(seq, fmt.Errorf("Rx aborted"))
+}
+
+func (bps *BlePlainSesn) Open() error {
+	return bps.bf.Start()
+}
+
+func (bps *BlePlainSesn) Close() error {
+	if !bps.setCloseChan() {
+		return bps.bf.closedError(
+			"Attempt to close an unopened BLE session")
+	}
+	defer bps.clearCloseChan()
+
+	done, err := bps.bf.Stop()
+	if err != nil {
+		return err
+	}
+
+	if done {
+		// Close complete.
+		return nil
+	}
+
+	// Block until close completes or timeout.
+	select {
+	case <-bps.closeChan:
+	case <-time.After(bps.closeTimeout):
+	}
+
+	return nil
+}
+
+func (bps *BlePlainSesn) IsOpen() bool {
+	return bps.bf.IsOpen()
+}
+
+func (bps *BlePlainSesn) onRxNmp(data []byte) {
+	bps.nd.Dispatch(data)
+}
+
+func (bps *BlePlainSesn) onDisconnect(peer BleDev, err error) {
+	for nl, _ := range bps.nls {
+		nl.ErrChan <- err
+	}
+
+	// If the session is being closed, unblock the close() call.
+	if bps.closeChan != nil {
+		bps.closeChan <- err
+	}
+	if bps.onCloseCb != nil {
+		bps.onCloseCb(bps, peer, err)
+	}
+}
+
+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.addNmpListener(msg.Hdr.Seq)
+	if err != nil {
+		return nil, err
+	}
+	defer bps.removeNmpListener(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)
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_proto.go
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..fe9112d
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_proto.go
@@ -0,0 +1,829 @@
+package nmble
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"strconv"
+	"strings"
+
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+)
+
+type MsgOp int
+type MsgType int
+
+type BleBytes struct {
+	Bytes []byte
+}
+
+type BleUuid struct {
+	Bytes [16]byte
+}
+
+const ERR_CODE_ATT_BASE = 0x100
+const ERR_CODE_HCI_BASE = 0x200
+const ERR_CODE_L2C_BASE = 0x300
+const ERR_CODE_SM_US_BASE = 0x400
+const ERR_CODE_SM_PEER_BASE = 0x500
+
+const (
+	ERR_CODE_EAGAIN       int = 1
+	ERR_CODE_EALREADY         = 2
+	ERR_CODE_EINVAL           = 3
+	ERR_CODE_EMSGSIZE         = 4
+	ERR_CODE_ENOENT           = 5
+	ERR_CODE_ENOMEM           = 6
+	ERR_CODE_ENOTCONN         = 7
+	ERR_CODE_ENOTSUP          = 8
+	ERR_CODE_EAPP             = 9
+	ERR_CODE_EBADDATA         = 10
+	ERR_CODE_EOS              = 11
+	ERR_CODE_ECONTROLLER      = 12
+	ERR_CODE_ETIMEOUT         = 13
+	ERR_CODE_EDONE            = 14
+	ERR_CODE_EBUSY            = 15
+	ERR_CODE_EREJECT          = 16
+	ERR_CODE_EUNKNOWN         = 17
+	ERR_CODE_EROLE            = 18
+	ERR_CODE_ETIMEOUT_HCI     = 19
+	ERR_CODE_ENOMEM_EVT       = 20
+	ERR_CODE_ENOADDR          = 21
+	ERR_CODE_ENOTSYNCED       = 22
+)
+
+var ErrCodeStringMap = map[int]string{
+	ERR_CODE_EAGAIN:       "eagain",
+	ERR_CODE_EALREADY:     "ealready",
+	ERR_CODE_EINVAL:       "einval",
+	ERR_CODE_EMSGSIZE:     "emsgsize",
+	ERR_CODE_ENOENT:       "enoent",
+	ERR_CODE_ENOMEM:       "enomem",
+	ERR_CODE_ENOTCONN:     "enotconn",
+	ERR_CODE_ENOTSUP:      "enotsup",
+	ERR_CODE_EAPP:         "eapp",
+	ERR_CODE_EBADDATA:     "ebaddata",
+	ERR_CODE_EOS:          "eos",
+	ERR_CODE_ECONTROLLER:  "econtroller",
+	ERR_CODE_ETIMEOUT:     "etimeout",
+	ERR_CODE_EDONE:        "edone",
+	ERR_CODE_EBUSY:        "ebusy",
+	ERR_CODE_EREJECT:      "ereject",
+	ERR_CODE_EUNKNOWN:     "eunknown",
+	ERR_CODE_EROLE:        "erole",
+	ERR_CODE_ETIMEOUT_HCI: "etimeout_hci",
+	ERR_CODE_ENOMEM_EVT:   "enomem_evt",
+	ERR_CODE_ENOADDR:      "enoaddr",
+	ERR_CODE_ENOTSYNCED:   "enotsynced",
+}
+
+const (
+	ERR_CODE_HCI_UNKNOWN_HCI_CMD     int = 1
+	ERR_CODE_HCI_UNK_CONN_ID             = 2
+	ERR_CODE_HCI_HW_FAIL                 = 3
+	ERR_CODE_HCI_PAGE_TMO                = 4
+	ERR_CODE_HCI_AUTH_FAIL               = 5
+	ERR_CODE_HCI_PINKEY_MISSING          = 6
+	ERR_CODE_HCI_MEM_CAPACITY            = 7
+	ERR_CODE_HCI_CONN_SPVN_TMO           = 8
+	ERR_CODE_HCI_CONN_LIMIT              = 9
+	ERR_CODE_HCI_SYNCH_CONN_LIMIT        = 10
+	ERR_CODE_HCI_ACL_CONN_EXISTS         = 11
+	ERR_CODE_HCI_CMD_DISALLOWED          = 12
+	ERR_CODE_HCI_CONN_REJ_RESOURCES      = 13
+	ERR_CODE_HCI_CONN_REJ_SECURITY       = 14
+	ERR_CODE_HCI_CONN_REJ_BD_ADDR        = 15
+	ERR_CODE_HCI_CONN_ACCEPT_TMO         = 16
+	ERR_CODE_HCI_UNSUPPORTED             = 17
+	ERR_CODE_HCI_INV_HCI_CMD_PARMS       = 18
+	ERR_CODE_HCI_REM_USER_CONN_TERM      = 19
+	ERR_CODE_HCI_RD_CONN_TERM_RESRCS     = 20
+	ERR_CODE_HCI_RD_CONN_TERM_PWROFF     = 21
+	ERR_CODE_HCI_CONN_TERM_LOCAL         = 22
+	ERR_CODE_HCI_REPEATED_ATTEMPTS       = 23
+	ERR_CODE_HCI_NO_PAIRING              = 24
+	ERR_CODE_HCI_UNK_LMP                 = 25
+	ERR_CODE_HCI_UNSUPP_REM_FEATURE      = 26
+	ERR_CODE_HCI_SCO_OFFSET              = 27
+	ERR_CODE_HCI_SCO_ITVL                = 28
+	ERR_CODE_HCI_SCO_AIR_MODE            = 29
+	ERR_CODE_HCI_INV_LMP_LL_PARM         = 30
+	ERR_CODE_HCI_UNSPECIFIED             = 31
+	ERR_CODE_HCI_UNSUPP_LMP_LL_PARM      = 32
+	ERR_CODE_HCI_NO_ROLE_CHANGE          = 33
+	ERR_CODE_HCI_LMP_LL_RSP_TMO          = 34
+	ERR_CODE_HCI_LMP_COLLISION           = 35
+	ERR_CODE_HCI_LMP_PDU                 = 36
+	ERR_CODE_HCI_ENCRYPTION_MODE         = 37
+	ERR_CODE_HCI_LINK_KEY_CHANGE         = 38
+	ERR_CODE_HCI_UNSUPP_QOS              = 39
+	ERR_CODE_HCI_INSTANT_PASSED          = 40
+	ERR_CODE_HCI_UNIT_KEY_PAIRING        = 41
+	ERR_CODE_HCI_DIFF_TRANS_COLL         = 42
+	ERR_CODE_HCI_QOS_PARM                = 44
+	ERR_CODE_HCI_QOS_REJECTED            = 45
+	ERR_CODE_HCI_CHAN_CLASS              = 46
+	ERR_CODE_HCI_INSUFFICIENT_SEC        = 47
+	ERR_CODE_HCI_PARM_OUT_OF_RANGE       = 48
+	ERR_CODE_HCI_PENDING_ROLE_SW         = 50
+	ERR_CODE_HCI_RESERVED_SLOT           = 52
+	ERR_CODE_HCI_ROLE_SW_FAIL            = 53
+	ERR_CODE_HCI_INQ_RSP_TOO_BIG         = 54
+	ERR_CODE_HCI_SEC_SIMPLE_PAIR         = 55
+	ERR_CODE_HCI_HOST_BUSY_PAIR          = 56
+	ERR_CODE_HCI_CONN_REJ_CHANNEL        = 57
+	ERR_CODE_HCI_CTLR_BUSY               = 58
+	ERR_CODE_HCI_CONN_PARMS              = 59
+	ERR_CODE_HCI_DIR_ADV_TMO             = 60
+	ERR_CODE_HCI_CONN_TERM_MIC           = 61
+	ERR_CODE_HCI_CONN_ESTABLISHMENT      = 62
+	ERR_CODE_HCI_MAC_CONN_FAIL           = 63
+	ERR_CODE_HCI_COARSE_CLK_ADJ          = 64
+)
+
+var HciErrCodeStringMap = map[int]string{
+	ERR_CODE_HCI_UNKNOWN_HCI_CMD:     "unknown hci cmd",
+	ERR_CODE_HCI_UNK_CONN_ID:         "unknown connection id",
+	ERR_CODE_HCI_HW_FAIL:             "hw fail",
+	ERR_CODE_HCI_PAGE_TMO:            "page tmo",
+	ERR_CODE_HCI_AUTH_FAIL:           "auth fail",
+	ERR_CODE_HCI_PINKEY_MISSING:      "pinkey missing",
+	ERR_CODE_HCI_MEM_CAPACITY:        "mem capacity",
+	ERR_CODE_HCI_CONN_SPVN_TMO:       "connection supervision timeout",
+	ERR_CODE_HCI_CONN_LIMIT:          "conn limit",
+	ERR_CODE_HCI_SYNCH_CONN_LIMIT:    "synch conn limit",
+	ERR_CODE_HCI_ACL_CONN_EXISTS:     "acl conn exists",
+	ERR_CODE_HCI_CMD_DISALLOWED:      "cmd disallowed",
+	ERR_CODE_HCI_CONN_REJ_RESOURCES:  "conn rej resources",
+	ERR_CODE_HCI_CONN_REJ_SECURITY:   "conn rej security",
+	ERR_CODE_HCI_CONN_REJ_BD_ADDR:    "conn rej bd addr",
+	ERR_CODE_HCI_CONN_ACCEPT_TMO:     "conn accept tmo",
+	ERR_CODE_HCI_UNSUPPORTED:         "unsupported",
+	ERR_CODE_HCI_INV_HCI_CMD_PARMS:   "inv hci cmd parms",
+	ERR_CODE_HCI_REM_USER_CONN_TERM:  "rem user conn term",
+	ERR_CODE_HCI_RD_CONN_TERM_RESRCS: "rd conn term resrcs",
+	ERR_CODE_HCI_RD_CONN_TERM_PWROFF: "rd conn term pwroff",
+	ERR_CODE_HCI_CONN_TERM_LOCAL:     "conn term local",
+	ERR_CODE_HCI_REPEATED_ATTEMPTS:   "repeated attempts",
+	ERR_CODE_HCI_NO_PAIRING:          "no pairing",
+	ERR_CODE_HCI_UNK_LMP:             "unk lmp",
+	ERR_CODE_HCI_UNSUPP_REM_FEATURE:  "unsupp rem feature",
+	ERR_CODE_HCI_SCO_OFFSET:          "sco offset",
+	ERR_CODE_HCI_SCO_ITVL:            "sco itvl",
+	ERR_CODE_HCI_SCO_AIR_MODE:        "sco air mode",
+	ERR_CODE_HCI_INV_LMP_LL_PARM:     "inv lmp ll parm",
+	ERR_CODE_HCI_UNSPECIFIED:         "unspecified",
+	ERR_CODE_HCI_UNSUPP_LMP_LL_PARM:  "unsupp lmp ll parm",
+	ERR_CODE_HCI_NO_ROLE_CHANGE:      "no role change",
+	ERR_CODE_HCI_LMP_LL_RSP_TMO:      "lmp ll rsp tmo",
+	ERR_CODE_HCI_LMP_COLLISION:       "lmp collision",
+	ERR_CODE_HCI_LMP_PDU:             "lmp pdu",
+	ERR_CODE_HCI_ENCRYPTION_MODE:     "encryption mode",
+	ERR_CODE_HCI_LINK_KEY_CHANGE:     "link key change",
+	ERR_CODE_HCI_UNSUPP_QOS:          "unsupp qos",
+	ERR_CODE_HCI_INSTANT_PASSED:      "instant passed",
+	ERR_CODE_HCI_UNIT_KEY_PAIRING:    "unit key pairing",
+	ERR_CODE_HCI_DIFF_TRANS_COLL:     "diff trans coll",
+	ERR_CODE_HCI_QOS_PARM:            "qos parm",
+	ERR_CODE_HCI_QOS_REJECTED:        "qos rejected",
+	ERR_CODE_HCI_CHAN_CLASS:          "chan class",
+	ERR_CODE_HCI_INSUFFICIENT_SEC:    "insufficient sec",
+	ERR_CODE_HCI_PARM_OUT_OF_RANGE:   "parm out of range",
+	ERR_CODE_HCI_PENDING_ROLE_SW:     "pending role sw",
+	ERR_CODE_HCI_RESERVED_SLOT:       "reserved slot",
+	ERR_CODE_HCI_ROLE_SW_FAIL:        "role sw fail",
+	ERR_CODE_HCI_INQ_RSP_TOO_BIG:     "inq rsp too big",
+	ERR_CODE_HCI_SEC_SIMPLE_PAIR:     "sec simple pair",
+	ERR_CODE_HCI_HOST_BUSY_PAIR:      "host busy pair",
+	ERR_CODE_HCI_CONN_REJ_CHANNEL:    "conn rej channel",
+	ERR_CODE_HCI_CTLR_BUSY:           "ctlr busy",
+	ERR_CODE_HCI_CONN_PARMS:          "conn parms",
+	ERR_CODE_HCI_DIR_ADV_TMO:         "dir adv tmo",
+	ERR_CODE_HCI_CONN_TERM_MIC:       "conn term mic",
+	ERR_CODE_HCI_CONN_ESTABLISHMENT:  "conn establishment",
+	ERR_CODE_HCI_MAC_CONN_FAIL:       "mac conn fail",
+	ERR_CODE_HCI_COARSE_CLK_ADJ:      "coarse clk adj",
+}
+
+const (
+	MSG_OP_REQ MsgOp = 0
+	MSG_OP_RSP       = 1
+	MSG_OP_EVT       = 2
+)
+
+const (
+	MSG_TYPE_ERR           MsgType = 1
+	MSG_TYPE_SYNC                  = 2
+	MSG_TYPE_CONNECT               = 3
+	MSG_TYPE_TERMINATE             = 4
+	MSG_TYPE_DISC_ALL_SVCS         = 5
+	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_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
+)
+
+var MsgOpStringMap = map[MsgOp]string{
+	MSG_OP_REQ: "request",
+	MSG_OP_RSP: "response",
+	MSG_OP_EVT: "event",
+}
+
+var MsgTypeStringMap = map[MsgType]string{
+	MSG_TYPE_ERR:           "error",
+	MSG_TYPE_SYNC:          "sync",
+	MSG_TYPE_CONNECT:       "connect",
+	MSG_TYPE_TERMINATE:     "terminate",
+	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_WRITE_CMD:     "write_cmd",
+	MSG_TYPE_EXCHANGE_MTU:  "exchange_mtu",
+	MSG_TYPE_CONN_CANCEL:   "conn_cancel",
+	MSG_TYPE_SCAN:          "scan",
+	MSG_TYPE_SCAN_CANCEL:   "scan_cancel",
+
+	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_NOTIFY_RX_EVT:  "notify_rx_evt",
+	MSG_TYPE_MTU_CHANGE_EVT: "mtu_change_evt",
+	MSG_TYPE_SCAN_EVT:       "scan_evt",
+}
+
+type BleHdr struct {
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+}
+
+type BleMsg interface{}
+
+type BleSvc struct {
+	StartHandle int     `json:"start_handle"`
+	EndHandle   int     `json:"end_handle"`
+	Uuid        BleUuid `json:"uuid"`
+}
+
+type BleChr struct {
+	DefHandle  int     `json:"def_handle"`
+	ValHandle  int     `json:"val_handle"`
+	Properties int     `json:"properties"`
+	Uuid       BleUuid `json:"uuid"`
+}
+
+type BleSyncReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+}
+
+type BleConnectReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	OwnAddrType  BleAddrType `json:"own_addr_type"`
+	PeerAddrType BleAddrType `json:"peer_addr_type"`
+	PeerAddr     BleAddr     `json:"peer_addr"`
+
+	// Optional
+	DurationMs         int `json:"duration_ms"`
+	ScanItvl           int `json:"scan_itvl"`
+	ScanWindow         int `json:"scan_window"`
+	ItvlMin            int `json:"itvl_min"`
+	ItvlMax            int `json:"itvl_max"`
+	Latency            int `json:"latency"`
+	SupervisionTimeout int `json:"supervision_timeout"`
+	MinCeLen           int `json:"min_ce_len"`
+	MaxCeLen           int `json:"max_ce_len"`
+}
+
+type BleConnectRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleConnectEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status          int         `json:"status"`
+	ConnHandle      int         `json:"conn_handle"`
+	OwnIdAddrType   BleAddrType `json:"own_id_addr_type"`
+	OwnIdAddr       BleAddr     `json:"own_id_addr"`
+	OwnOtaAddrType  BleAddrType `json:"own_ota_addr_type"`
+	OwnOtaAddr      BleAddr     `json:"own_ota_addr"`
+	PeerIdAddrType  BleAddrType `json:"peer_id_addr_type"`
+	PeerIdAddr      BleAddr     `json:"peer_id_addr"`
+	PeerOtaAddrType BleAddrType `json:"peer_ota_addr_type"`
+	PeerOtaAddr     BleAddr     `json:"peer_ota_addr"`
+}
+
+type BleTerminateReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	ConnHandle int `json:"conn_handle"`
+	HciReason  int `json:"hci_reason"`
+}
+
+type BleTerminateRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleConnCancelReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+}
+
+type BleConnCancelRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleDisconnectEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Reason     int `json:"reason"`
+	ConnHandle int `json:"conn_handle"`
+}
+
+type BleDiscSvcUuidReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	ConnHandle int     `json:"conn_handle"`
+	Uuid       BleUuid `json:"svc_uuid"`
+}
+
+type BleDiscSvcUuidRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleDiscSvcEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int    `json:"status"`
+	Svc    BleSvc `json:"service"`
+}
+
+type BleDiscChrUuidReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	ConnHandle  int     `json:"conn_handle"`
+	StartHandle int     `json:"start_handle"`
+	EndHandle   int     `json:"end_handle"`
+	Uuid        BleUuid `json:"chr_uuid"`
+}
+
+type BleDiscAllChrsReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	ConnHandle  int `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  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleErrRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int    `json:"status"`
+	Msg    string `json:"msg"`
+}
+
+type BleSyncRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Synced bool `json:"synced"`
+}
+
+type BleDiscChrUuidRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleDiscChrEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int    `json:"status"`
+	Chr    BleChr `json:"characteristic"`
+}
+
+type BleWriteCmdReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	ConnHandle int      `json:"conn_handle"`
+	AttrHandle int      `json:"attr_handle"`
+	Data       BleBytes `json:"data"`
+}
+
+type BleWriteCmdRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleSyncEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Synced bool `json:"synced"`
+}
+
+type BleNotifyRxEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	ConnHandle int      `json:"conn_handle"`
+	AttrHandle int      `json:"attr_handle"`
+	Indication bool     `json:"indication"`
+	Data       BleBytes `json:"data"`
+}
+
+type BleExchangeMtuReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	ConnHandle int `json:"conn_handle"`
+}
+
+type BleExchangeMtuRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleMtuChangeEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status     int `json:"status"`
+	ConnHandle int `json:"conn_handle"`
+	Mtu        int `json:"mtu"`
+}
+
+type BleScanReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	OwnAddrType      BleAddrType         `json:"own_addr_type"`
+	DurationMs       int                 `json:"duration_ms"`
+	Itvl             int                 `json:"itvl"`
+	Window           int                 `json:"window"`
+	FilterPolicy     BleScanFilterPolicy `json:"filter_policy"`
+	Limited          bool                `json:"limited"`
+	Passive          bool                `json:"passive"`
+	FilterDuplicates bool                `json:"filter_duplicates"`
+}
+
+type BleScanRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+type BleScanEvt struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	EventType BleAdvEventType `json:"event_type"`
+	AddrType  BleAddrType     `json:"addr_type"`
+	Addr      BleAddr         `json:"addr"`
+	Rssi      int8            `json:"rssi"`
+	Data      BleBytes        `json:"data"`
+
+	// Optional
+	DataFlags          uint8  `json:"data_flags"`
+	DataName           string `json:"data_name"`
+	DataNameIsComplete bool   `json:"data_name_is_complete"`
+}
+
+type BleScanCancelReq struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+}
+
+type BleScanCancelRsp struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Mandatory
+	Status int `json:"status"`
+}
+
+func ErrCodeToString(e int) string {
+	var s string
+
+	switch {
+	case e >= ERR_CODE_SM_PEER_BASE:
+	case e >= ERR_CODE_SM_US_BASE:
+	case e >= ERR_CODE_L2C_BASE:
+	case e >= ERR_CODE_HCI_BASE:
+		s = HciErrCodeStringMap[e-ERR_CODE_HCI_BASE]
+
+	case e >= ERR_CODE_ATT_BASE:
+	default:
+		s = ErrCodeStringMap[e]
+	}
+
+	if s == "" {
+		s = "unknown"
+	}
+
+	return s
+}
+
+func MsgOpToString(op MsgOp) string {
+	s := MsgOpStringMap[op]
+	if s == "" {
+		panic(fmt.Sprintf("Invalid MsgOp: %d", int(op)))
+	}
+
+	return s
+}
+
+func MsgOpFromString(s string) (MsgOp, error) {
+	for op, name := range MsgOpStringMap {
+		if s == name {
+			return op, nil
+		}
+	}
+
+	return MsgOp(0), errors.New("Invalid MsgOp string: " + s)
+}
+
+func MsgTypeToString(msgType MsgType) string {
+	s := MsgTypeStringMap[msgType]
+	if s == "" {
+		panic(fmt.Sprintf("Invalid MsgType: %d", int(msgType)))
+	}
+
+	return s
+}
+
+func MsgTypeFromString(s string) (MsgType, error) {
+	for addrType, name := range MsgTypeStringMap {
+		if s == name {
+			return addrType, nil
+		}
+	}
+
+	return MsgType(0), errors.New("Invalid MsgType string: " + s)
+}
+
+func (o MsgOp) MarshalJSON() ([]byte, error) {
+	return json.Marshal(MsgOpToString(o))
+}
+
+func (o *MsgOp) UnmarshalJSON(data []byte) error {
+	var err error
+
+	var s string
+	if err := json.Unmarshal(data, &s); err != nil {
+		return err
+	}
+
+	*o, err = MsgOpFromString(s)
+	return err
+}
+
+func (t MsgType) MarshalJSON() ([]byte, error) {
+	return json.Marshal(MsgTypeToString(t))
+}
+
+func (t *MsgType) UnmarshalJSON(data []byte) error {
+	var err error
+
+	var s string
+	if err := json.Unmarshal(data, &s); err != nil {
+		return err
+	}
+
+	*t, err = MsgTypeFromString(s)
+	return err
+}
+
+func (bb *BleBytes) MarshalJSON() ([]byte, error) {
+	var buf bytes.Buffer
+	buf.Grow(len(bb.Bytes) * 5)
+
+	for i, b := range bb.Bytes {
+		if i != 0 {
+			buf.WriteString(":")
+		}
+		fmt.Fprintf(&buf, "0x%02x", b)
+	}
+
+	s := buf.String()
+	return json.Marshal(s)
+
+	return buf.Bytes(), nil
+}
+
+func (bb *BleBytes) UnmarshalJSON(data []byte) error {
+	var s string
+	if err := json.Unmarshal(data, &s); err != nil {
+		return err
+	}
+
+	// strings.Split() appears to return { nil } when passed an empty string.
+	if len(s) == 0 {
+		return nil
+	}
+
+	toks := strings.Split(strings.ToLower(s), ":")
+	bb.Bytes = make([]byte, len(toks))
+
+	for i, t := range toks {
+		if !strings.HasPrefix(t, "0x") {
+			return fmt.Errorf(
+				"Byte stream contains invalid token; token=%s stream=%s", t, s)
+		}
+
+		u64, err := strconv.ParseUint(t, 0, 8)
+		if err != nil {
+			return err
+		}
+		bb.Bytes[i] = byte(u64)
+	}
+
+	return nil
+}
+
+func (bu *BleUuid) String() string {
+	var buf bytes.Buffer
+	buf.Grow(len(bu.Bytes)*2 + 3)
+
+	// XXX: For now, only support 128-bit UUIDs.
+
+	for i, b := range bu.Bytes {
+		switch i {
+		case 4, 6, 8, 10:
+			buf.WriteString("-")
+		}
+
+		fmt.Fprintf(&buf, "%02x", b)
+	}
+
+	return buf.String()
+}
+
+func (bu *BleUuid) MarshalJSON() ([]byte, error) {
+	return json.Marshal(bu.String())
+}
+
+func (bu *BleUuid) UnmarshalJSON(data []byte) error {
+	var s string
+	if err := json.Unmarshal(data, &s); err != nil {
+		return err
+	}
+
+	var err error
+	*bu, err = ParseUuid(s)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func CompareUuids(a BleUuid, b BleUuid) int {
+	return bytes.Compare(a.Bytes[:], b.Bytes[:])
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..31f0e62
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_util.go
@@ -0,0 +1,174 @@
+package nmble
+
+import (
+	"fmt"
+	"strconv"
+	"sync/atomic"
+
+	log "github.com/Sirupsen/logrus"
+
+	. "mynewt.apache.org/newtmgr/nmxact/bledefs"
+	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
+)
+
+const NmpPlainSvcUuid = "8D53DC1D-1DB7-4CD3-868B-8A527460AA84"
+const NmpPlainChrUuid = "DA2E7828-FBCE-4E01-AE9E-261174997C48"
+const NmpOicSvcUuid = "ADE3D529-C784-4F63-A987-EB69F70EE816"
+const NmpOicReqChrUuid = "AD7B334F-4637-4B86-90B6-9D787F03D218"
+const NmpOicRspChrUuid = "E9241982-4580-42C4-8831-95048216B256"
+
+const WRITE_CMD_BASE_SZ = 3
+const NOTIFY_CMD_BASE_SZ = 3
+
+var nextSeq uint32
+
+func NextSeq() int {
+	return int(atomic.AddUint32(&nextSeq, 1))
+}
+
+func ParseUuid(uuidStr string) (BleUuid, error) {
+	bu := BleUuid{}
+
+	if len(uuidStr) != 36 {
+		return bu, fmt.Errorf("Invalid UUID: %s", uuidStr)
+	}
+
+	boff := 0
+	for i := 0; i < 36; {
+		switch i {
+		case 8, 13, 18, 23:
+			if uuidStr[i] != '-' {
+				return bu, fmt.Errorf("Invalid UUID: %s", uuidStr)
+			}
+			i++
+
+		default:
+			u64, err := strconv.ParseUint(uuidStr[i:i+2], 16, 8)
+			if err != nil {
+				return bu, fmt.Errorf("Invalid UUID: %s", uuidStr)
+			}
+			bu.Bytes[boff] = byte(u64)
+			i += 2
+			boff++
+		}
+	}
+
+	return bu, nil
+}
+
+func BhdTimeoutError(rspType MsgType) error {
+	str := fmt.Sprintf("Timeout waiting for blehostd to send %s response",
+		MsgTypeToString(rspType))
+
+	log.Debug(str)
+	return nmxutil.NewXportTimeoutError(str)
+}
+
+func StatusError(op MsgOp, msgType MsgType, status int) error {
+	str := fmt.Sprintf("%s %s indicates error: %s (%d)",
+		MsgOpToString(op),
+		MsgTypeToString(msgType),
+		ErrCodeToString(status),
+		status)
+
+	log.Debug(str)
+	return nmxutil.NewBleHostError(status, str)
+}
+
+func NewBleConnectReq() *BleConnectReq {
+	return &BleConnectReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_CONNECT,
+		Seq:  NextSeq(),
+
+		OwnAddrType:  BLE_ADDR_TYPE_PUBLIC,
+		PeerAddrType: BLE_ADDR_TYPE_PUBLIC,
+		PeerAddr:     BleAddr{},
+
+		DurationMs:         30000,
+		ScanItvl:           0x0010,
+		ScanWindow:         0x0010,
+		ItvlMin:            24,
+		ItvlMax:            40,
+		Latency:            0,
+		SupervisionTimeout: 0x0200,
+		MinCeLen:           0x0010,
+		MaxCeLen:           0x0300,
+	}
+}
+
+func NewBleTerminateReq() *BleTerminateReq {
+	return &BleTerminateReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_TERMINATE,
+		Seq:  NextSeq(),
+
+		ConnHandle: 0,
+		HciReason:  0,
+	}
+}
+
+func NewBleConnCancelReq() *BleConnCancelReq {
+	return &BleConnCancelReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_CONN_CANCEL,
+		Seq:  NextSeq(),
+	}
+}
+
+func NewBleDiscSvcUuidReq() *BleDiscSvcUuidReq {
+	return &BleDiscSvcUuidReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_DISC_SVC_UUID,
+		Seq:  NextSeq(),
+
+		ConnHandle: 0,
+		Uuid:       BleUuid{},
+	}
+}
+
+func NewBleDiscAllChrsReq() *BleDiscAllChrsReq {
+	return &BleDiscAllChrsReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_DISC_ALL_CHRS,
+		Seq:  NextSeq(),
+	}
+}
+
+func NewBleExchangeMtuReq() *BleExchangeMtuReq {
+	return &BleExchangeMtuReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_EXCHANGE_MTU,
+		Seq:  NextSeq(),
+
+		ConnHandle: 0,
+	}
+}
+
+func NewBleWriteCmdReq() *BleWriteCmdReq {
+	return &BleWriteCmdReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_WRITE_CMD,
+		Seq:  NextSeq(),
+
+		ConnHandle: 0,
+		AttrHandle: 0,
+		Data:       BleBytes{},
+	}
+}
+
+func NewBleScanReq() *BleScanReq {
+	return &BleScanReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_SCAN,
+		Seq:  NextSeq(),
+	}
+}
+
+func NewBleScanCancelReq() *BleScanCancelReq {
+	return &BleScanCancelReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_SCAN_CANCEL,
+		Seq:  NextSeq(),
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..ba38b9d
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/ble_xport.go
@@ -0,0 +1,319 @@
+package nmble
+
+import (
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"sync/atomic"
+	"time"
+
+	log "github.com/Sirupsen/logrus"
+
+	"mynewt.apache.org/newtmgr/nmxact/nmxutil"
+	"mynewt.apache.org/newtmgr/nmxact/sesn"
+	"mynewt.apache.org/newt/util/unixchild"
+)
+
+type XportCfg struct {
+	// Path of Unix domain socket to create and listen on.
+	SockPath string
+
+	// Path of the blehostd executable.
+	BlehostdPath string
+
+	// How long to wait for the blehostd process to connect to the Unix domain
+	// socket.
+	BlehostdAcceptTimeout time.Duration
+
+	// Whether to restart the blehostd process if it terminates.
+	BlehostdRestart bool
+
+	// How long to wait for a JSON response from the blehostd process.
+	BlehostdRspTimeout time.Duration
+
+	// Path of the BLE controller device (e.g., /dev/ttyUSB0).
+	DevPath string
+}
+
+func NewXportCfg() XportCfg {
+	return XportCfg{
+		BlehostdAcceptTimeout: time.Second,
+		BlehostdRestart:       true,
+		BlehostdRspTimeout:    time.Second,
+	}
+}
+
+type BleXportState uint32
+
+const (
+	BLE_XPORT_STATE_STOPPED BleXportState = iota
+	BLE_XPORT_STATE_STARTING
+	BLE_XPORT_STATE_STARTED
+)
+
+// Implements xport.Xport.
+type BleXport struct {
+	Bd     *BleDispatcher
+	client *unixchild.Client
+	state  BleXportState
+
+	syncTimeout time.Duration
+	rspTimeout  time.Duration
+}
+
+func NewBleXport(cfg XportCfg) (*BleXport, error) {
+	config := unixchild.Config{
+		SockPath:      cfg.SockPath,
+		ChildPath:     cfg.BlehostdPath,
+		ChildArgs:     []string{cfg.DevPath, cfg.SockPath},
+		Depth:         10,
+		MaxMsgSz:      10240,
+		AcceptTimeout: cfg.BlehostdAcceptTimeout,
+		Restart:       cfg.BlehostdRestart,
+	}
+
+	c := unixchild.New(config)
+
+	bx := &BleXport{
+		client:      c,
+		Bd:          NewBleDispatcher(),
+		syncTimeout: 10 * time.Second,
+		rspTimeout:  cfg.BlehostdRspTimeout,
+	}
+
+	return bx, 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) addSyncListener() (*BleListener, error) {
+	bl := NewBleListener()
+	base := BleMsgBase{
+		Op:         MSG_OP_EVT,
+		Type:       MSG_TYPE_SYNC_EVT,
+		Seq:        -1,
+		ConnHandle: -1,
+	}
+	if err := bx.Bd.AddListener(base, bl); err != nil {
+		return nil, err
+	}
+
+	return bl, nil
+}
+
+func (bx *BleXport) removeSyncListener() {
+	base := BleMsgBase{
+		Op:         MSG_OP_EVT,
+		Type:       MSG_TYPE_SYNC_EVT,
+		Seq:        -1,
+		ConnHandle: -1,
+	}
+	bx.Bd.RemoveListener(base)
+}
+
+func (bx *BleXport) querySyncStatus() (bool, error) {
+	req := &BleSyncReq{
+		Op:   MSG_OP_REQ,
+		Type: MSG_TYPE_SYNC,
+		Seq:  NextSeq(),
+	}
+
+	j, err := json.Marshal(req)
+	if err != nil {
+		return false, err
+	}
+
+	bl := NewBleListener()
+	base := BleMsgBase{
+		Op:         -1,
+		Type:       -1,
+		Seq:        req.Seq,
+		ConnHandle: -1,
+	}
+	if err := bx.Bd.AddListener(base, bl); err != nil {
+		return false, err
+	}
+	defer bx.Bd.RemoveListener(base)
+
+	bx.txNoSync(j)
+	for {
+		select {
+		case err := <-bl.ErrChan:
+			return false, err
+		case bm := <-bl.BleChan:
+			switch msg := bm.(type) {
+			case *BleSyncRsp:
+				return msg.Synced, nil
+			}
+		}
+	}
+}
+
+func (bx *BleXport) initialSyncCheck() (bool, *BleListener, error) {
+	bl, err := bx.addSyncListener()
+	if err != nil {
+		return false, nil, err
+	}
+
+	synced, err := bx.querySyncStatus()
+	if err != nil {
+		bx.removeSyncListener()
+		return false, nil, err
+	}
+
+	return synced, bl, nil
+}
+
+func (bx *BleXport) onError(err error) {
+	if !bx.setStateFrom(BLE_XPORT_STATE_STARTED, BLE_XPORT_STATE_STOPPED) &&
+		!bx.setStateFrom(BLE_XPORT_STATE_STARTING, BLE_XPORT_STATE_STOPPED) {
+
+		// Stop already in progress.
+		return
+	}
+	bx.Bd.ErrorAll(err)
+	if bx.client != nil {
+		bx.client.Stop()
+		bx.client.FromChild <- nil
+	}
+}
+
+func (bx *BleXport) setStateFrom(from BleXportState, to BleXportState) bool {
+	return atomic.CompareAndSwapUint32(
+		(*uint32)(&bx.state), uint32(from), uint32(to))
+}
+
+func (bx *BleXport) getState() BleXportState {
+	u32 := atomic.LoadUint32((*uint32)(&bx.state))
+	return BleXportState(u32)
+}
+
+func (bx *BleXport) Stop() error {
+	bx.onError(nil)
+	return nil
+}
+
+func (bx *BleXport) Start() error {
+	if !bx.setStateFrom(BLE_XPORT_STATE_STOPPED, BLE_XPORT_STATE_STARTING) {
+		return nmxutil.NewXportError("BLE xport started twice")
+	}
+
+	if err := bx.client.Start(); err != nil {
+		return nmxutil.NewXportError(
+			"Failed to start child child process: " + err.Error())
+	}
+
+	go func() {
+		err := <-bx.client.ErrChild
+		if unixchild.IsUcAcceptError(err) {
+			err = fmt.Errorf("blehostd did not connect to socket; " +
+				"controller not attached?")
+		}
+		bx.onError(err)
+		return
+	}()
+
+	go func() {
+		for {
+			if _, err := bx.rx(); err != nil {
+				// The error should have been reported to everyone interested.
+				break
+			}
+		}
+	}()
+
+	synced, bl, err := bx.initialSyncCheck()
+	if err != nil {
+		bx.Stop()
+		return err
+	}
+
+	if !synced {
+		// Not synced yet.  Wait for sync event.
+
+	SyncLoop:
+		for {
+			select {
+			case err := <-bl.ErrChan:
+				return err
+			case bm := <-bl.BleChan:
+				switch msg := bm.(type) {
+				case *BleSyncEvt:
+					if msg.Synced {
+						break SyncLoop
+					}
+				}
+			case <-time.After(bx.syncTimeout):
+				bx.Stop()
+				return nmxutil.NewXportError(
+					"Timeout waiting for host <-> controller sync")
+			}
+		}
+	}
+
+	// Host and controller are synced.  Listen for sync loss in the background.
+	go func() {
+		for {
+			select {
+			case err := <-bl.ErrChan:
+				bx.onError(err)
+				return
+			case bm := <-bl.BleChan:
+				switch msg := bm.(type) {
+				case *BleSyncEvt:
+					if !msg.Synced {
+						bx.onError(nmxutil.NewXportError(
+							"BLE host <-> controller sync lost"))
+						return
+					}
+				}
+			}
+		}
+	}()
+
+	if !bx.setStateFrom(BLE_XPORT_STATE_STARTING, BLE_XPORT_STATE_STARTED) {
+		return nmxutil.NewXportError(
+			"Internal error; BLE transport in unexpected state")
+	}
+
+	return nil
+}
+
+func (bx *BleXport) txNoSync(data []byte) {
+	log.Debugf("Tx to blehostd:\n%s", hex.Dump(data))
+	bx.client.ToChild <- data
+}
+
+func (bx *BleXport) Tx(data []byte) error {
+	if bx.getState() != BLE_XPORT_STATE_STARTED {
+		return nmxutil.NewXportError("Attempt to transmit before BLE xport " +
+			"fully started")
+	}
+
+	bx.txNoSync(data)
+	return nil
+}
+
+func (bx *BleXport) rx() ([]byte, error) {
+	select {
+	case err := <-bx.client.ErrChild:
+		return nil, err
+	case buf := <-bx.client.FromChild:
+		if len(buf) != 0 {
+			log.Debugf("Receive from blehostd:\n%s", hex.Dump(buf))
+			bx.Bd.Dispatch(buf)
+		}
+		return buf, nil
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/dispatch.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/dispatch.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/dispatch.go
new file mode 100644
index 0000000..546fc11
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmble/dispatch.go
@@ -0,0 +1,297 @@
+/**
+ * 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/json"
+	"fmt"
+	"sync"
+	"time"
+
+	log "github.com/Sirupsen/logrus"
+)
+
+type OpTypePair struct {
+	Op   MsgOp
+	Type MsgType
+}
+
+type BleMsgBase struct {
+	// Header
+	Op   MsgOp   `json:"op"`
+	Type MsgType `json:"type"`
+	Seq  int     `json:"seq"`
+
+	// Optional
+	ConnHandle int `json:"conn_handle" json:",omitempty"`
+}
+
+type BleListener struct {
+	BleChan chan BleMsg
+	ErrChan chan error
+	TmoChan chan time.Time
+	Acked   bool
+
+	timer *time.Timer
+}
+
+func NewBleListener() *BleListener {
+	return &BleListener{
+		BleChan: make(chan BleMsg, 16),
+		ErrChan: make(chan error, 4),
+		TmoChan: make(chan time.Time, 1),
+	}
+}
+
+func (bl *BleListener) AfterTimeout(tmo time.Duration) <-chan time.Time {
+	fn := func() {
+		if !bl.Acked {
+			bl.TmoChan <- time.Now()
+		}
+	}
+	bl.timer = time.AfterFunc(tmo, fn)
+	return bl.TmoChan
+}
+
+func (bl *BleListener) Stop() {
+	if bl.timer != nil {
+		bl.timer.Stop()
+	}
+}
+
+type BleDispatcher struct {
+	seqMap  map[int]*BleListener
+	baseMap map[BleMsgBase]*BleListener
+	mutex   sync.Mutex
+}
+
+type msgCtor func() BleMsg
+
+func errRspCtor() BleMsg         { return &BleErrRsp{} }
+func syncRspCtor() BleMsg        { return &BleSyncRsp{} }
+func connectRspCtor() BleMsg     { return &BleConnectRsp{} }
+func terminateRspCtor() BleMsg   { return &BleTerminateRsp{} }
+func discSvcUuidRspCtor() BleMsg { return &BleDiscSvcUuidRsp{} }
+func discAllChrsRspCtor() BleMsg { return &BleDiscAllChrsRsp{} }
+func discChrUuidRspCtor() BleMsg { return &BleDiscChrUuidRsp{} }
+func writeCmdRspCtor() BleMsg    { return &BleWriteCmdRsp{} }
+func exchangeMtuRspCtor() BleMsg { return &BleExchangeMtuRsp{} }
+func connCancelRspCtor() BleMsg  { return &BleConnCancelRsp{} }
+func scanRspCtor() BleMsg        { return &BleScanRsp{} }
+func scanCancelRspCtor() BleMsg  { return &BleScanCancelRsp{} }
+
+func syncEvtCtor() BleMsg       { return &BleSyncEvt{} }
+func connectEvtCtor() BleMsg    { return &BleConnectEvt{} }
+func disconnectEvtCtor() BleMsg { return &BleDisconnectEvt{} }
+func discSvcEvtCtor() BleMsg    { return &BleDiscSvcEvt{} }
+func discChrEvtCtor() BleMsg    { return &BleDiscChrEvt{} }
+func notifyRxEvtCtor() BleMsg   { return &BleNotifyRxEvt{} }
+func mtuChangeEvtCtor() BleMsg  { return &BleMtuChangeEvt{} }
+func scanEvtCtor() BleMsg       { return &BleScanEvt{} }
+
+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_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_WRITE_CMD}:     writeCmdRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_EXCHANGE_MTU}:  exchangeMtuRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_CONN_CANCEL}:   connCancelRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_SCAN}:          scanRspCtor,
+	{MSG_OP_RSP, MSG_TYPE_SCAN_CANCEL}:   scanCancelRspCtor,
+
+	{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_NOTIFY_RX_EVT}:  notifyRxEvtCtor,
+	{MSG_OP_EVT, MSG_TYPE_MTU_CHANGE_EVT}: mtuChangeEvtCtor,
+	{MSG_OP_EVT, MSG_TYPE_SCAN_EVT}:       scanEvtCtor,
+}
+
+func NewBleDispatcher() *BleDispatcher {
+	return &BleDispatcher{
+		seqMap:  map[int]*BleListener{},
+		baseMap: map[BleMsgBase]*BleListener{},
+	}
+}
+
+func (bd *BleDispatcher) findBaseListener(base BleMsgBase) (
+	BleMsgBase, *BleListener) {
+
+	for k, v := range bd.baseMap {
+		if k.Op != -1 && base.Op != -1 && k.Op != base.Op {
+			continue
+		}
+		if k.Type != -1 && base.Type != -1 && k.Type != base.Type {
+			continue
+		}
+		if k.ConnHandle != -1 && base.ConnHandle != -1 &&
+			k.ConnHandle != base.ConnHandle {
+
+			continue
+		}
+
+		return k, v
+	}
+
+	return base, nil
+}
+
+func (bd *BleDispatcher) findDupListener(base BleMsgBase) (
+	BleMsgBase, *BleListener) {
+
+	if base.Seq != -1 {
+		return base, bd.seqMap[base.Seq]
+	}
+
+	return bd.findBaseListener(base)
+}
+
+func (bd *BleDispatcher) findListener(base BleMsgBase) (
+	BleMsgBase, *BleListener) {
+
+	if base.Seq != -1 {
+		if bl := bd.seqMap[base.Seq]; bl != nil {
+			return base, bl
+		}
+	}
+
+	return bd.findBaseListener(base)
+}
+
+func (bd *BleDispatcher) AddListener(base BleMsgBase,
+	listener *BleListener) error {
+
+	bd.mutex.Lock()
+	defer bd.mutex.Unlock()
+
+	if ob, old := bd.findDupListener(base); old != nil {
+		return fmt.Errorf(
+			"Duplicate BLE listener;\n"+
+				"    old=op=%d type=%d seq=%d connHandle=%d\n"+
+				"    new=op=%d type=%d seq=%d connHandle=%d",
+			ob.Op, ob.Type, ob.Seq, ob.ConnHandle,
+			base.Op, base.Type, base.Seq, base.ConnHandle)
+	}
+
+	if base.Seq != -1 {
+		if base.Op != -1 ||
+			base.Type != -1 ||
+			base.ConnHandle != -1 {
+			return fmt.Errorf(
+				"Invalid listener base; non-wild seq with wild fields")
+		}
+
+		bd.seqMap[base.Seq] = listener
+	} else {
+		bd.baseMap[base] = listener
+	}
+
+	return nil
+}
+
+func (bd *BleDispatcher) RemoveListener(base BleMsgBase) *BleListener {
+	bd.mutex.Lock()
+	defer bd.mutex.Unlock()
+
+	base, bl := bd.findListener(base)
+	if bl != nil {
+		bl.Stop()
+		if base.Seq != -1 {
+			delete(bd.seqMap, base.Seq)
+		} else {
+			delete(bd.baseMap, base)
+		}
+	}
+
+	return bl
+}
+
+func decodeBleBase(data []byte) (BleMsgBase, error) {
+	base := BleMsgBase{}
+	if err := json.Unmarshal(data, &base); err != nil {
+		return base, err
+	}
+
+	return base, nil
+}
+
+func decodeBleMsg(data []byte) (BleMsgBase, BleMsg, error) {
+	base, err := decodeBleBase(data)
+	if err != nil {
+		return base, nil, err
+	}
+
+	opTypePair := OpTypePair{base.Op, base.Type}
+	cb := msgCtorMap[opTypePair]
+	if cb == nil {
+		return base, nil, fmt.Errorf(
+			"Unrecognized op+type pair: %s, %s",
+			MsgOpToString(base.Op), MsgTypeToString(base.Type))
+	}
+
+	msg := cb()
+	if err := json.Unmarshal(data, msg); err != nil {
+		return base, nil, err
+	}
+
+	return base, msg, nil
+}
+
+func (bd *BleDispatcher) Dispatch(data []byte) {
+	base, msg, err := decodeBleMsg(data)
+	if err != nil {
+		log.Warnf("BLE dispatch error: %s", err.Error())
+		return
+	}
+
+	_, listener := bd.findListener(base)
+	if listener == nil {
+		log.Debugf(
+			"No BLE listener for op=%d type=%d seq=%d connHandle=%d",
+			base.Op, base.Type, base.Seq, base.ConnHandle)
+		return
+	}
+
+	listener.BleChan <- msg
+}
+
+func (bd *BleDispatcher) ErrorAll(err error) {
+	bd.mutex.Lock()
+
+	listeners := make([]*BleListener, 0, len(bd.seqMap)+len(bd.baseMap))
+	for _, v := range bd.seqMap {
+		listeners = append(listeners, v)
+	}
+	for _, v := range bd.baseMap {
+		listeners = append(listeners, v)
+	}
+
+	bd.mutex.Unlock()
+
+	for _, listener := range listeners {
+		listener.ErrChan <- err
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/config.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/config.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/config.go
new file mode 100644
index 0000000..dc00df5
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/config.go
@@ -0,0 +1,80 @@
+/**
+ * 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 nmp
+
+import ()
+
+//////////////////////////////////////////////////////////////////////////////
+// $read                                                                    //
+//////////////////////////////////////////////////////////////////////////////
+
+type ConfigReadReq struct {
+	NmpBase `structs:"-"`
+	Name    string `codec:"name"`
+}
+
+type ConfigReadRsp struct {
+	NmpBase
+	Rc  int    `codec:"rc" codec:",omitempty"`
+	Val string `codec:"val"`
+}
+
+func NewConfigReadReq() *ConfigReadReq {
+	r := &ConfigReadReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_CONFIG, NMP_ID_CONFIG_VAL)
+	return r
+}
+
+func (r *ConfigReadReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewConfigReadRsp() *ConfigReadRsp {
+	return &ConfigReadRsp{}
+}
+
+func (r *ConfigReadRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $write                                                                   //
+//////////////////////////////////////////////////////////////////////////////
+
+type ConfigWriteReq struct {
+	NmpBase
+	Name string `codec:"name"`
+	Val  string `codec:"val"`
+}
+
+type ConfigWriteRsp struct {
+	NmpBase
+	Rc int `codec:"rc" codec:",omitempty"`
+}
+
+func NewConfigWriteReq() *ConfigWriteReq {
+	r := &ConfigWriteReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_CONFIG, NMP_ID_CONFIG_VAL)
+	return r
+}
+
+func (r *ConfigWriteReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewConfigWriteRsp() *ConfigWriteRsp {
+	return &ConfigWriteRsp{}
+}
+
+func (r *ConfigWriteRsp) Msg() *NmpMsg { return MsgFromReq(r) }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/crash.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/crash.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/crash.go
new file mode 100644
index 0000000..5711d7f
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/crash.go
@@ -0,0 +1,46 @@
+/**
+ * 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 nmp
+
+import ()
+
+type CrashReq struct {
+	NmpBase
+	CrashType string `codec:"t"`
+}
+
+type CrashRsp struct {
+	NmpBase
+	Rc int `codec:"rc" codec:",omitempty"`
+}
+
+func NewCrashReq() *CrashReq {
+	r := &CrashReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_CRASH, NMP_ID_CRASH_TRIGGER)
+	return r
+}
+
+func (r *CrashReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewCrashRsp() *CrashRsp {
+	return &CrashRsp{}
+}
+
+func (r *CrashRsp) Msg() *NmpMsg { return MsgFromReq(r) }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/datetime.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/datetime.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/datetime.go
new file mode 100644
index 0000000..ce52d8b
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/datetime.go
@@ -0,0 +1,78 @@
+/**
+ * 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 nmp
+
+import ()
+
+///////////////////////////////////////////////////////////////////////////////
+// $read                                                                     //
+///////////////////////////////////////////////////////////////////////////////
+
+type DateTimeReadReq struct {
+	NmpBase
+}
+
+type DateTimeReadRsp struct {
+	NmpBase
+	DateTime string `codec:"datetime"`
+	Rc       int    `codec:"rc" codec:",omitempty"`
+}
+
+func NewDateTimeReadReq() *DateTimeReadReq {
+	r := &DateTimeReadReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_DEFAULT, NMP_ID_DEF_DATETIME_STR)
+	return r
+}
+
+func (r *DateTimeReadReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewDateTimeReadRsp() *DateTimeReadRsp {
+	return &DateTimeReadRsp{}
+}
+
+func (r *DateTimeReadRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+///////////////////////////////////////////////////////////////////////////////
+// $write                                                                    //
+///////////////////////////////////////////////////////////////////////////////
+
+type DateTimeWriteReq struct {
+	NmpBase
+	DateTime string `codec:"datetime"`
+}
+
+type DateTimeWriteRsp struct {
+	NmpBase
+	Rc int `codec:"rc" codec:",omitempty"`
+}
+
+func NewDateTimeWriteReq() *DateTimeWriteReq {
+	r := &DateTimeWriteReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_DEFAULT, NMP_ID_DEF_DATETIME_STR)
+	return r
+}
+
+func (r *DateTimeWriteReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewDateTimeWriteRsp() *DateTimeWriteRsp {
+	return &DateTimeWriteRsp{}
+}
+
+func (r *DateTimeWriteRsp) Msg() *NmpMsg { return MsgFromReq(r) }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/decode.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/decode.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/decode.go
new file mode 100644
index 0000000..748d13d
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/decode.go
@@ -0,0 +1,121 @@
+/**
+ * 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 nmp
+
+import (
+	"fmt"
+
+	"github.com/ugorji/go/codec"
+)
+
+// These aliases just allow the ctor map to fit within 79 columns.
+const op_wr = NMP_OP_WRITE_RSP
+const op_rr = NMP_OP_READ_RSP
+const gr_def = NMP_GROUP_DEFAULT
+const gr_img = NMP_GROUP_IMAGE
+const gr_sta = NMP_GROUP_STAT
+const gr_cfg = NMP_GROUP_CONFIG
+const gr_log = NMP_GROUP_LOG
+const gr_cra = NMP_GROUP_CRASH
+const gr_run = NMP_GROUP_RUN
+const gr_fil = NMP_GROUP_FS
+
+// Op-Group-Id
+type Ogi struct {
+	Op    uint8
+	Group uint16
+	Id    uint8
+}
+
+type rspCtor func() NmpRsp
+
+func echoRspCtor() NmpRsp          { return NewEchoRsp() }
+func taskStatRspCtor() NmpRsp      { return NewTaskStatRsp() }
+func mpStatRspCtor() NmpRsp        { return NewMempoolStatRsp() }
+func dateTimeReadRspCtor() NmpRsp  { return NewDateTimeReadRsp() }
+func dateTimeWriteRspCtor() NmpRsp { return NewDateTimeWriteRsp() }
+func resetRspCtor() NmpRsp         { return NewResetRsp() }
+func imageUploadRspCtor() NmpRsp   { return NewImageUploadRsp() }
+func imageStateRspCtor() NmpRsp    { return NewImageStateRsp() }
+func coreListRspCtor() NmpRsp      { return NewCoreListRsp() }
+func coreLoadRspCtor() NmpRsp      { return NewCoreLoadRsp() }
+func coreEraseRspCtor() NmpRsp     { return NewCoreEraseRsp() }
+func statReadRspCtor() NmpRsp      { return NewStatReadRsp() }
+func statListRspCtor() NmpRsp      { return NewStatListRsp() }
+func logReadRspCtor() NmpRsp       { return NewLogShowRsp() }
+func logListRspCtor() NmpRsp       { return NewLogListRsp() }
+func logModuleListRspCtor() NmpRsp { return NewLogModuleListRsp() }
+func logLevelListRspCtor() NmpRsp  { return NewLogLevelListRsp() }
+func logClearRspCtor() NmpRsp      { return NewLogClearRsp() }
+func crashRspCtor() NmpRsp         { return NewCrashRsp() }
+func runTestRspCtor() NmpRsp       { return NewRunTestRsp() }
+func runListRspCtor() NmpRsp       { return NewRunListRsp() }
+func fsDownloadRspCtor() NmpRsp    { return NewFsDownloadRsp() }
+func fsUploadRspCtor() NmpRsp      { return NewFsUploadRsp() }
+func configReadRspCtor() NmpRsp    { return NewConfigReadRsp() }
+func configWriteRspCtor() NmpRsp   { return NewConfigWriteRsp() }
+
+var rspCtorMap = map[Ogi]rspCtor{
+	{op_wr, gr_def, NMP_ID_DEF_ECHO}:         echoRspCtor,
+	{op_rr, gr_def, NMP_ID_DEF_TASKSTAT}:     taskStatRspCtor,
+	{op_rr, gr_def, NMP_ID_DEF_MPSTAT}:       mpStatRspCtor,
+	{op_rr, gr_def, NMP_ID_DEF_DATETIME_STR}: dateTimeReadRspCtor,
+	{op_wr, gr_def, NMP_ID_DEF_DATETIME_STR}: dateTimeWriteRspCtor,
+	{op_wr, gr_def, NMP_ID_DEF_RESET}:        resetRspCtor,
+	{op_wr, gr_img, NMP_ID_IMAGE_UPLOAD}:     imageUploadRspCtor,
+	{op_rr, gr_img, NMP_ID_IMAGE_STATE}:      imageStateRspCtor,
+	{op_wr, gr_img, NMP_ID_IMAGE_STATE}:      imageStateRspCtor,
+	{op_rr, gr_img, NMP_ID_IMAGE_CORELIST}:   coreListRspCtor,
+	{op_rr, gr_img, NMP_ID_IMAGE_CORELOAD}:   coreLoadRspCtor,
+	{op_wr, gr_img, NMP_ID_IMAGE_CORELOAD}:   coreEraseRspCtor,
+	{op_rr, gr_sta, NMP_ID_STAT_READ}:        statReadRspCtor,
+	{op_rr, gr_sta, NMP_ID_STAT_LIST}:        statListRspCtor,
+	{op_rr, gr_log, NMP_ID_LOG_SHOW}:         logReadRspCtor,
+	{op_rr, gr_log, NMP_ID_LOG_LIST}:         logListRspCtor,
+	{op_rr, gr_log, NMP_ID_LOG_MODULE_LIST}:  logModuleListRspCtor,
+	{op_rr, gr_log, NMP_ID_LOG_LEVEL_LIST}:   logLevelListRspCtor,
+	{op_wr, gr_log, NMP_ID_LOG_CLEAR}:        logClearRspCtor,
+	{op_wr, gr_cra, NMP_ID_CRASH_TRIGGER}:    crashRspCtor,
+	{op_wr, gr_run, NMP_ID_RUN_TEST}:         runTestRspCtor,
+	{op_rr, gr_run, NMP_ID_RUN_LIST}:         runListRspCtor,
+	{op_rr, gr_fil, NMP_ID_FS_FILE}:          fsDownloadRspCtor,
+	{op_wr, gr_fil, NMP_ID_FS_FILE}:          fsUploadRspCtor,
+	{op_rr, gr_cfg, NMP_ID_CONFIG_VAL}:       configReadRspCtor,
+	{op_wr, gr_cfg, NMP_ID_CONFIG_VAL}:       configWriteRspCtor,
+}
+
+func DecodeRspBody(hdr *NmpHdr, body []byte) (NmpRsp, error) {
+	cb := rspCtorMap[Ogi{hdr.Op, hdr.Group, hdr.Id}]
+	if cb == nil {
+		return nil, fmt.Errorf("Unrecognized NMP op+group+id: %d, %d, %d",
+			hdr.Op, hdr.Group, hdr.Id)
+	}
+
+	r := cb()
+	cborCodec := new(codec.CborHandle)
+	dec := codec.NewDecoderBytes(body, cborCodec)
+
+	if err := dec.Decode(r); err != nil {
+		return nil, fmt.Errorf("Invalid response: %s", err.Error())
+	}
+
+	r.SetHdr(hdr)
+	return r, nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/defs.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/defs.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/defs.go
new file mode 100644
index 0000000..d10ffe5
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/defs.go
@@ -0,0 +1,88 @@
+package nmp
+
+const (
+	NMP_OP_READ      = 0
+	NMP_OP_READ_RSP  = 1
+	NMP_OP_WRITE     = 2
+	NMP_OP_WRITE_RSP = 3
+)
+
+const (
+	NMP_ERR_OK       = 0
+	NMP_ERR_EUNKNOWN = 1
+	NMP_ERR_ENOMEM   = 2
+	NMP_ERR_EINVAL   = 3
+	NMP_ERR_ETIMEOUT = 4
+	NMP_ERR_ENOENT   = 5
+)
+
+// First 64 groups are reserved for system level newtmgr commands.
+// Per-user commands are then defined after group 64.
+
+const (
+	NMP_GROUP_DEFAULT = 0
+	NMP_GROUP_IMAGE   = 1
+	NMP_GROUP_STAT    = 2
+	NMP_GROUP_CONFIG  = 3
+	NMP_GROUP_LOG     = 4
+	NMP_GROUP_CRASH   = 5
+	NMP_GROUP_SPLIT   = 6
+	NMP_GROUP_RUN     = 7
+	NMP_GROUP_FS      = 8
+	NMP_GROUP_PERUSER = 64
+)
+
+// Default group (0).
+const (
+	NMP_ID_DEF_ECHO           = 0
+	NMP_ID_DEF_CONS_ECHO_CTRL = 1
+	NMP_ID_DEF_TASKSTAT       = 2
+	NMP_ID_DEF_MPSTAT         = 3
+	NMP_ID_DEF_DATETIME_STR   = 4
+	NMP_ID_DEF_RESET          = 5
+)
+
+// Image group (1).
+const (
+	NMP_ID_IMAGE_STATE    = 0
+	NMP_ID_IMAGE_UPLOAD   = 1
+	NMP_ID_IMAGE_CORELIST = 3
+	NMP_ID_IMAGE_CORELOAD = 4
+)
+
+// Stat group (2).
+const (
+	NMP_ID_STAT_READ = 0
+	NMP_ID_STAT_LIST = 1
+)
+
+// Config group (3).
+const (
+	NMP_ID_CONFIG_VAL = 0
+)
+
+// Log group (4).
+const (
+	NMP_ID_LOG_SHOW        = 0
+	NMP_ID_LOG_CLEAR       = 1
+	NMP_ID_LOG_APPEND      = 2
+	NMP_ID_LOG_MODULE_LIST = 3
+	NMP_ID_LOG_LEVEL_LIST  = 4
+	NMP_ID_LOG_LIST        = 5
+)
+
+// Crash group (5).
+const (
+	NMP_ID_CRASH_TRIGGER = 0
+)
+
+// Run group (7).
+const (
+	NMP_ID_RUN_TEST = 0
+	NMP_ID_RUN_LIST = 1
+)
+
+// File system group (8).
+const (
+	NMP_ID_FS_FILE = 0
+)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/dispatch.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/dispatch.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/dispatch.go
new file mode 100644
index 0000000..7b1ad11
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/dispatch.go
@@ -0,0 +1,167 @@
+/**
+ * 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 nmp
+
+import (
+	"encoding/hex"
+	"fmt"
+	"sync"
+	"time"
+
+	log "github.com/Sirupsen/logrus"
+)
+
+type NmpListener struct {
+	RspChan chan NmpRsp
+	ErrChan chan error
+	tmoChan chan time.Time
+	timer   *time.Timer
+}
+
+func NewNmpListener() *NmpListener {
+	return &NmpListener{
+		RspChan: make(chan NmpRsp, 1),
+		ErrChan: make(chan error, 1),
+	}
+}
+
+func (nl *NmpListener) AfterTimeout(tmo time.Duration) <-chan time.Time {
+	fn := func() {
+		nl.tmoChan <- time.Now()
+	}
+	nl.timer = time.AfterFunc(tmo, fn)
+	return nl.tmoChan
+}
+
+func (nl *NmpListener) Stop() {
+	if nl.timer != nil {
+		nl.timer.Stop()
+	}
+}
+
+type NmpDispatcher struct {
+	seqListenerMap map[uint8]*NmpListener
+	reassembler    *Reassembler
+	mutex          sync.Mutex
+}
+
+func NewNmpDispatcher() *NmpDispatcher {
+	return &NmpDispatcher{
+		seqListenerMap: map[uint8]*NmpListener{},
+		reassembler:    NewReassembler(),
+	}
+}
+
+func (nd *NmpDispatcher) AddListener(seq uint8, nl *NmpListener) error {
+	nd.mutex.Lock()
+	defer nd.mutex.Unlock()
+
+	if _, ok := nd.seqListenerMap[seq]; ok {
+		return fmt.Errorf("Duplicate NMP listener; seq=%d", seq)
+	}
+
+	nd.seqListenerMap[seq] = nl
+	return nil
+}
+
+func (nd *NmpDispatcher) removeListenerNoLock(seq uint8) *NmpListener {
+	nl := nd.seqListenerMap[seq]
+	if nl != nil {
+		nl.Stop()
+		delete(nd.seqListenerMap, seq)
+	}
+	return nl
+}
+
+func (nd *NmpDispatcher) RemoveListener(seq uint8) *NmpListener {
+	nd.mutex.Lock()
+	defer nd.mutex.Unlock()
+
+	return nd.removeListenerNoLock(seq)
+}
+
+func (nd *NmpDispatcher) FakeRxError(seq uint8, err error) error {
+	nd.mutex.Lock()
+	defer nd.mutex.Unlock()
+
+	nl := nd.seqListenerMap[seq]
+	if nl == nil {
+		return fmt.Errorf("No NMP listener for seq %d", seq)
+	}
+
+	nl.ErrChan <- err
+
+	return nil
+}
+
+func decodeRsp(pkt []byte) (NmpRsp, error) {
+	hdr, err := DecodeNmpHdr(pkt)
+	if err != nil {
+		return nil, err
+	}
+
+	// Ignore incoming non-responses.  This is necessary for devices that echo
+	// received requests over serial.
+	if hdr.Op != NMP_OP_READ_RSP && hdr.Op != NMP_OP_WRITE_RSP {
+		return nil, nil
+	}
+
+	body := pkt[NMP_HDR_SIZE:]
+	return DecodeRspBody(hdr, body)
+}
+
+// Returns true if the response was dispatched.
+func (nd *NmpDispatcher) DispatchRsp(r NmpRsp) bool {
+	log.Debugf("Received nmp rsp: %+v", r)
+
+	nl := nd.seqListenerMap[r.Hdr().Seq]
+	if nl == nil {
+		return false
+	}
+
+	nl.RspChan <- r
+
+	return true
+}
+
+// Returns true if the response was dispatched.
+func (nd *NmpDispatcher) Dispatch(data []byte) bool {
+	nd.mutex.Lock()
+	defer nd.mutex.Unlock()
+
+	pkt := nd.reassembler.RxFrag(data)
+	if pkt == nil {
+		return false
+	}
+
+	rsp, err := decodeRsp(pkt)
+	if err != nil {
+		log.Printf("Failure decoding NMP rsp: %s\npacket=\n%s", err.Error(),
+			hex.Dump(data))
+		return false
+	}
+
+	if rsp == nil {
+		// Packet wasn't a response.
+		return false
+	}
+
+	return nd.DispatchRsp(rsp)
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/echo.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/echo.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/echo.go
new file mode 100644
index 0000000..e8e334b
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/echo.go
@@ -0,0 +1,47 @@
+/**
+ * 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 nmp
+
+import ()
+
+type EchoReq struct {
+	NmpBase
+	Payload string `codec:"d"`
+}
+
+type EchoRsp struct {
+	NmpBase
+	Payload string `codec:"r"`
+	Rc      int    `codec:"rc" codec:",omitempty"`
+}
+
+func NewEchoReq() *EchoReq {
+	r := &EchoReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_DEFAULT, NMP_ID_DEF_ECHO)
+	return r
+}
+
+func (r *EchoReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewEchoRsp() *EchoRsp {
+	return &EchoRsp{}
+}
+
+func (r *EchoRsp) Msg() *NmpMsg { return MsgFromReq(r) }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/frag.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/frag.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/frag.go
new file mode 100644
index 0000000..31ee392
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/frag.go
@@ -0,0 +1,61 @@
+/**
+ * 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 nmp
+
+import (
+	log "github.com/Sirupsen/logrus"
+)
+
+type Reassembler struct {
+	cur []byte
+}
+
+func NewReassembler() *Reassembler {
+	return &Reassembler{}
+}
+
+func (r *Reassembler) RxFrag(frag []byte) []byte {
+	r.cur = append(r.cur, frag...)
+
+	hdr, err := DecodeNmpHdr(r.cur)
+	if err != nil {
+		// Incomplete header.
+		return nil
+	}
+
+	actualLen := len(r.cur) - NMP_HDR_SIZE
+	if actualLen > int(hdr.Len) {
+		// More data than expected.  Discard packet.
+		log.Debugf("received invalid nmp packet; hdr.len=%d actualLen=%d",
+			hdr.Len, actualLen)
+		r.cur = nil
+		return nil
+	}
+
+	if actualLen < int(hdr.Len) {
+		// More fragments to come.
+		return nil
+	}
+
+	// Packet complete
+	pkt := r.cur
+	r.cur = nil
+	return pkt
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/fs.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/fs.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/fs.go
new file mode 100644
index 0000000..91083de
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/fs.go
@@ -0,0 +1,86 @@
+/**
+ * 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 nmp
+
+import ()
+
+//////////////////////////////////////////////////////////////////////////////
+// $download                                                                //
+//////////////////////////////////////////////////////////////////////////////
+
+type FsDownloadReq struct {
+	NmpBase
+	Name string `codec:"name"`
+	Off  uint32 `codec:"off"`
+}
+
+type FsDownloadRsp struct {
+	NmpBase
+	Rc   int    `codec:"rc" codec:",omitempty"`
+	Off  uint32 `codec:"off"`
+	Len  uint32 `codec:"len"`
+	Data []byte `codec:"data"`
+}
+
+func NewFsDownloadReq() *FsDownloadReq {
+	r := &FsDownloadReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_FS, NMP_ID_FS_FILE)
+	return r
+}
+
+func (r *FsDownloadReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewFsDownloadRsp() *FsDownloadRsp {
+	return &FsDownloadRsp{}
+}
+
+func (r *FsDownloadRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $upload                                                                  //
+//////////////////////////////////////////////////////////////////////////////
+
+type FsUploadReq struct {
+	NmpBase
+	Name string `codec:"name" codec:",omitempty"`
+	Len  uint32 `codec:"len" codec:",omitempty"`
+	Off  uint32 `codec:"off"`
+	Data []byte `codec:"data"`
+}
+
+type FsUploadRsp struct {
+	NmpBase
+	Rc  int    `codec:"rc" codec:",omitempty"`
+	Off uint32 `codec:"off"`
+}
+
+func NewFsUploadReq() *FsUploadReq {
+	r := &FsUploadReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_FS, NMP_ID_FS_FILE)
+	return r
+}
+
+func (r *FsUploadReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewFsUploadRsp() *FsUploadRsp {
+	return &FsUploadRsp{}
+}
+
+func (r *FsUploadRsp) Msg() *NmpMsg { return MsgFromReq(r) }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/image.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/image.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/image.go
new file mode 100644
index 0000000..ac2d9a0
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/image.go
@@ -0,0 +1,215 @@
+/**
+ * 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 nmp
+
+import ()
+
+//////////////////////////////////////////////////////////////////////////////
+// $upload                                                                  //
+//////////////////////////////////////////////////////////////////////////////
+
+type ImageUploadReq struct {
+	NmpBase
+	Off  uint32 `codec:"off"`
+	Len  uint32 `codec:"len" codec:",omitempty"`
+	Data []byte `codec:"data"`
+}
+
+type ImageUploadRsp struct {
+	NmpBase
+	Rc  int    `codec:"rc" codec:",omitempty"`
+	Off uint32 `codec:"off"`
+}
+
+func NewImageUploadReq() *ImageUploadReq {
+	r := &ImageUploadReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_IMAGE, NMP_ID_IMAGE_UPLOAD)
+	return r
+}
+
+func (r *ImageUploadReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewImageUploadRsp() *ImageUploadRsp {
+	return &ImageUploadRsp{}
+}
+
+func (r *ImageUploadRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $state                                                                   //
+//////////////////////////////////////////////////////////////////////////////
+
+type SplitStatus int
+
+const (
+	NOT_APPLICABLE SplitStatus = iota
+	NOT_MATCHING
+	MATCHING
+)
+
+/* returns the enum as a string */
+func (sm SplitStatus) String() string {
+	names := map[SplitStatus]string{
+		NOT_APPLICABLE: "N/A",
+		NOT_MATCHING:   "non-matching",
+		MATCHING:       "matching",
+	}
+
+	str := names[sm]
+	if str == "" {
+		return "Unknown!"
+	}
+	return str
+}
+
+type ImageStateEntry struct {
+	NmpBase
+	Slot      int    `codec:"slot"`
+	Version   string `codec:"version"`
+	Hash      []byte `codec:"hash"`
+	Bootable  bool   `codec:"bootable"`
+	Pending   bool   `codec:"pending"`
+	Confirmed bool   `codec:"confirmed"`
+	Active    bool   `codec:"active"`
+	Permanent bool   `codec:"permanent"`
+}
+
+type ImageStateReadReq struct {
+	NmpBase
+}
+
+type ImageStateWriteReq struct {
+	NmpBase
+	Hash    []byte `codec:"hash"`
+	Confirm bool   `codec:"confirm"`
+}
+
+type ImageStateRsp struct {
+	NmpBase
+	Rc          int               `codec:"rc"`
+	Images      []ImageStateEntry `codec:"images"`
+	SplitStatus SplitStatus       `codec:"splitStatus"`
+}
+
+func NewImageStateReadReq() *ImageStateReadReq {
+	r := &ImageStateReadReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_IMAGE, NMP_ID_IMAGE_STATE)
+	return r
+}
+
+func (r *ImageStateReadReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewImageStateWriteReq() *ImageStateWriteReq {
+	r := &ImageStateWriteReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_IMAGE, NMP_ID_IMAGE_STATE)
+	return r
+}
+
+func (r *ImageStateWriteReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewImageStateRsp() *ImageStateRsp {
+	return &ImageStateRsp{}
+}
+
+func (r *ImageStateRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $corelist                                                                //
+//////////////////////////////////////////////////////////////////////////////
+
+type CoreListReq struct {
+	NmpBase
+}
+
+type CoreListRsp struct {
+	NmpBase
+	Rc int `codec:"rc"`
+}
+
+func NewCoreListReq() *CoreListReq {
+	r := &CoreListReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_IMAGE, NMP_ID_IMAGE_CORELIST)
+	return r
+}
+
+func (r *CoreListReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewCoreListRsp() *CoreListRsp {
+	return &CoreListRsp{}
+}
+
+func (r *CoreListRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $coreload                                                                //
+//////////////////////////////////////////////////////////////////////////////
+
+type CoreLoadReq struct {
+	NmpBase
+	Off uint32 `codec:"off"`
+}
+
+type CoreLoadRsp struct {
+	NmpBase
+	Rc   int    `codec:"rc"`
+	Off  uint32 `codec:"off"`
+	Data []byte `codec:"data"`
+}
+
+func NewCoreLoadReq() *CoreLoadReq {
+	r := &CoreLoadReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_IMAGE, NMP_ID_IMAGE_CORELOAD)
+	return r
+}
+
+func (r *CoreLoadReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewCoreLoadRsp() *CoreLoadRsp {
+	return &CoreLoadRsp{}
+}
+
+func (r *CoreLoadRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $coreerase                                                               //
+//////////////////////////////////////////////////////////////////////////////
+
+type CoreEraseReq struct {
+	NmpBase
+}
+
+type CoreEraseRsp struct {
+	NmpBase
+	Rc int `codec:"rc"`
+}
+
+func NewCoreEraseReq() *CoreEraseReq {
+	r := &CoreEraseReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_IMAGE, NMP_ID_IMAGE_CORELOAD)
+	return r
+}
+
+func (r *CoreEraseReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewCoreEraseRsp() *CoreEraseRsp {
+	return &CoreEraseRsp{}
+}
+
+func (r *CoreEraseRsp) Msg() *NmpMsg { return MsgFromReq(r) }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/log.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/log.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/log.go
new file mode 100644
index 0000000..e03376f
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/log.go
@@ -0,0 +1,260 @@
+/**
+ * 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 nmp
+
+import ()
+
+//////////////////////////////////////////////////////////////////////////////
+// $defs                                                                    //
+//////////////////////////////////////////////////////////////////////////////
+
+const (
+	LEVEL_DEBUG    int = 0
+	LEVEL_INFO         = 1
+	LEVEL_WARN         = 2
+	LEVEL_ERROR        = 3
+	LEVEL_CRITICAL     = 4
+	/* Upto 7 custom loglevels */
+	LEVEL_MAX = 255
+)
+
+const (
+	STREAM_LOG  int = 0
+	MEMORY_LOG      = 1
+	STORAGE_LOG     = 2
+)
+
+const (
+	MODULE_DEFAULT     int = 0
+	MODULE_OS              = 1
+	MODULE_NEWTMGR         = 2
+	MODULE_NIMBLE_CTLR     = 3
+	MODULE_NIMBLE_HOST     = 4
+	MODULE_NFFS            = 5
+	MODULE_REBOOT          = 6
+	MODULE_TEST            = 8
+	MODULE_MAX             = 255
+)
+
+var LogModuleNameMap = map[int]string{
+	MODULE_DEFAULT:     "DEFAULT",
+	MODULE_OS:          "OS",
+	MODULE_NEWTMGR:     "NEWTMGR",
+	MODULE_NIMBLE_CTLR: "NIMBLE_CTLR",
+	MODULE_NIMBLE_HOST: "NIMBLE_HOST",
+	MODULE_NFFS:        "NFFS",
+	MODULE_REBOOT:      "REBOOT",
+	MODULE_TEST:        "TEST",
+}
+
+var LogLevelNameMap = map[int]string{
+	LEVEL_DEBUG:    "DEBUG",
+	LEVEL_INFO:     "INFO",
+	LEVEL_WARN:     "WARN",
+	LEVEL_ERROR:    "ERROR",
+	LEVEL_CRITICAL: "CRITICAL",
+}
+
+var LogTypeNameMap = map[int]string{
+	STREAM_LOG:  "STREAM",
+	MEMORY_LOG:  "MEMORY",
+	STORAGE_LOG: "STORAGE",
+}
+
+func LogModuleToString(lm int) string {
+	name := LogModuleNameMap[lm]
+	if name == "" {
+		name = "CUSTOM"
+	}
+	return name
+}
+
+func LogLevelToString(lm int) string {
+	name := LogLevelNameMap[lm]
+	if name == "" {
+		name = "CUSTOM"
+	}
+	return name
+}
+
+func LogTypeToString(lm int) string {
+	name := LogTypeNameMap[lm]
+	if name == "" {
+		name = "UNDEFINED"
+	}
+	return name
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// $show                                                                    //
+//////////////////////////////////////////////////////////////////////////////
+
+type LogShowReq struct {
+	NmpBase
+	Name      string `codec:"log_name"`
+	Timestamp int64  `codec:"ts"`
+	Index     uint32 `codec:"index"`
+}
+
+type LogEntry struct {
+	Index     uint32 `codec:"index"`
+	Timestamp int64  `codec:"ts"`
+	Module    uint8  `codec:"module"`
+	Level     uint8  `codec:"level"`
+	Msg       string `codec:"msg"`
+}
+
+type LogShowLog struct {
+	Name    string     `codec:"name"`
+	Type    int        `codec:"type"`
+	Entries []LogEntry `codec:"entries"`
+}
+
+type LogShowRsp struct {
+	NmpBase
+	Rc        int          `codec:"rc" codec:",omitempty"`
+	NextIndex uint32       `codec:"next_index"`
+	Logs      []LogShowLog `codec:"logs"`
+}
+
+func NewLogShowReq() *LogShowReq {
+	r := &LogShowReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_LOG, NMP_ID_LOG_SHOW)
+	return r
+}
+
+func (r *LogShowReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewLogShowRsp() *LogShowRsp {
+	return &LogShowRsp{}
+}
+
+func (r *LogShowRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $list                                                                    //
+//////////////////////////////////////////////////////////////////////////////
+
+type LogListReq struct {
+	NmpBase
+}
+
+type LogListRsp struct {
+	NmpBase
+	Rc   int      `codec:"rc" codec:",omitempty"`
+	List []string `codec:"log_list"`
+}
+
+func NewLogListReq() *LogListReq {
+	r := &LogListReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_LOG, NMP_ID_LOG_LIST)
+	return r
+}
+
+func (r *LogListReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewLogListRsp() *LogListRsp {
+	return &LogListRsp{}
+}
+
+func (r *LogListRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $module list                                                             //
+//////////////////////////////////////////////////////////////////////////////
+
+type LogModuleListReq struct {
+	NmpBase
+}
+
+type LogModuleListRsp struct {
+	NmpBase
+	Rc  int            `codec:"rc" codec:",omitempty"`
+	Map map[string]int `codec:"module_map"`
+}
+
+func NewLogModuleListReq() *LogModuleListReq {
+	r := &LogModuleListReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_LOG, NMP_ID_LOG_MODULE_LIST)
+	return r
+}
+
+func (r *LogModuleListReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewLogModuleListRsp() *LogModuleListRsp {
+	return &LogModuleListRsp{}
+}
+
+func (r *LogModuleListRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $level list                                                              //
+//////////////////////////////////////////////////////////////////////////////
+
+type LogLevelListReq struct {
+	NmpBase
+}
+
+type LogLevelListRsp struct {
+	NmpBase
+	Rc  int            `codec:"rc" codec:",omitempty"`
+	Map map[string]int `codec:"module_map"`
+}
+
+func NewLogLevelListReq() *LogLevelListReq {
+	r := &LogLevelListReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_LOG, NMP_ID_LOG_LEVEL_LIST)
+	return r
+}
+
+func (r *LogLevelListReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewLogLevelListRsp() *LogLevelListRsp {
+	return &LogLevelListRsp{}
+}
+
+func (r *LogLevelListRsp) Msg() *NmpMsg { return MsgFromReq(r) }
+
+//////////////////////////////////////////////////////////////////////////////
+// $clear                                                                   //
+//////////////////////////////////////////////////////////////////////////////
+
+type LogClearReq struct {
+	NmpBase
+}
+
+type LogClearRsp struct {
+	NmpBase
+	Rc int `codec:"rc" codec:",omitempty"`
+}
+
+func NewLogClearReq() *LogClearReq {
+	r := &LogClearReq{}
+	fillNmpReq(r, NMP_OP_WRITE, NMP_GROUP_LOG, NMP_ID_LOG_CLEAR)
+	return r
+}
+
+func (r *LogClearReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewLogClearRsp() *LogClearRsp {
+	return &LogClearRsp{}
+}
+
+func (r *LogClearRsp) Msg() *NmpMsg { return MsgFromReq(r) }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/15498bdc/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/mpstat.go
----------------------------------------------------------------------
diff --git a/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/mpstat.go b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/mpstat.go
new file mode 100644
index 0000000..f2313e9
--- /dev/null
+++ b/newtmgr/vendor/mynewt.apache.org/newtmgr/nmxact/nmp/mpstat.go
@@ -0,0 +1,46 @@
+/**
+ * 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 nmp
+
+import ()
+
+type MempoolStatReq struct {
+	NmpBase
+}
+
+type MempoolStatRsp struct {
+	NmpBase
+	Rc     int                       `codec:"rc"`
+	Mpools map[string]map[string]int `codec:"mpools"`
+}
+
+func NewMempoolStatReq() *MempoolStatReq {
+	r := &MempoolStatReq{}
+	fillNmpReq(r, NMP_OP_READ, NMP_GROUP_DEFAULT, NMP_ID_DEF_MPSTAT)
+	return r
+}
+
+func (r *MempoolStatReq) Msg() *NmpMsg { return MsgFromReq(r) }
+
+func NewMempoolStatRsp() *MempoolStatRsp {
+	return &MempoolStatRsp{}
+}
+
+func (r *MempoolStatRsp) Msg() *NmpMsg { return MsgFromReq(r) }