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