Use application specific SMP group ID without CBOR

Dear Nordic support team,

I need to send large data over BLE, and for this purpose we are trying to use the SMP layer over BLE, especially for cybersecurity. I feel that use the SMP protocol is a good idea because I have the exact same purpose as the MCUmgr for the update or the filesystem management : send large data, with the possibility of reassembling packets automatically.

It's specified in the nRF Connect SDK specification that there can be application specific SMP group IDs, and that these group IDs can use any protocol they wish.
"The payload for above groups, except for user groups (64 and above) is always CBOR encoded. The group 64, and above can define their own scheme for data communication." (SMP spec)

I managed to send custom data in CBOR format using the implementations in ncs/zephyr as reference :

/**
 * @brief Command IDs for this group ID
 */
#define CUSTOM_COMMAND_READ (0)

static int send_data_handler(struct smp_streamer *ctxt) {
  // CBOR encoding here using ctxt->writer->zs, too long to be written here
  return 0;
}

static const struct mgmt_handler custom_handlers[] = {
    [CUSTOM_COMMAND_READ] =
        {
            .mh_read = send_data_handler,
            .mh_write = NULL,
        },
};

static struct mgmt_group lnv_log_mgmt_group = {
    .mg_handlers = (struct mgmt_handler *)custom_handlers,
    .mg_handlers_count = ARRAY_SIZE(custom_handlers),
    .mg_group_id = (64),
};


MCUMGR_HANDLER_DEFINE(my_handler, my_handler_init);
 

My .prj file has the following lines : 

CONFIG_MCUMGR_BUF_SIZE=2000
CONFIG_MCUMGR=y
CONFIG_MCUMGR_BUF_COUNT=2
CONFIG_MCUMGR_SMP_BT=y
CONFIG_MCUMGR_SMP_REASSEMBLY_BT=y
CONFIG_MCUMGR_SMP_BT_AUTHEN=n

But is it possible to use other serialization protocol (such as protobuf, or custom C structures) via a specific SMP group ID ? Do you have an example for this ? I feel this is not possible with this approach, because in smp.c the characters to start a CBOR map (0xBF) and end a map (0xFF) are automatically added : 

	if (handler_fn) {
		*handler_found = true;

        /***** HERE, this add a character to start a map in CBOR *****/
		zcbor_map_start_encode(cbuf->writer->zs, CONFIG_MGMT_MAX_MAIN_MAP_ENTRIES);

        /***** my custom function, where I encore data in CBOR as a map *****/
		MGMT_CTXT_SET_RC_RSN(cbuf, NULL);
		rc = handler_fn(cbuf);

		/* End response payload. */
        /***** HERE, this add a character to end a map in CBOR *****/
		if (!zcbor_map_end_encode(cbuf->writer->zs, CONFIG_MGMT_MAX_MAIN_MAP_ENTRIES) &&
		    rc == 0) {
			rc = MGMT_ERR_EMSGSIZE;
		}

Thanks in advance !

Best regards

  • Hello,

    Looking at the implementation I can see the same as you: that it seems as start and end characters are added when using smp_process_request_packet(). So it might seem as there is either an error in the documentation or the implementation is wrong here. I can report this.

    In terms of security: I do not believe The Simple Management Protocol (SMP) and CBOR have specific security, maybe you are thinking of the Security Manager Protocol (also SMP) that can ensure authentication and encryption between two BLE devices, this protocol can work for any kind of data over BLE. I assume this can for instance be enabled through the CONFIG_MCUMGR_SMP_BT_AUTHEN=y if you want.

    So that said, have you considered just using NUS service to send and receive arbitrary data? (This can also use authentication and security between two BLE devices)
    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/libraries/bluetooth_services/services/nus.html

    Best regards,
    Kenneth

  • Dear Kenneth,

    Thank you for your answer and for the link to the NUS. I'd gladly use the NUS if there were any transport protocol higher than L2CAP which is too limited in term of size. I have to separate (on transmission) and concatenate (upon reception of packets) then parse the payloads to get my protobuf or CBOR encoded PDUs entirely if I use NUS. That's the whole point of using SMP in addition of saving RAM because the same buffers are used for the BLE update. And it works fine. The only counterpart is that SMP is a client / server protocol where the server cannot notify the client, I'll see if this is an issue.

    After reading again, I think the documentation is not very clear. But it also says that : 

    "Regardless of a command issued, as long as there is SMP client on the other side of a request, a response should be issued containing the header followed by CBOR map container. Lack of response is only allowed when there is no SMP service or device is non-responsive."

    So I think it's correct to add the CBOR characters to start and end a map. It's not very logical though.

    For the security aspect I mentionned, I meant to implement our own security scheme and not rely on the Security Management Protocol.

Related