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 <ccoll...@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" <commits@mynewt.apache.org>.