/* * Copyright Runtime.io 2018. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Utility functions used by the UART and shell mcumgr transports. * * Mcumgr packets sent over serial are fragmented into frames of 128 bytes or * fewer. * * The initial frame in a packet has the following format: * offset 0: 0x06 0x09 * === Begin base64 encoding === * offset 2: {16-bit packet-length} * offset ?: {body} * offset ?: {crc16} (if final frame) * === End base64 encoding === * offset ?: 0x0a (newline) * * All subsequent frames have the following format: * offset 0: 0x04 0x14 * === Begin base64 encoding === * offset 2: {body} * offset ?: {crc16} (if final frame) * === End base64 encoding === * offset ?: 0x0a (newline) * * All integers are represented in big-endian. The packet fields are described * below: * * | Field | Description | * | -------------- | ------------------------------------------------------- | * | 0x06 0x09 | Byte pair indicating the start of a packet. | * | 0x04 0x14 | Byte pair indicating the start of a continuation frame. | * | Packet length | The combined total length of the *unencoded* body. | * | Body | The actual SMP data (i.e., 8-byte header and CBOR | * | | key-value map). | * | CRC16 | A CRC16 of the *unencoded* body of the entire packet. | * | | This field is only present in the final frame of a | * | | packet. | * | Newline | A 0x0a byte; terminates a frame. | * * The packet is fully received when {packet-length} bytes of body has been * received. * * ## CRC details * * The CRC16 should be calculated with the following parameters: * * | Field | Value | * | ------------- | ------------- | * | Polynomial | 0x1021 | * | Initial Value | 0 | */ #ifndef H_MGMT_SERIAL_ #define H_MGMT_SERIAL_ #include #ifdef __cplusplus extern "C" { #endif #define MCUMGR_SERIAL_HDR_PKT 0x0609 #define MCUMGR_SERIAL_HDR_FRAG 0x0414 #define MCUMGR_SERIAL_MAX_FRAME 128 #define MCUMGR_SERIAL_HDR_PKT_1 (MCUMGR_SERIAL_HDR_PKT >> 8) #define MCUMGR_SERIAL_HDR_PKT_2 (MCUMGR_SERIAL_HDR_PKT & 0xff) #define MCUMGR_SERIAL_HDR_FRAG_1 (MCUMGR_SERIAL_HDR_FRAG >> 8) #define MCUMGR_SERIAL_HDR_FRAG_2 (MCUMGR_SERIAL_HDR_FRAG & 0xff) /** * @brief Maintains state for an incoming mcumgr request packet. */ struct mcumgr_serial_rx_ctxt { /* Contains the partially- or fully-received mcumgr request. Data * stored in this buffer has already been base64-decoded. */ struct net_buf *nb; /* Length of full packet, as read from header. */ u16_t pkt_len; }; /** @typedef mcumgr_serial_tx_cb * @brief Transmits a chunk of raw response data. * * @param data The data to transmit. * @param len The number of bytes to transmit. * @param arg An optional argument. * * @return 0 on success; negative error code on failure. */ typedef int (*mcumgr_serial_tx_cb)(const void *data, int len, void *arg); /** * @brief Processes an mcumgr request fragment received over a serial * transport. * * Processes an mcumgr request fragment received over a serial transport. If * the fragment is the end of a valid mcumgr request, this function returns a * net_buf containing the decoded request. It is the caller's responsibility * to free the net_buf after it has been processed. * * @param rx_ctxt The receive context associated with the serial * transport being used. * @param frag The incoming fragment to process. * @param frag_len The length of the fragment, in bytes. * * @return A net_buf containing the decoded request if a * complete and valid request has been * received. * NULL if the packet is incomplete or invalid. */ struct net_buf *mcumgr_serial_process_frag( struct mcumgr_serial_rx_ctxt *rx_ctxt, const u8_t *frag, int frag_len); /** * @brief Encodes and transmits an mcumgr packet over serial. * * @param data The mcumgr packet data to send. * @param len The length of the unencoded mcumgr packet. * @param cb A callback used to transmit raw bytes. * @param arg An optional argument to pass to the callback. * * @return 0 on success; negative error code on failure. */ int mcumgr_serial_tx_pkt(const u8_t *data, int len, mcumgr_serial_tx_cb cb, void *arg); #ifdef __cplusplus } #endif #endif