Browse Source

mgmt: mcumgr: Fix output packet to frame issue on serial transport

Fixes an issue with outgoing mcumgr frames that are larger than the
transport MTU size whereby they would wrongly be split up into multiple
frames with multiple start frame headers, which affected SMP over
console transports.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
pull/50115/head
Jamie McCrae 3 years ago committed by Fabio Baltieri
parent
commit
c56b45c3e8
  1. 4
      drivers/console/uart_mcumgr.c
  2. 7
      include/zephyr/mgmt/mcumgr/serial.h
  3. 96
      subsys/mgmt/mcumgr/smp.c
  4. 239
      subsys/mgmt/mcumgr/transport/serial_util.c
  5. 86
      subsys/mgmt/mcumgr/transport/smp_bt.c
  6. 42
      subsys/mgmt/mcumgr/transport/smp_dummy.c
  7. 6
      subsys/mgmt/mcumgr/transport/smp_shell.c
  8. 2
      subsys/mgmt/mcumgr/transport/smp_uart.c
  9. 30
      subsys/mgmt/mcumgr/transport/smp_udp.c

4
drivers/console/uart_mcumgr.c

@ -199,7 +199,7 @@ static void uart_mcumgr_isr(const struct device *unused, void *user_data) @@ -199,7 +199,7 @@ static void uart_mcumgr_isr(const struct device *unused, void *user_data)
/**
* Sends raw data over the UART.
*/
static int uart_mcumgr_send_raw(const void *data, int len, void *arg)
static int uart_mcumgr_send_raw(const void *data, int len)
{
const uint8_t *u8p;
@ -213,7 +213,7 @@ static int uart_mcumgr_send_raw(const void *data, int len, void *arg) @@ -213,7 +213,7 @@ static int uart_mcumgr_send_raw(const void *data, int len, void *arg)
int uart_mcumgr_send(const uint8_t *data, int len)
{
return mcumgr_serial_tx_pkt(data, len, uart_mcumgr_send_raw, NULL);
return mcumgr_serial_tx_pkt(data, len, uart_mcumgr_send_raw);
}

7
include/zephyr/mgmt/mcumgr/serial.h

@ -93,11 +93,10 @@ struct mcumgr_serial_rx_ctxt { @@ -93,11 +93,10 @@ struct mcumgr_serial_rx_ctxt {
*
* @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);
typedef int (*mcumgr_serial_tx_cb)(const void *data, int len);
/**
* @brief Processes an mcumgr request fragment received over a serial
@ -128,12 +127,10 @@ struct net_buf *mcumgr_serial_process_frag( @@ -128,12 +127,10 @@ struct net_buf *mcumgr_serial_process_frag(
* @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 uint8_t *data, int len, mcumgr_serial_tx_cb cb,
void *arg);
int mcumgr_serial_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb cb);
#ifdef __cplusplus
}

96
subsys/mgmt/mcumgr/smp.c

@ -71,73 +71,6 @@ void *zephyr_smp_alloc_rsp(const void *req, void *arg) @@ -71,73 +71,6 @@ void *zephyr_smp_alloc_rsp(const void *req, void *arg)
return rsp_nb;
}
/**
* Splits an appropriately-sized fragment from the front of a net_buf, as
* needed. If the length of the net_buf is greater than specified maximum
* fragment size, a new net_buf is allocated, and data is moved from the source
* net_buf to the new net_buf. If the net_buf is small enough to fit in a
* single fragment, the source net_buf is returned unmodified, and the supplied
* pointer is set to NULL.
*
* This function is expected to be called in a loop until the entire source
* net_buf has been consumed. For example:
*
* struct net_buf *frag;
* struct net_buf *rsp;
* ...
* while (rsp != NULL) {
* frag = zephyr_smp_split_frag(&rsp, zst, get_mtu());
* if (frag == NULL) {
* net_buf_unref(nb);
* return SYS_ENOMEM;
* }
* send_packet(frag)
* }
*
* @param nb The packet to fragment. Upon fragmentation,
* this net_buf is adjusted such that the
* fragment data is removed. If the packet
* constitutes a single fragment, this gets
* set to NULL on success.
* @param arg The zephyr SMP transport pointer.
* @param mtu The maximum payload size of a fragment.
*
* @return The next fragment to send on success;
* NULL on failure.
*/
static struct net_buf *
zephyr_smp_split_frag(struct net_buf **nb, void *arg, uint16_t mtu)
{
struct net_buf *frag;
struct net_buf *src;
src = *nb;
if (src->len <= mtu) {
*nb = NULL;
frag = src;
} else {
frag = zephyr_smp_alloc_rsp(src, arg);
if (!frag) {
return NULL;
}
/* Copy fragment payload into new buffer. */
net_buf_add_mem(frag, src->data, mtu);
/* Remove fragment from total response. */
net_buf_pull(src, mtu);
}
return frag;
}
/**
* @brief Frees an allocated buffer.
*
* @param buf The buffer to free.
* @param arg The streamer providing the callback.
*/
void zephyr_smp_free_buf(void *buf, void *arg)
{
struct zephyr_smp_transport *zst = arg;
@ -157,36 +90,15 @@ static int @@ -157,36 +90,15 @@ static int
zephyr_smp_tx_rsp(struct smp_streamer *ns, void *rsp, void *arg)
{
struct zephyr_smp_transport *zst;
struct net_buf *frag;
struct net_buf *nb;
uint16_t mtu;
int rc;
int i;
zst = arg;
nb = rsp;
mtu = zst->zst_get_mtu(rsp);
if (mtu == 0U) {
/* The transport cannot support a transmission right now. */
return MGMT_ERR_EUNKNOWN;
}
i = 0;
while (nb != NULL) {
frag = zephyr_smp_split_frag(&nb, zst, mtu);
if (frag == NULL) {
zephyr_smp_free_buf(nb, zst);
return MGMT_ERR_ENOMEM;
}
rc = zst->zst_output(frag);
if (rc != 0) {
return MGMT_ERR_EUNKNOWN;
}
}
return 0;
/* Pass full packet to output function so it can be transmitted or split into frames as
* needed by the transport
*/
return zst->zst_output(nb);
}
/**

239
subsys/mgmt/mcumgr/transport/serial_util.c

@ -143,11 +143,10 @@ struct net_buf *mcumgr_serial_process_frag( @@ -143,11 +143,10 @@ struct net_buf *mcumgr_serial_process_frag(
}
/**
* Base64-encodes a small chunk of data and transmits it. The data must be no
* larger than three bytes.
* Base64-encodes a small chunk of data and transmits it. The data must be no larger than three
* bytes.
*/
static int mcumgr_serial_tx_small(const void *data, int len,
mcumgr_serial_tx_cb cb, void *arg)
static int mcumgr_serial_tx_small(const void *data, int len, mcumgr_serial_tx_cb cb)
{
uint8_t b64[4 + 1]; /* +1 required for null terminator. */
size_t dst_len;
@ -157,179 +156,159 @@ static int mcumgr_serial_tx_small(const void *data, int len, @@ -157,179 +156,159 @@ static int mcumgr_serial_tx_small(const void *data, int len,
__ASSERT_NO_MSG(rc == 0);
__ASSERT_NO_MSG(dst_len == 4);
return cb(b64, 4, arg);
return cb(b64, 4);
}
/**
* @brief Transmits a single mcumgr frame over serial.
* @brief Transmits a single mcumgr packet over serial, splits into multiple frames as needed.
*
* @param data The frame payload to transmit. This does not
* include a header or CRC.
* @param first Whether this is the first frame in the packet.
* @param len The number of untransmitted data bytes in the
* packet.
* @param crc The 16-bit CRC of the entire packet.
* @param data The packet payload to transmit. This does not include a header or
* CRC.
* @param len The size of the packet payload.
* @param cb A callback used for transmitting raw data.
* @param arg An optional argument that gets passed to the
* callback.
* @param out_data_bytes_txed On success, the number of data bytes
* transmitted gets written here.
*
* @return 0 on success; negative error code on failure.
*/
int mcumgr_serial_tx_frame(const uint8_t *data, bool first, int len,
uint16_t crc, mcumgr_serial_tx_cb cb, void *arg,
int *out_data_bytes_txed)
int mcumgr_serial_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb cb)
{
bool first = true;
bool last = false;
uint8_t raw[3];
uint16_t u16;
uint16_t crc;
int src_off = 0;
int rc = 0;
int to_process;
bool last = false;
int reminder;
/*
* This is max input bytes that can be taken to the frame before encoding with Base64;
* Base64 has three-to-four ratio, which means that for each three input bytes there are
* going to be four bytes of output used. The frame starts with two byte marker and ends
* going to be four bytes of output used. The frame starts with two byte marker and ends
* with newline character, which are not encoded (this is the "-3" in calculation).
*/
int max_input = (((MCUMGR_SERIAL_MAX_FRAME - 3) >> 2) * 3);
if (first) {
/* First frame marker */
u16 = sys_cpu_to_be16(MCUMGR_SERIAL_HDR_PKT);
} else {
/* Continuation frame marker */
u16 = sys_cpu_to_be16(MCUMGR_SERIAL_HDR_FRAG);
}
rc = cb(&u16, sizeof(u16), arg);
if (rc != 0) {
return rc;
}
/* Calculate the CRC16 checksum of the whole packet, prior to splitting it into frames */
crc = mcumgr_serial_calc_crc(data, len);
/*
* Only the first fragment contains the packet length; the packet length, which is two
* byte long is paired with first byte of input buffer to form triplet for Base64 encoding.
*/
if (first) {
/* The size of the CRC16 should be added to packet length */
u16 = sys_cpu_to_be16(len + 2);
memcpy(raw, &u16, sizeof(u16));
raw[2] = data[0];
/* First frame marker */
u16 = sys_cpu_to_be16(MCUMGR_SERIAL_HDR_PKT);
rc = mcumgr_serial_tx_small(raw, 3, cb, arg);
while (src_off < len) {
/* Send first frame or continuation frame marker */
rc = cb(&u16, sizeof(u16));
if (rc != 0) {
return rc;
}
++src_off;
/* One triple of allowed input already used */
max_input -= 3;
}
/*
* Only the first fragment contains the packet length; the packet length, which is
* two byte long is paired with first byte of input buffer to form triplet for
* Base64 encoding.
*/
if (first) {
/* The size of the CRC16 should be added to packet length */
u16 = sys_cpu_to_be16(len + 2);
memcpy(raw, &u16, sizeof(u16));
raw[2] = data[0];
/*
* Only as much as fits into the frame can be processed, but we also need to fit in the
* two byte CRC. The frame can not be stretched and current logic does not allow to
* send CRC separately so if CRC would not fit as a whole, shrink to_process by one byte
* forcing one byte to the next frame, with the CRC.
*/
to_process = MIN(max_input, len - src_off);
reminder = max_input - (len - src_off);
rc = mcumgr_serial_tx_small(raw, 3, cb);
if (rc != 0) {
return rc;
}
if (reminder == 0 || reminder == 1) {
to_process -= 1;
} else if (reminder >= 2) {
last = true;
}
++src_off;
/* One triple of allowed input already used */
max_input -= 3;
}
/*
* Try to process input buffer by chunks of three bytes that will be output as four byte
* chunks, due to Base64 encoding; the number of chunks that can be processed is calculated
* from number of three byte, complete, chunks in input buffer, but can not be greater
* than the number of four byte, complete, chunks that the frame can accept.
*/
while (to_process >= 3) {
memcpy(raw, data + src_off, 3);
rc = mcumgr_serial_tx_small(raw, 3, cb, arg);
if (rc != 0) {
return rc;
/*
* Only as much as fits into the frame can be processed, but we also need to fit
* in the two byte CRC. The frame can not be stretched and current logic does not
* allow to send CRC separately so if CRC would not fit as a whole, shrink
* to_process by one byte forcing one byte to the next frame, with the CRC.
*/
to_process = MIN(max_input, len - src_off);
reminder = max_input - (len - src_off);
if (reminder == 0 || reminder == 1) {
to_process -= 1;
/* This is the last frame but the checksum cannot be added, remove the
* last packet flag until the function runs again with the final piece of
* data and place the checksum there
*/
last = false;
} else if (reminder >= 2) {
last = true;
}
src_off += 3;
to_process -= 3;
}
if (last) {
/*
* Process the reminder bytes of the input buffer, after sending it in three byte
* chunks, and CRC.
* Try to process input buffer by chunks of three bytes that will be output as
* four byte chunks, due to Base64 encoding; the number of chunks that can be
* processed is calculated from number of three byte, complete, chunks in input
* buffer, but can not be greater than the number of four byte, complete, chunks
* that the frame can accept.
*/
switch (len - src_off) {
case 0:
raw[0] = (crc & 0xff00) >> 8;
raw[1] = crc & 0x00ff;
rc = mcumgr_serial_tx_small(raw, 2, cb, arg);
break;
case 1:
raw[0] = data[src_off++];
raw[1] = (crc & 0xff00) >> 8;
raw[2] = crc & 0x00ff;
rc = mcumgr_serial_tx_small(raw, 3, cb, arg);
break;
case 2:
raw[0] = data[src_off++];
raw[1] = data[src_off++];
raw[2] = (crc & 0xff00) >> 8;
rc = mcumgr_serial_tx_small(raw, 3, cb, arg);
while (to_process >= 3) {
memcpy(raw, data + src_off, 3);
rc = mcumgr_serial_tx_small(raw, 3, cb);
if (rc != 0) {
return rc;
}
raw[0] = crc & 0x00ff;
rc = mcumgr_serial_tx_small(raw, 1, cb, arg);
break;
src_off += 3;
to_process -= 3;
}
if (rc != 0) {
return rc;
}
}
rc = cb("\n", 1, arg);
if (rc != 0) {
return rc;
}
*out_data_bytes_txed = src_off;
return 0;
}
int mcumgr_serial_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb cb,
void *arg)
{
uint16_t crc;
int data_bytes_txed = 0;
int rc;
if (last) {
/*
* Process the reminder bytes of the input buffer, after sending it in
* three byte chunks, and CRC.
*/
switch (len - src_off) {
case 0:
raw[0] = (crc & 0xff00) >> 8;
raw[1] = crc & 0x00ff;
rc = mcumgr_serial_tx_small(raw, 2, cb);
break;
case 1:
raw[0] = data[src_off++];
raw[1] = (crc & 0xff00) >> 8;
raw[2] = crc & 0x00ff;
rc = mcumgr_serial_tx_small(raw, 3, cb);
break;
case 2:
raw[0] = data[src_off++];
raw[1] = data[src_off++];
raw[2] = (crc & 0xff00) >> 8;
rc = mcumgr_serial_tx_small(raw, 3, cb);
if (rc != 0) {
return rc;
}
raw[0] = crc & 0x00ff;
rc = mcumgr_serial_tx_small(raw, 1, cb);
break;
}
/* Calculate CRC of entire packet. */
crc = mcumgr_serial_calc_crc(data, len);
if (rc != 0) {
return rc;
}
}
/* Transmit packet as a sequence of frames. */
while (len) {
rc = mcumgr_serial_tx_frame(data, data_bytes_txed == 0, len, crc, cb, arg,
&data_bytes_txed);
rc = cb("\n", 1);
if (rc != 0) {
return rc;
}
data += data_bytes_txed;
len -= data_bytes_txed;
/* Use a continuation frame marker for the next packet */
u16 = sys_cpu_to_be16(MCUMGR_SERIAL_HDR_FRAG);
first = false;
}
return 0;

86
subsys/mgmt/mcumgr/transport/smp_bt.c

@ -391,57 +391,65 @@ static int smp_bt_tx_pkt(struct net_buf *nb) @@ -391,57 +391,65 @@ static int smp_bt_tx_pkt(struct net_buf *nb)
conn = smp_bt_conn_from_pkt(nb);
if (conn == NULL) {
rc = MGMT_ERR_ENOENT;
} else {
/* Send data in chunks of the MTU size */
mtu_size = smp_bt_get_mtu(nb);
goto cleanup;
}
k_sem_reset(&smp_notify_sem);
/* Send data in chunks of the MTU size */
mtu_size = smp_bt_get_mtu(nb);
while (off < nb->len) {
if ((off + mtu_size) > nb->len) {
/* Final packet, limit size */
mtu_size = nb->len - off;
}
if (mtu_size == 0U) {
/* The transport cannot support a transmission right now. */
rc = MGMT_ERR_EUNKNOWN;
goto cleanup;
}
k_sem_reset(&smp_notify_sem);
notify_param.len = mtu_size;
while (off < nb->len) {
if ((off + mtu_size) > nb->len) {
/* Final packet, limit size */
mtu_size = nb->len - off;
}
notify_param.len = mtu_size;
rc = bt_gatt_notify_cb(conn, &notify_param);
k_sem_take(&smp_notify_sem, K_FOREVER);
rc = bt_gatt_notify_cb(conn, &notify_param);
k_sem_take(&smp_notify_sem, K_FOREVER);
if (rc == -ENOMEM) {
if (sent == false) {
/* Failed to send a packet thus far, try reducing the MTU
* size as perhaps the buffer size is limited to a value
* which is less than the MTU or there is a configuration
* error in the project
if (rc == -ENOMEM) {
if (sent == false) {
/* Failed to send a packet thus far, try reducing the MTU size
* as perhaps the buffer size is limited to a value which is
* less than the MTU or there is a configuration error in the
* project
*/
if (mtu_size < SMP_BT_MINIMUM_MTU_SEND_FAILURE) {
/* If unable to send a 20 byte message, something is
* amiss, no point in continuing
*/
if (mtu_size < SMP_BT_MINIMUM_MTU_SEND_FAILURE) {
/* If unable to send a 20 byte message, something
* is amiss and so no point in continuing
*/
rc = MGMT_ERR_ENOMEM;
break;
}
mtu_size /= 2;
rc = MGMT_ERR_ENOMEM;
break;
}
/* No buffers available, wait until the next loop for them to
* become available
*/
rc = MGMT_ERR_EOK;
k_yield();
} else if (rc == 0) {
off += mtu_size;
notify_param.data = &nb->data[off];
sent = true;
} else {
rc = MGMT_ERR_EUNKNOWN;
break;
mtu_size /= 2;
}
/* No buffers available, wait until the next loop for them to become
* available
*/
rc = MGMT_ERR_EOK;
k_yield();
} else if (rc == 0) {
off += mtu_size;
notify_param.data = &nb->data[off];
sent = true;
} else {
rc = MGMT_ERR_EUNKNOWN;
break;
}
}
cleanup:
if (rc != MGMT_ERR_ENOENT) {
bt_conn_unref(conn);
}

42
subsys/mgmt/mcumgr/transport/smp_dummy.c

@ -27,6 +27,9 @@ @@ -27,6 +27,9 @@
#include <mgmt/mcumgr/smp_dummy.h>
#include "../smp_internal.h"
BUILD_ASSERT(CONFIG_MCUMGR_SMP_DUMMY_RX_BUF_SIZE != 0,
"CONFIG_MCUMGR_SMP_DUMMY_RX_BUF_SIZE must be > 0");
struct device;
static struct mcumgr_serial_rx_ctxt smp_dummy_rx_ctxt;
static struct mcumgr_serial_rx_ctxt smp_dummy_tx_ctxt;
@ -63,7 +66,7 @@ static struct net_buf *mcumgr_dummy_process_frag_outgoing( @@ -63,7 +66,7 @@ static struct net_buf *mcumgr_dummy_process_frag_outgoing(
const uint8_t *frag, int frag_len);
static int mcumgr_dummy_tx_pkt(const uint8_t *data, int len,
mcumgr_serial_tx_cb cb, void *arg);
mcumgr_serial_tx_cb cb);
K_FIFO_DEFINE(smp_dummy_rx_fifo);
K_WORK_DEFINE(smp_dummy_work, smp_dummy_process_rx_queue);
@ -150,7 +153,7 @@ static uint16_t smp_dummy_get_mtu(const struct net_buf *nb) @@ -150,7 +153,7 @@ static uint16_t smp_dummy_get_mtu(const struct net_buf *nb)
return CONFIG_MCUMGR_SMP_DUMMY_RX_BUF_SIZE;
}
int dummy_mcumgr_send_raw(const void *data, int len, void *arg)
int dummy_mcumgr_send_raw(const void *data, int len)
{
uint16_t data_size =
MIN(len, (sizeof(smp_send_buffer) - smp_send_pos - 1));
@ -174,7 +177,7 @@ static int smp_dummy_tx_pkt_int(struct net_buf *nb) @@ -174,7 +177,7 @@ static int smp_dummy_tx_pkt_int(struct net_buf *nb)
{
int rc;
rc = mcumgr_dummy_tx_pkt(nb->data, nb->len, dummy_mcumgr_send_raw, NULL);
rc = mcumgr_dummy_tx_pkt(nb->data, nb->len, dummy_mcumgr_send_raw);
mcumgr_buf_free(nb);
return rc;
@ -507,7 +510,7 @@ static struct net_buf *mcumgr_dummy_process_frag_outgoing( @@ -507,7 +510,7 @@ static struct net_buf *mcumgr_dummy_process_frag_outgoing(
* larger than three bytes.
*/
static int mcumgr_dummy_tx_small(const void *data, int len,
mcumgr_serial_tx_cb cb, void *arg)
mcumgr_serial_tx_cb cb)
{
uint8_t b64[4 + 1]; /* +1 required for null terminator. */
size_t dst_len;
@ -517,7 +520,7 @@ static int mcumgr_dummy_tx_small(const void *data, int len, @@ -517,7 +520,7 @@ static int mcumgr_dummy_tx_small(const void *data, int len,
__ASSERT_NO_MSG(rc == 0);
__ASSERT_NO_MSG(dst_len == 4);
return cb(b64, 4, arg);
return cb(b64, 4);
}
/**
@ -530,15 +533,13 @@ static int mcumgr_dummy_tx_small(const void *data, int len, @@ -530,15 +533,13 @@ static int mcumgr_dummy_tx_small(const void *data, int len,
* packet.
* @param crc The 16-bit CRC of the entire packet.
* @param cb A callback used for transmitting raw data.
* @param arg An optional argument that gets passed to the
* callback.
* @param out_data_bytes_txed On success, the number of data bytes
* transmitted gets written here.
*
* @return 0 on success; negative error code on failure.
*/
int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
uint16_t crc, mcumgr_serial_tx_cb cb, void *arg,
uint16_t crc, mcumgr_serial_tx_cb cb,
int *out_data_bytes_txed)
{
uint8_t raw[3];
@ -557,7 +558,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len, @@ -557,7 +558,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
u16 = sys_cpu_to_be16(MCUMGR_SERIAL_HDR_FRAG);
}
rc = cb(&u16, sizeof(u16), arg);
rc = cb(&u16, sizeof(u16));
if (rc != 0) {
return rc;
}
@ -569,7 +570,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len, @@ -569,7 +570,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
memcpy(raw, &u16, sizeof(u16));
raw[2] = data[0];
rc = mcumgr_dummy_tx_small(raw, 3, cb, arg);
rc = mcumgr_dummy_tx_small(raw, 3, cb);
if (rc != 0) {
return rc;
}
@ -591,7 +592,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len, @@ -591,7 +592,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
if (rem == 0) {
raw[0] = (crc & 0xff00) >> 8;
raw[1] = crc & 0x00ff;
rc = mcumgr_dummy_tx_small(raw, 2, cb, arg);
rc = mcumgr_dummy_tx_small(raw, 2, cb);
if (rc != 0) {
return rc;
}
@ -604,7 +605,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len, @@ -604,7 +605,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
raw[1] = (crc & 0xff00) >> 8;
raw[2] = crc & 0x00ff;
rc = mcumgr_dummy_tx_small(raw, 3, cb, arg);
rc = mcumgr_dummy_tx_small(raw, 3, cb);
if (rc != 0) {
return rc;
}
@ -617,13 +618,13 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len, @@ -617,13 +618,13 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
src_off += 2;
raw[2] = (crc & 0xff00) >> 8;
rc = mcumgr_dummy_tx_small(raw, 3, cb, arg);
rc = mcumgr_dummy_tx_small(raw, 3, cb);
if (rc != 0) {
return rc;
}
raw[0] = crc & 0x00ff;
rc = mcumgr_dummy_tx_small(raw, 1, cb, arg);
rc = mcumgr_dummy_tx_small(raw, 1, cb);
if (rc != 0) {
return rc;
}
@ -632,7 +633,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len, @@ -632,7 +633,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
/* Otherwise, just encode payload data. */
memcpy(raw, data + src_off, 3);
rc = mcumgr_dummy_tx_small(raw, 3, cb, arg);
rc = mcumgr_dummy_tx_small(raw, 3, cb);
if (rc != 0) {
return rc;
}
@ -640,7 +641,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len, @@ -640,7 +641,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
dst_off += 4;
}
rc = cb("\n", 1, arg);
rc = cb("\n", 1);
if (rc != 0) {
return rc;
}
@ -649,8 +650,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len, @@ -649,8 +650,7 @@ int mcumgr_dummy_tx_frame(const uint8_t *data, bool first, int len,
return 0;
}
static int mcumgr_dummy_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb cb,
void *arg)
static int mcumgr_dummy_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb cb)
{
uint16_t crc;
int data_bytes_txed;
@ -666,7 +666,7 @@ static int mcumgr_dummy_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb @@ -666,7 +666,7 @@ static int mcumgr_dummy_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb
rc = mcumgr_dummy_tx_frame(data + src_off,
src_off == 0,
len - src_off,
crc, cb, arg,
crc, cb,
&data_bytes_txed);
if (rc != 0) {
return rc;
@ -678,7 +678,7 @@ static int mcumgr_dummy_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb @@ -678,7 +678,7 @@ static int mcumgr_dummy_tx_pkt(const uint8_t *data, int len, mcumgr_serial_tx_cb
return 0;
}
static int smp_receive(const void *data, int len, void *arg)
static int smp_receive(const void *data, int len)
{
uint16_t data_size =
MIN(len, (sizeof(smp_receive_buffer) - smp_receive_pos - 1));
@ -713,7 +713,7 @@ uint16_t smp_dummy_get_receive_pos(void) @@ -713,7 +713,7 @@ uint16_t smp_dummy_get_receive_pos(void)
int smp_dummy_tx_pkt(const uint8_t *data, int len)
{
return mcumgr_dummy_tx_pkt(data, len, smp_receive, NULL);
return mcumgr_dummy_tx_pkt(data, len, smp_receive);
}
void smp_dummy_enable(void)

6
subsys/mgmt/mcumgr/transport/smp_shell.c

@ -26,6 +26,8 @@ @@ -26,6 +26,8 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(smp_shell);
BUILD_ASSERT(CONFIG_MCUMGR_SMP_SHELL_MTU != 0, "CONFIG_MCUMGR_SMP_SHELL_MTU must be > 0");
static struct zephyr_smp_transport smp_shell_transport;
static struct mcumgr_serial_rx_ctxt smp_shell_rx_ctxt;
@ -160,7 +162,7 @@ static uint16_t smp_shell_get_mtu(const struct net_buf *nb) @@ -160,7 +162,7 @@ static uint16_t smp_shell_get_mtu(const struct net_buf *nb)
return CONFIG_MCUMGR_SMP_SHELL_MTU;
}
static int smp_shell_tx_raw(const void *data, int len, void *arg)
static int smp_shell_tx_raw(const void *data, int len)
{
const struct shell *const sh = shell_backend_uart_get_ptr();
const struct shell_uart *const su = sh->iface->ctx;
@ -180,7 +182,7 @@ static int smp_shell_tx_pkt(struct net_buf *nb) @@ -180,7 +182,7 @@ static int smp_shell_tx_pkt(struct net_buf *nb)
{
int rc;
rc = mcumgr_serial_tx_pkt(nb->data, nb->len, smp_shell_tx_raw, NULL);
rc = mcumgr_serial_tx_pkt(nb->data, nb->len, smp_shell_tx_raw);
mcumgr_buf_free(nb);
return rc;

2
subsys/mgmt/mcumgr/transport/smp_uart.c

@ -19,6 +19,8 @@ @@ -19,6 +19,8 @@
#include <zephyr/mgmt/mcumgr/smp.h>
#include "../smp_internal.h"
BUILD_ASSERT(CONFIG_MCUMGR_SMP_UART_MTU != 0, "CONFIG_MCUMGR_SMP_UART_MTU must be > 0");
struct device;
static void smp_uart_process_rx_queue(struct k_work *work);

30
subsys/mgmt/mcumgr/transport/smp_udp.c

@ -28,6 +28,8 @@ @@ -28,6 +28,8 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(smp_udp);
BUILD_ASSERT(CONFIG_MCUMGR_SMP_UDP_MTU != 0, "CONFIG_MCUMGR_SMP_UDP_MTU must be > 0");
struct config {
int sock;
const char *proto;
@ -64,24 +66,40 @@ static struct configs configs = { @@ -64,24 +66,40 @@ static struct configs configs = {
#ifdef CONFIG_MCUMGR_SMP_UDP_IPV4
static int smp_udp4_tx(struct net_buf *nb)
{
int ret;
struct sockaddr *addr = net_buf_user_data(nb);
int ret = sendto(configs.ipv4.sock, nb->data, nb->len,
0, addr, sizeof(*addr));
ret = sendto(configs.ipv4.sock, nb->data, nb->len, 0, addr, sizeof(*addr));
if (ret < 0) {
ret = MGMT_ERR_EINVAL;
} else {
ret = MGMT_ERR_EOK;
}
mcumgr_buf_free(nb);
return ret < 0 ? MGMT_ERR_EINVAL : MGMT_ERR_EOK;
return ret;
}
#endif
#ifdef CONFIG_MCUMGR_SMP_UDP_IPV6
static int smp_udp6_tx(struct net_buf *nb)
{
int ret;
struct sockaddr *addr = net_buf_user_data(nb);
int ret = sendto(configs.ipv6.sock, nb->data, nb->len,
0, addr, sizeof(*addr));
ret = sendto(configs.ipv6.sock, nb->data, nb->len, 0, addr, sizeof(*addr));
if (ret < 0) {
ret = MGMT_ERR_EINVAL;
} else {
ret = MGMT_ERR_EOK;
}
mcumgr_buf_free(nb);
return ret < 0 ? MGMT_ERR_EINVAL : MGMT_ERR_EOK;
return ret;
}
#endif

Loading…
Cancel
Save