I think there is a bug in the v2.4.0 nRF9160 SDK in the Zephyr mcumgr smp code that prevents mcumgr from working when CONFIG_ZCBOR_CANONICAL=y is defined.
This can be demonstrated by building the lwm2m_client sample from \ncs\v2.4.0\nrf\samples\nrf9160\lwm2m_client and adding the following to prj.conf to enable mcumgr over the SHELL transport:
# # Enable RTT console. # CONFIG_USE_SEGGER_RTT=y CONFIG_RTT_CONSOLE=y CONFIG_SHELL_LOG_BACKEND=n # # Enable MCUMGR. # CONFIG_MCUMGR=y CONFIG_ZCBOR=y # CONFIG_ZCBOR_CANONICAL=y CONFIG_MCUMGR_TRANSPORT_SHELL=y CONFIG_BASE64=y CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=3072 CONFIG_MCUMGR_GRP_STAT=y CONFIG_STATS=y
With this configuration, the 'mcumgr' command-line tool can be used to access the 'stats' module, like so:
$ mcumgr --conntype serial --connstring dev=/dev/ttyS18,baud=115200 stat list
stat groups: none
If you uncomment the CONFIG_ZCBOR_CANONICAL=y, mcumgr stops working, giving a timeout:
$ mcumgr --conntype serial --connstring dev=/dev/ttyS18,baud=115200 stat list
Error: NMP timeout
This is important for the l2m2m_client, as various overlays (e.g. overlay-lwm2m-1.1-core-interop.conf) set CONFIG_ZCBOR_CANONICAL=y, so this prevents mcumgr from working with those overlays.
I have traced this to a problem in the mcumgr 'smp' subsystem in zephyr, which allocates unsufficient buffers for zcbor when used in canonical mode. The following patch appears to fix it:
diff --git a/include/zephyr/mgmt/mcumgr/smp/smp.h b/include/zephyr/mgmt/mcumgr/smp/smp.h index 2aa5cf5d87..ecb9b99e4d 100644 --- a/include/zephyr/mgmt/mcumgr/smp/smp.h +++ b/include/zephyr/mgmt/mcumgr/smp/smp.h @@ -45,7 +45,7 @@ struct cbor_nb_reader { struct cbor_nb_writer { struct net_buf *nb; - zcbor_state_t zs[2]; + zcbor_state_t zs[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; }; /** diff --git a/subsys/mgmt/mcumgr/smp/src/smp.c b/subsys/mgmt/mcumgr/smp/src/smp.c index 2fdde35427..4f1e71297f 100644 --- a/subsys/mgmt/mcumgr/smp/src/smp.c +++ b/subsys/mgmt/mcumgr/smp/src/smp.c @@ -40,7 +40,7 @@ static void cbor_nb_writer_init(struct cbor_nb_writer *cnw, struct net_buf *nb) net_buf_reset(nb); cnw->nb = nb; cnw->nb->len = sizeof(struct smp_hdr); - zcbor_new_encode_state(cnw->zs, 2, nb->data + sizeof(struct smp_hdr), + zcbor_new_encode_state(cnw->zs, ARRAY_SIZE(cnw->zs), nb->data + sizeof(struct smp_hdr), net_buf_tailroom(nb), 0); }
Can someone please confirm this?
Thanks
Ian