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) }
