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 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")
}