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/18 02:02:08 UTC

[mynewt-newtmgr] 03/04: newtmgr - Support for CoAP POST and DELETE

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 1af0b3ef25bc69726c0fa7c5309cf21b73f4a430
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Thu Aug 17 18:38:42 2017 -0700

    newtmgr - Support for CoAP POST and DELETE
---
 newtmgr/cli/res.go       | 206 ++++++++++++++++++++++++++++++++++++++---------
 nmxact/sesn/sesn_util.go |   2 +-
 nmxact/xact/res.go       | 101 +++++++++++++++++++++--
 3 files changed, 262 insertions(+), 47 deletions(-)

diff --git a/newtmgr/cli/res.go b/newtmgr/cli/res.go
index 0e1c771..c1fd5a7 100644
--- a/newtmgr/cli/res.go
+++ b/newtmgr/cli/res.go
@@ -51,7 +51,7 @@ func cborValStr(itf interface{}) string {
 		return v
 
 	case []byte:
-		return hex.Dump(v)
+		return strings.TrimSuffix(hex.Dump(v), "\n")
 
 	default:
 		return fmt.Sprintf("%#v", v)
@@ -75,11 +75,44 @@ func extractResKv(params []string) (map[string]interface{}, error) {
 	return m, nil
 }
 
-func resGetRunCmd(s sesn.Sesn, resType sesn.ResourceType, uri string) {
+func resResponseStr(path string, cbor []byte) string {
+	s := path
+
+	m, err := nmxutil.DecodeCborMap(cbor)
+	if err != nil {
+		s += fmt.Sprintf("\n    invalid incoming cbor:\n%s", hex.Dump(cbor))
+	} else if len(m) == 0 {
+		s += "\n    <empty>"
+	} else {
+		for k, v := range m {
+			s += fmt.Sprintf("\n    %s\n%s", k, indent(cborValStr(v), 8))
+		}
+	}
+
+	return s
+}
+
+func resGetCmd(cmd *cobra.Command, args []string) {
+	if len(args) < 2 {
+		nmUsage(cmd, nil)
+	}
+
+	s, err := GetSesn()
+	if err != nil {
+		nmUsage(nil, err)
+	}
+
+	rt, err := sesn.ParseResType(args[0])
+	if err != nil {
+		nmUsage(cmd, err)
+	}
+
+	path := args[1]
+
 	c := xact.NewGetResCmd()
 	c.SetTxOptions(nmutil.TxOptions())
-	c.Uri = uri
-	c.Typ = resType
+	c.Path = path
+	c.Typ = rt
 
 	res, err := c.Run(s)
 	if err != nil {
@@ -93,34 +126,43 @@ func resGetRunCmd(s sesn.Sesn, resType sesn.ResourceType, uri string) {
 		return
 	}
 
-	var valstr string
+	if sres.Value != nil {
+		fmt.Printf("%s\n", resResponseStr(c.Path, sres.Value))
+	}
+}
 
-	m, err := nmxutil.DecodeCborMap(sres.Value)
+func resPutCmd(cmd *cobra.Command, args []string) {
+	if len(args) < 3 {
+		nmUsage(cmd, nil)
+	}
+
+	s, err := GetSesn()
 	if err != nil {
-		valstr = hex.Dump(sres.Value)
-	} else if len(m) == 0 {
-		valstr = "<empty>"
-	} else {
-		for k, v := range m {
-			valstr += fmt.Sprintf("\n    %s\n%s", k, indent(cborValStr(v), 8))
-		}
+		nmUsage(nil, err)
 	}
 
-	fmt.Printf("%s%s\n", uri, valstr)
-}
+	rt, err := sesn.ParseResType(args[0])
+	if err != nil {
+		nmUsage(cmd, err)
+	}
 
-func resPutRunCmd(s sesn.Sesn, resType sesn.ResourceType, uri string,
-	value map[string]interface{}) {
+	path := args[1]
 
-	b, err := nmxutil.EncodeCborMap(value)
+	var m map[string]interface{}
+	m, err = extractResKv(args[2:])
+	if err != nil {
+		nmUsage(cmd, err)
+	}
+
+	b, err := nmxutil.EncodeCborMap(m)
 	if err != nil {
 		nmUsage(nil, util.ChildNewtError(err))
 	}
 
 	c := xact.NewPutResCmd()
 	c.SetTxOptions(nmutil.TxOptions())
-	c.Uri = uri
-	c.Typ = resType
+	c.Path = path
+	c.Typ = rt
 	c.Value = b
 
 	res, err := c.Run(s)
@@ -132,29 +174,68 @@ func resPutRunCmd(s sesn.Sesn, resType sesn.ResourceType, uri string,
 	if sres.Status() != 0 {
 		fmt.Printf("Error: %s (%d)\n",
 			coap.COAPCode(sres.Status()), sres.Status())
-	} else {
-		fmt.Printf("Done\n")
+		return
+	}
+
+	if sres.Value != nil {
+		fmt.Printf("%s\n", resResponseStr(c.Path, sres.Value))
 	}
 }
 
-func resRunCmd(cmd *cobra.Command, args []string) {
-	if len(args) < 2 {
+func resPostCmd(cmd *cobra.Command, args []string) {
+	if len(args) < 3 {
 		nmUsage(cmd, nil)
 	}
 
+	s, err := GetSesn()
+	if err != nil {
+		nmUsage(nil, err)
+	}
+
 	rt, err := sesn.ParseResType(args[0])
 	if err != nil {
 		nmUsage(cmd, err)
 	}
 
-	uri := args[1]
+	path := args[1]
 
 	var m map[string]interface{}
-	if len(args) >= 3 {
-		m, err = extractResKv(args[2:])
-		if err != nil {
-			nmUsage(cmd, err)
-		}
+	m, err = extractResKv(args[2:])
+	if err != nil {
+		nmUsage(cmd, err)
+	}
+
+	b, err := nmxutil.EncodeCborMap(m)
+	if err != nil {
+		nmUsage(nil, util.ChildNewtError(err))
+	}
+
+	c := xact.NewPostResCmd()
+	c.SetTxOptions(nmutil.TxOptions())
+	c.Path = path
+	c.Typ = rt
+	c.Value = b
+
+	res, err := c.Run(s)
+	if err != nil {
+		nmUsage(nil, util.ChildNewtError(err))
+	}
+
+	sres := res.(*xact.PostResResult)
+	if sres.Status() != 0 {
+		fmt.Printf("Error: %s (%d)\n",
+			coap.COAPCode(sres.Status()), sres.Status())
+		return
+	}
+
+	if sres.Value != nil {
+		fmt.Printf("%s\n", resResponseStr(c.Path, sres.Value))
+	}
+}
+
+func resDeleteCmd(cmd *cobra.Command, args []string) {
+	if len(args) < 2 {
+		nmUsage(cmd, nil)
 	}
 
 	s, err := GetSesn()
@@ -162,22 +243,67 @@ func resRunCmd(cmd *cobra.Command, args []string) {
 		nmUsage(nil, err)
 	}
 
-	if m == nil {
-		resGetRunCmd(s, rt, uri)
-	} else {
-		resPutRunCmd(s, rt, uri, m)
+	rt, err := sesn.ParseResType(args[0])
+	if err != nil {
+		nmUsage(cmd, err)
+	}
+
+	path := args[1]
+
+	c := xact.NewDeleteResCmd()
+	c.SetTxOptions(nmutil.TxOptions())
+	c.Path = path
+	c.Typ = rt
+
+	res, err := c.Run(s)
+	if err != nil {
+		nmUsage(nil, util.ChildNewtError(err))
+	}
+
+	sres := res.(*xact.DeleteResResult)
+	if sres.Status() != 0 {
+		fmt.Printf("Error: %s (%d)\n",
+			coap.COAPCode(sres.Status()), sres.Status())
+		return
+	}
+
+	if sres.Value != nil {
+		fmt.Printf("%s\n", resResponseStr(c.Path, sres.Value))
 	}
 }
 
 func resCmd() *cobra.Command {
-	resEx := "   newtmgr -c olimex res public /dev\n"
-
 	resCmd := &cobra.Command{
-		Use:     "res <type> <uri> [k=v] [k=v] [...]",
-		Short:   "Read or write a CoAP resource on a device",
-		Example: resEx,
-		Run:     resRunCmd,
+		Use:   "res",
+		Short: "Access a CoAP resource on a device",
+		Run: func(cmd *cobra.Command, args []string) {
+			cmd.HelpFunc()(cmd, args)
+		},
 	}
 
+	resCmd.AddCommand(&cobra.Command{
+		Use:   "get <type> <path>",
+		Short: "Send a CoAP GET request",
+		Run:   resGetCmd,
+	})
+
+	resCmd.AddCommand(&cobra.Command{
+		Use:   "put <type> <path> <k=v> [k=v] [k=v]",
+		Short: "Send a CoAP PUT request",
+		Run:   resPutCmd,
+	})
+
+	resCmd.AddCommand(&cobra.Command{
+		Use:   "post <type> <path> <k=v> [k=v] [k=v]",
+		Short: "Send a CoAP POST request",
+		Run:   resPostCmd,
+	})
+
+	resCmd.AddCommand(&cobra.Command{
+		Use:   "delete <type> <path>",
+		Short: "Send a CoAP DELETE request",
+		Run:   resDeleteCmd,
+	})
+
 	return resCmd
 }
diff --git a/nmxact/sesn/sesn_util.go b/nmxact/sesn/sesn_util.go
index f7b38c2..26eec86 100644
--- a/nmxact/sesn/sesn_util.go
+++ b/nmxact/sesn/sesn_util.go
@@ -128,7 +128,7 @@ func PostResource(s Sesn, resType ResourceType, uri string,
 }
 
 func DeleteResource(s Sesn, resType ResourceType, uri string,
-	value []byte, o TxOptions) (coap.COAPCode, []byte, error) {
+	o TxOptions) (coap.COAPCode, []byte, error) {
 
 	return txCoap(func() (coap.COAPCode, []byte, error) {
 		return deleteResourceOnce(s, resType, uri, o)
diff --git a/nmxact/xact/res.go b/nmxact/xact/res.go
index c9fec2f..f54614a 100644
--- a/nmxact/xact/res.go
+++ b/nmxact/xact/res.go
@@ -27,8 +27,8 @@ import (
 
 type GetResCmd struct {
 	CmdBase
-	Uri string
-	Typ sesn.ResourceType
+	Path string
+	Typ  sesn.ResourceType
 }
 
 func NewGetResCmd() *GetResCmd {
@@ -55,7 +55,7 @@ func (r *GetResResult) Status() int {
 }
 
 func (c *GetResCmd) Run(s sesn.Sesn) (Result, error) {
-	status, val, err := sesn.GetResource(s, c.Typ, c.Uri, c.TxOptions())
+	status, val, err := sesn.GetResource(s, c.Typ, c.Path, c.TxOptions())
 	if err != nil {
 		return nil, err
 	}
@@ -68,7 +68,7 @@ func (c *GetResCmd) Run(s sesn.Sesn) (Result, error) {
 
 type PutResCmd struct {
 	CmdBase
-	Uri   string
+	Path  string
 	Typ   sesn.ResourceType
 	Value []byte
 }
@@ -89,7 +89,10 @@ func newPutResResult() *PutResResult {
 }
 
 func (r *PutResResult) Status() int {
-	if r.Code == coap.Created || r.Code == coap.Changed || r.Code == coap.Content {
+	if r.Code == coap.Created ||
+		r.Code == coap.Changed ||
+		r.Code == coap.Content {
+
 		return 0
 	} else {
 		return int(r.Code)
@@ -97,7 +100,7 @@ func (r *PutResResult) Status() int {
 }
 
 func (c *PutResCmd) Run(s sesn.Sesn) (Result, error) {
-	status, r, err := sesn.PutResource(s, c.Typ, c.Uri, c.Value, c.TxOptions())
+	status, r, err := sesn.PutResource(s, c.Typ, c.Path, c.Value, c.TxOptions())
 	if err != nil {
 		return nil, err
 	}
@@ -107,3 +110,89 @@ func (c *PutResCmd) Run(s sesn.Sesn) (Result, error) {
 	res.Value = r
 	return res, nil
 }
+
+type PostResCmd struct {
+	CmdBase
+	Path  string
+	Typ   sesn.ResourceType
+	Value []byte
+}
+
+func NewPostResCmd() *PostResCmd {
+	return &PostResCmd{
+		CmdBase: NewCmdBase(),
+	}
+}
+
+type PostResResult struct {
+	Code  coap.COAPCode
+	Value []byte
+}
+
+func newPostResResult() *PostResResult {
+	return &PostResResult{}
+}
+
+func (r *PostResResult) Status() int {
+	if r.Code == coap.Created ||
+		r.Code == coap.Changed ||
+		r.Code == coap.Content {
+
+		return 0
+	} else {
+		return int(r.Code)
+	}
+}
+
+func (c *PostResCmd) Run(s sesn.Sesn) (Result, error) {
+	status, r, err := sesn.PostResource(s, c.Typ, c.Path, c.Value, c.TxOptions())
+	if err != nil {
+		return nil, err
+	}
+
+	res := newPostResResult()
+	res.Code = status
+	res.Value = r
+	return res, nil
+}
+
+type DeleteResCmd struct {
+	CmdBase
+	Path string
+	Typ  sesn.ResourceType
+}
+
+func NewDeleteResCmd() *DeleteResCmd {
+	return &DeleteResCmd{
+		CmdBase: NewCmdBase(),
+	}
+}
+
+type DeleteResResult struct {
+	Code  coap.COAPCode
+	Value []byte
+}
+
+func newDeleteResResult() *DeleteResResult {
+	return &DeleteResResult{}
+}
+
+func (r *DeleteResResult) Status() int {
+	if r.Code == coap.Deleted {
+		return 0
+	} else {
+		return int(r.Code)
+	}
+}
+
+func (c *DeleteResCmd) Run(s sesn.Sesn) (Result, error) {
+	status, val, err := sesn.DeleteResource(s, c.Typ, c.Path, c.TxOptions())
+	if err != nil {
+		return nil, err
+	}
+
+	res := newDeleteResResult()
+	res.Code = status
+	res.Value = val
+	return res, nil
+}

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