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/07 20:14:24 UTC
[mynewt-newtmgr] 02/06: newtmgr - "res" command
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 566e56c0243ba504918c0156b648c13f841be726
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Fri Aug 4 17:32:10 2017 -0700
newtmgr - "res" command
Get or set a CoAP resource.
---
newtmgr/bll/bll_oic_sesn.go | 36 ++++++++++++++++++++++-
newtmgr/cli/commands.go | 2 +-
newtmgr/cli/res.go | 40 ++++++++++++++++++++++----
nmxact/bledefs/bledefs.go | 16 +++++++----
nmxact/example/ble_adv/ble_adv | Bin 14030132 -> 14030132 bytes
nmxact/nmble/ble_sesn.go | 29 ++++++++++++++++---
nmxact/nmble/ble_util.go | 16 ++++++++++-
nmxact/nmble/temp.go | 7 +++--
nmxact/oic/oic.go | 64 +++++++++++++++++++++++++++++++++++------
nmxact/oic/resmgr.go | 17 ++++-------
nmxact/sesn/sesn_util.go | 20 ++++++++-----
nmxact/xact/res.go | 4 +--
12 files changed, 200 insertions(+), 51 deletions(-)
diff --git a/newtmgr/bll/bll_oic_sesn.go b/newtmgr/bll/bll_oic_sesn.go
index 2cb141d..e813967 100644
--- a/newtmgr/bll/bll_oic_sesn.go
+++ b/newtmgr/bll/bll_oic_sesn.go
@@ -405,5 +405,39 @@ func (bls *BllOicSesn) GetResourceOnce(resType sesn.ResourceType, uri string,
func (bls *BllOicSesn) PutResourceOnce(resType sesn.ResourceType,
uri string, value []byte, opt sesn.TxOptions) (coap.COAPCode, error) {
- return 0, fmt.Errorf("BllOicSesn.PutResourceOnce() unsupported")
+ chr, err := bls.resReqChr(resType)
+ if err != nil {
+ return 0, err
+ }
+
+ token := nmxutil.NextToken()
+
+ ol, err := bls.d.AddOicListener(token)
+ if err != nil {
+ return 0, err
+ }
+ defer bls.d.RemoveOicListener(token)
+
+ req, err := oic.EncodePut(true, uri, token, value)
+ if err != nil {
+ return 0, err
+ }
+
+ // Send request.
+ if err := bls.cln.WriteCharacteristic(chr, req, true); err != nil {
+ return 0, err
+ }
+
+ // Now wait for CoAP response.
+ for {
+ select {
+ case err := <-ol.ErrChan:
+ return 0, err
+ case rsp := <-ol.RspChan:
+ return rsp.Code(), nil
+ case <-ol.AfterTimeout(opt.Timeout):
+ msg := fmt.Sprintf("CoAP timeout; uri=%s", uri)
+ return 0, nmxutil.NewRspTimeoutError(msg)
+ }
+ }
}
diff --git a/newtmgr/cli/commands.go b/newtmgr/cli/commands.go
index 41a9120..cde0416 100644
--- a/newtmgr/cli/commands.go
+++ b/newtmgr/cli/commands.go
@@ -81,7 +81,7 @@ func Commands() *cobra.Command {
nmCmd.AddCommand(configCmd())
nmCmd.AddCommand(connProfileCmd())
nmCmd.AddCommand(echoCmd())
- nmCmd.AddCommand(getResCmd())
+ nmCmd.AddCommand(resCmd())
return nmCmd
}
diff --git a/newtmgr/cli/res.go b/newtmgr/cli/res.go
index 5192645..560b30c 100644
--- a/newtmgr/cli/res.go
+++ b/newtmgr/cli/res.go
@@ -20,13 +20,16 @@
package cli
import (
+ "encoding/hex"
"fmt"
"strings"
+ "github.com/runtimeco/go-coap"
"github.com/spf13/cobra"
"mynewt.apache.org/newt/util"
"mynewt.apache.org/newtmgr/newtmgr/nmutil"
+ "mynewt.apache.org/newtmgr/nmxact/nmxutil"
"mynewt.apache.org/newtmgr/nmxact/sesn"
"mynewt.apache.org/newtmgr/nmxact/xact"
)
@@ -61,20 +64,44 @@ func resGetRunCmd(s sesn.Sesn, resType sesn.ResourceType, uri string) {
sres := res.(*xact.GetResResult)
if sres.Status() != 0 {
- fmt.Printf("Error: %d\n", sres.Status())
+ fmt.Printf("Error: %s (%d)\n",
+ coap.COAPCode(sres.Status()), sres.Status())
+ return
+ }
+
+ var valstr string
+
+ m, err := nmxutil.DecodeCborMap(sres.Value)
+ if err != nil {
+ valstr = hex.Dump(sres.Value)
+ } else if len(m) == 0 {
+ valstr = "<empty>"
+ } else if len(m) == 1 {
+ for k, v := range m {
+ valstr = fmt.Sprintf("%s=%+v", k, v)
+ }
} else {
- fmt.Printf("%s: %+v\n", uri, sres.Value)
+ for k, v := range m {
+ valstr += fmt.Sprintf("\n %s=%+v", k, v)
+ }
}
+
+ fmt.Printf("%s: %s\n", uri, valstr)
}
func resPutRunCmd(s sesn.Sesn, resType sesn.ResourceType, uri string,
value map[string]interface{}) {
+ b, err := nmxutil.EncodeCborMap(value)
+ if err != nil {
+ nmUsage(nil, util.ChildNewtError(err))
+ }
+
c := xact.NewPutResCmd()
c.SetTxOptions(nmutil.TxOptions())
c.Uri = uri
c.Typ = resType
- c.Value = value
+ c.Value = b
res, err := c.Run(s)
if err != nil {
@@ -83,14 +110,15 @@ func resPutRunCmd(s sesn.Sesn, resType sesn.ResourceType, uri string,
sres := res.(*xact.PutResResult)
if sres.Status() != 0 {
- fmt.Printf("Error: %d\n", sres.Status())
+ fmt.Printf("Error: %s (%d)\n",
+ coap.COAPCode(sres.Status()), sres.Status())
} else {
fmt.Printf("Done\n")
}
}
func resRunCmd(cmd *cobra.Command, args []string) {
- if len(args) != 2 {
+ if len(args) < 2 {
nmUsage(cmd, nil)
}
@@ -121,7 +149,7 @@ func resRunCmd(cmd *cobra.Command, args []string) {
}
}
-func getResCmd() *cobra.Command {
+func resCmd() *cobra.Command {
resEx := " newtmgr -c olimex res public mynewt.value.0\n"
resCmd := &cobra.Command{
diff --git a/nmxact/bledefs/bledefs.go b/nmxact/bledefs/bledefs.go
index d19d7e9..8a243ef 100644
--- a/nmxact/bledefs/bledefs.go
+++ b/nmxact/bledefs/bledefs.go
@@ -809,13 +809,17 @@ type BleChrId struct {
ChrUuid BleUuid
}
+func (b *BleChrId) String() string {
+ return fmt.Sprintf("s=%s c=%s", b.SvcUuid.String(), b.ChrUuid.String())
+}
+
type BleMgmtChrs struct {
- NmpReqChr *BleChrId
- NmpRspChr *BleChrId
- ResPublicReqChr *BleChrId
- ResPublicRspChr *BleChrId
- ResUnauthReqChr *BleChrId
- ResUnauthRspChr *BleChrId
+ NmpReqChr *BleChrId
+ NmpRspChr *BleChrId
+ ResPublicReqChr *BleChrId
+ ResPublicRspChr *BleChrId
+ ResUnauthReqChr *BleChrId
+ ResUnauthRspChr *BleChrId
ResSecureReqChr *BleChrId
ResSecureRspChr *BleChrId
}
diff --git a/nmxact/example/ble_adv/ble_adv b/nmxact/example/ble_adv/ble_adv
index d57f915..d1fcdab 100755
Binary files a/nmxact/example/ble_adv/ble_adv and b/nmxact/example/ble_adv/ble_adv differ
diff --git a/nmxact/nmble/ble_sesn.go b/nmxact/nmble/ble_sesn.go
index 63e0d96..6d9c889 100644
--- a/nmxact/nmble/ble_sesn.go
+++ b/nmxact/nmble/ble_sesn.go
@@ -117,7 +117,7 @@ func (s *BleSesn) getChr(chrId *BleChrId) (*Characteristic, error) {
chr := s.conn.Profile().FindChrByUuid(*chrId)
if chr == nil {
return nil, fmt.Errorf("BLE peer doesn't support required "+
- "characteristic: %s", *chrId)
+ "characteristic: %s", chrId.String())
}
return chr, nil
@@ -323,14 +323,14 @@ func (s *BleSesn) GetResourceOnce(resType sesn.ResourceType, uri string,
return 0, nil, err
}
- chrId := ResChrIdLookup(s.mgmtChrs, resType)
+ chrId := ResChrReqIdLookup(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")
+ return s.conn.WriteChrNoRsp(chr, b, "oic-get")
}
rsp, err := s.txvr.TxOic(txRaw, req, opt.Timeout)
@@ -344,5 +344,26 @@ func (s *BleSesn) GetResourceOnce(resType sesn.ResourceType, uri string,
func (s *BleSesn) PutResourceOnce(resType sesn.ResourceType,
uri string, value []byte, opt sesn.TxOptions) (coap.COAPCode, error) {
- return 0, fmt.Errorf("SerialPlainSesn.PutResourceOnce() unsupported")
+ token := nmxutil.NextToken()
+ req, err := oic.CreatePut(true, uri, token, value)
+ if err != nil {
+ return 0, err
+ }
+
+ chrId := ResChrReqIdLookup(s.mgmtChrs, resType)
+ chr, err := s.getChr(chrId)
+ if err != nil {
+ return 0, err
+ }
+
+ txRaw := func(b []byte) error {
+ return s.conn.WriteChrNoRsp(chr, b, "oic-put")
+ }
+
+ rsp, err := s.txvr.TxOic(txRaw, req, opt.Timeout)
+ if err != nil {
+ return 0, err
+ }
+
+ return rsp.Code(), nil
}
diff --git a/nmxact/nmble/ble_util.go b/nmxact/nmble/ble_util.go
index 7d5b316..0f530e3 100644
--- a/nmxact/nmble/ble_util.go
+++ b/nmxact/nmble/ble_util.go
@@ -713,7 +713,9 @@ func GenCoapService(x *BleXport, svcUuid BleUuid, reqChrUuid BleUuid,
return svc, nil
}
-func ResChrIdLookup(mgmtChrs BleMgmtChrs, resType sesn.ResourceType) *BleChrId {
+func ResChrReqIdLookup(mgmtChrs BleMgmtChrs,
+ resType sesn.ResourceType) *BleChrId {
+
m := map[sesn.ResourceType]*BleChrId{
sesn.RES_TYPE_PUBLIC: mgmtChrs.ResPublicReqChr,
sesn.RES_TYPE_UNAUTH: mgmtChrs.ResUnauthReqChr,
@@ -723,6 +725,18 @@ func ResChrIdLookup(mgmtChrs BleMgmtChrs, resType sesn.ResourceType) *BleChrId {
return m[resType]
}
+func ResChrRspIdLookup(mgmtChrs BleMgmtChrs,
+ resType sesn.ResourceType) *BleChrId {
+
+ m := map[sesn.ResourceType]*BleChrId{
+ sesn.RES_TYPE_PUBLIC: mgmtChrs.ResPublicRspChr,
+ sesn.RES_TYPE_UNAUTH: mgmtChrs.ResUnauthRspChr,
+ sesn.RES_TYPE_SECURE: mgmtChrs.ResSecureRspChr,
+ }
+
+ return m[resType]
+}
+
func BuildMgmtChrs(mgmtProto sesn.MgmtProto) (BleMgmtChrs, error) {
mgmtChrs := BleMgmtChrs{}
diff --git a/nmxact/nmble/temp.go b/nmxact/nmble/temp.go
index 2c19fb5..b7371cf 100644
--- a/nmxact/nmble/temp.go
+++ b/nmxact/nmble/temp.go
@@ -16,8 +16,11 @@ func GwService(x *BleXport) (BleSvc, error) {
resources := []oic.Resource{
oic.NewFixedResource(
"mynewt.yourmom",
- map[string]interface{}{"yourmom": "fat"},
- func(val map[string]interface{}) coap.COAPCode {
+ map[string]interface{}{
+ "yourmom": "fat",
+ "yourmomsmom": "hella fat",
+ },
+ func(uri string, val map[string]interface{}) coap.COAPCode {
return coap.Changed
},
)}
diff --git a/nmxact/oic/oic.go b/nmxact/oic/oic.go
index f5052ed..285600a 100644
--- a/nmxact/oic/oic.go
+++ b/nmxact/oic/oic.go
@@ -38,6 +38,22 @@ func NextMessageId() uint16 {
return id
}
+func validateToken(t []byte) error {
+ if len(t) > 8 {
+ return fmt.Errorf("Invalid token; len=%d, must be <= 8", len(t))
+ }
+
+ return nil
+}
+
+func buildMessage(isTcp bool, p coap.MessageParams) coap.Message {
+ if isTcp {
+ return coap.NewTcpMessage(p)
+ } else {
+ return coap.NewDgramMessage(p)
+ }
+}
+
func Encode(m coap.Message) ([]byte, error) {
b, err := m.MarshalBinary()
if err != nil {
@@ -48,9 +64,8 @@ func Encode(m coap.Message) ([]byte, error) {
}
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))
+ if err := validateToken(token); err != nil {
+ return nil, err
}
p := coap.MessageParams{
@@ -59,12 +74,7 @@ func CreateGet(isTcp bool, resUri string, token []byte) (coap.Message, error) {
Token: token,
}
- var m coap.Message
- if isTcp {
- m = coap.NewTcpMessage(p)
- } else {
- m = coap.NewDgramMessage(p)
- }
+ m := buildMessage(isTcp, p)
m.SetPathString(resUri)
return m, nil
@@ -83,3 +93,39 @@ func EncodeGet(isTcp bool, resUri string, token []byte) ([]byte, error) {
return b, nil
}
+
+func CreatePut(isTcp bool, resUri string, token []byte,
+ val []byte) (coap.Message, error) {
+
+ if err := validateToken(token); err != nil {
+ return nil, err
+ }
+
+ p := coap.MessageParams{
+ Type: coap.Confirmable,
+ Code: coap.PUT,
+ Token: token,
+ Payload: val,
+ }
+
+ m := buildMessage(isTcp, p)
+ m.SetPathString(resUri)
+
+ return m, nil
+}
+
+func EncodePut(isTcp bool, resUri string, token []byte, val []byte) (
+ []byte, error) {
+
+ m, err := CreatePut(isTcp, resUri, token, val)
+ if err != nil {
+ return nil, err
+ }
+
+ b, err := Encode(m)
+ if err != nil {
+ return nil, err
+ }
+
+ return b, nil
+}
diff --git a/nmxact/oic/resmgr.go b/nmxact/oic/resmgr.go
index c6d9e6d..f715f13 100644
--- a/nmxact/oic/resmgr.go
+++ b/nmxact/oic/resmgr.go
@@ -38,12 +38,7 @@ func (rm *ResMgr) Add(r Resource) error {
}
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]
+ path := m.PathString()
r, ok := rm.uriResMap[path]
if !ok {
@@ -73,7 +68,8 @@ func (rm *ResMgr) Access(m coap.Message) (coap.COAPCode, []byte) {
}
}
-type FixedResourceWriteFn func(val map[string]interface{}) coap.COAPCode
+type FixedResourceWriteFn func(uri string,
+ val map[string]interface{}) coap.COAPCode
func NewFixedResource(uri string, val map[string]interface{},
writeCb FixedResourceWriteFn) Resource {
@@ -95,11 +91,8 @@ func NewFixedResource(uri string, val map[string]interface{},
return coap.BadRequest
}
- code := writeCb(m)
- if code == coap.Created ||
- code == coap.Deleted ||
- code == coap.Changed {
-
+ code := writeCb(uri, m)
+ if code == coap.Created || code == coap.Changed {
val = m
}
return code
diff --git a/nmxact/sesn/sesn_util.go b/nmxact/sesn/sesn_util.go
index a66aed6..b38634c 100644
--- a/nmxact/sesn/sesn_util.go
+++ b/nmxact/sesn/sesn_util.go
@@ -57,16 +57,11 @@ func GetResource(s Sesn, resType ResourceType, uri string, o TxOptions) (
}
func PutResource(s Sesn, resType ResourceType, uri string,
- value map[string]interface{}, o TxOptions) (coap.COAPCode, error) {
-
- b, err := nmxutil.EncodeCborMap(value)
- if err != nil {
- return 0, err
- }
+ value []byte, o TxOptions) (coap.COAPCode, error) {
retries := o.Tries - 1
for i := 0; ; i++ {
- code, err := s.PutResourceOnce(resType, uri, b, o)
+ code, err := s.PutResourceOnce(resType, uri, value, o)
if err == nil {
return code, nil
}
@@ -76,3 +71,14 @@ func PutResource(s Sesn, resType ResourceType, uri string,
}
}
}
+
+func PutCborResource(s Sesn, resType ResourceType, uri string,
+ value map[string]interface{}, o TxOptions) (coap.COAPCode, error) {
+
+ b, err := nmxutil.EncodeCborMap(value)
+ if err != nil {
+ return 0, err
+ }
+
+ return PutResource(s, resType, uri, b, o)
+}
diff --git a/nmxact/xact/res.go b/nmxact/xact/res.go
index 6cfa47e..4c0ffd5 100644
--- a/nmxact/xact/res.go
+++ b/nmxact/xact/res.go
@@ -70,7 +70,7 @@ type PutResCmd struct {
CmdBase
Uri string
Typ sesn.ResourceType
- Value map[string]interface{}
+ Value []byte
}
func NewPutResCmd() *PutResCmd {
@@ -88,7 +88,7 @@ func newPutResResult() *PutResResult {
}
func (r *PutResResult) Status() int {
- if r.Code == coap.Content {
+ if r.Code == coap.Created || r.Code == coap.Changed {
return 0
} else {
return int(r.Code)
--
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.