func crashRunCmd(cmd *cobra.Command, args []string) { cpm, err := config.NewConnProfileMgr() if err != nil { nmUsage(cmd, err) } if len(args) != 1 { nmUsage(cmd, nil) } crashType := args[0] profile, err := cpm.GetConnProfile(ConnProfileName) if err != nil { nmUsage(cmd, err) } conn, err := transport.NewConnWithTimeout(profile, time.Second*1) if err != nil { nmUsage(cmd, err) } defer conn.Close() runner, err := protocol.NewCmdRunner(conn) if err != nil { nmUsage(cmd, err) } crash, err := protocol.NewCrash(crashType) if err != nil { nmUsage(cmd, err) } nmr, err := crash.EncodeWriteRequest() if err != nil { nmUsage(cmd, err) } if err := runner.WriteReq(nmr); err != nil { nmUsage(cmd, err) } rsp, err := runner.ReadResp() if err == nil { cRsp, err := protocol.DecodeCrashResponse(rsp.Data) if err != nil { nmUsage(cmd, err) } if cRsp.Err != 0 { fmt.Printf("Failed, error:%d\n", cRsp.Err) } } fmt.Println("Done") }
func getTargetCmdRunner() (*protocol.CmdRunner, error) { cpm, err := config.NewConnProfileMgr() if err != nil { return nil, err } profile, err := cpm.GetConnProfile(ConnProfileName) if err != nil { return nil, err } conn, err := transport.NewConn(profile) if err != nil { return nil, err } runner, err := protocol.NewCmdRunner(conn) if err != nil { return nil, err } return runner, nil }
func imageUploadCmd(cmd *cobra.Command, args []string) { if len(args) < 1 { nmUsage(cmd, util.NewNewtError("Need to specify image to upload")) } imageFile, err := ioutil.ReadFile(args[0]) if err != nil { nmUsage(cmd, util.NewNewtError(err.Error())) } cpm, err := config.NewConnProfileMgr() if err != nil { nmUsage(cmd, err) } profile, err := cpm.GetConnProfile(ConnProfileName) if err != nil { nmUsage(cmd, err) } conn, err := transport.NewConnWithTimeout(profile, time.Second*16) if err != nil { nmUsage(nil, err) } defer conn.Close() runner, err := protocol.NewCmdRunner(conn) if err != nil { nmUsage(cmd, err) } if profile.Type() == "serial" { err = echoCtrl(runner, "0") if err != nil { nmUsage(cmd, err) } defer echoCtrl(runner, "1") } var currOff uint32 = 0 var mtu uint32 = 0 imageSz := uint32(len(imageFile)) rexmits := 0 if profile.Type() == "ble" { mtu = uint32((transport.BleMTU - 64) * 3 / 4) } else { /* since this possibly gets base 64 encoded, we want * to ensure that the payload leaving this layer is 91 * bytes or less (91 bytes plus 2 byte crc will encode * to 124 with 4 bytes of header * left over */ /* 00000000 02 00 00 4f 00 01 00 01 a2 64 64 61 74 61 58 40 |...O.....ddataX@| * 00000010 00 f0 5a f8 0e 4b 1c 70 0e 4b 5a 88 12 05 10 0f |..Z..K.p.KZ.....| * 00000020 59 88 0d 4a 0a 40 5a 80 59 88 0c 4a 0a 40 5a 80 |[email protected].@Z.| * 00000030 19 1c 80 22 d2 01 4b 88 13 42 fc d1 05 49 02 02 |..."..K..B...I..| * 00000040 48 88 05 4b 03 40 13 43 4b 80 00 f0 5d f8 10 bd |[email protected]...]...| * 00000050 63 6f 66 66 1a 00 01 5d b8 |coff..x| */ /* from this dump we can see the following * 1) newtmgr hdr 8 bytes * 2) cbor wrapper up to data (and length) 8 bytes * 3) cbor data 64 bytes * 4) offset tag 4 bytes * 5) offsert value 3 (safely say 5 bytes since it could be bigger * than uint16_t * That makes 25 bytes plus the data needs to fit in 91 bytes */ /* however, something is not calcualated properly as we * can only do 66 bytes here. Use 64 for power of 2 */ mtu = 64 } for currOff < imageSz { imageUpload, err := protocol.NewImageUpload() if err != nil { echoOnNmUsage(runner, err, cmd) } blockSz := imageSz - currOff if blockSz > mtu { blockSz = mtu } if currOff == 0 { /* we need extra space to encode the image size */ if blockSz > (mtu - 8) { /* * to encode the image size, we write clen=val in CBOR. * From below (for up to 2G images, you can see that it * will take up to 9 bytes. (starts at 63.. ends at e8) * 00000040 7d c4 00 00 7d c4 00 00 63 6c 65 6e 1a 00 01 5d |}...}...clen...]| * 00000050 e8 63 6f 66 66 00 |.coff.| * However, since the offset is zero, we will use less * bytes (we budgeted for 5 bytes but will only use 1 */ /* to make these powers of 2, just go with 8 bytes */ blockSz = mtu - 8 } } imageUpload.Offset = currOff imageUpload.Size = imageSz imageUpload.Data = imageFile[currOff : currOff+blockSz] nmr, err := imageUpload.EncodeWriteRequest() if err != nil { echoOnNmUsage(runner, err, cmd) } var rsp *protocol.NmgrReq var i int for i = 0; i < 5; i++ { if err := runner.WriteReq(nmr); err != nil { echoOnNmUsage(runner, err, cmd) } rsp, err = runner.ReadResp() if err == nil { break } /* * Failed. Reopening tty. */ conn, err = transport.NewConnWithTimeout(profile, time.Second) if err != nil { echoOnNmUsage(runner, err, cmd) } runner, err = protocol.NewCmdRunner(conn) if err != nil { echoOnNmUsage(runner, err, cmd) } } rexmits += i if i == 5 { err = util.NewNewtError("Maximum number of TX retries reached") } if err != nil { echoOnNmUsage(runner, err, cmd) } ersp, err := protocol.DecodeImageUploadResponse(rsp.Data) if err != nil { echoOnNmUsage(runner, err, nil) } currOff = ersp.Offset fmt.Println(currOff) } if rexmits != 0 { fmt.Printf(" %d retransmits\n", rexmits) } fmt.Println("Done") }