Sending SHELL commands between two nRF52-DK (n52832 MCU) boards over BLE based on SMP

Hello Support-Team!
We are designing a system, where we need to maintain some settings using shell commands
(we plan to develop our own set of customised commands).
Our platform already implements OTA DFU with MCUboot/SMP-server and external SPI flash (it's working fine).
Initially we wanted to use Nordic UART service to transfer commands, but we run out of RAM memory,
when adding nordic UART Service to our embedded application (with nRF52832 MCU we have quite limited RAM resources).
So, we started to investigate how to send SHELL commands between two nRF52-DK boards:
On one side/board we have central_smp_client sample and on the other side/board we have the smp_svr sample
- so far it worked fine (we can send SMP 'echo' and receive the right response).
But our goal is to enable/add the possibility to send SHELL commands (from central_smp_client to smp_svr) over BLE/SMP.
Finally we want to extend the smp_svr with custom commands.
We need any sample (project configuration file and sample implementation) of sending the SHELL commands over BLE/SMP
from the central_smp_client to smp_svr.
We were thinking about using the 'smp_bt_notify', but we ca not build it (linking of smp_bt_notify).

prf.conf (based on central_smp_client)
CONFIG_NCS_SAMPLES_DEFAULTS=y

CONFIG_BT=y
#CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_DM=y
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_BT_DFU_SMP=y

CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1

CONFIG_ZCBOR=y
CONFIG_ZCBOR_STOP_ON_ERROR=y

CONFIG_DK_LIBRARY=y

# new defiens for SHELL support:
CONFIG_SHELL=y
CONFIG_MCUMGR=y
CONFIG_MCUMGR_TRANSPORT_BT=y
CONFIG_MCUMGR_TRANSPORT_SHELL=y

//-----------------------------------------------------------------------------

This is a sample function to send SHELL commands with smp_bt_notify function (but it does not build correctly):

//-----------------------------------------------------------------------------
void send_shell_command(struct bt_conn *conn, const char *cmd) {
    uint8_t buf[128] = {0};  // Explicitly zero the buffer for safety
    zcbor_state_t zs[4];  // CBOR encoding state

    // Initialize CBOR encoder
    zcbor_new_state(zs, ARRAY_SIZE(zs), buf, sizeof(buf), 1);

    // Encode the CBOR payload
    bool ok = zcbor_map_start_encode(zs, 1);
    ok = ok && zcbor_tstr_put_lit(zs, "command");  // Encode the "command" string literal key
    ok = ok && zcbor_tstr_put_lit(zs, cmd);        // Encode the user-provided command string
    ok = ok && zcbor_map_end_encode(zs, 1);

    if (!ok) {
        printk("Failed to encode CBOR payload\n");
        return;
    }

    // Send the CBOR-encoded message as an SMP notification
    int err = smp_bt_notify(conn, buf, zs[0].payload - buf);
    if (err) {
        printk("Failed to send SMP command: %d\n", err);
    } else {
        printk("SMP command sent successfully\n");
    }

}

Id the 'smp_bt_notify' the right way to pass SHELL commands between SMP clinet and SMP Server?
Could you help us with any code snippets (proj.conf and C code) showing how
to configure and what API to use on the client side to be able to send SHELL commands to the smp_srv?

Having any SMP Client<->Server sampels exchanging SHELL commands would be very appreciated.

Best regards, Andy

  • We further investigated on our side and it seems that we need to simply replace the command group id (Group id of 0 for 'echo' with id of 9 for 'shell') commands i.e.:

    smp_cmd.header.group_l8 = 9; /* SHELL */

    Could you please just confirm, if it is the right approach?  With this change we can send commands and get responses from server side (we get decoding error: 10). Do you have any samples how to handle (smp_user_tst_rsp_proc() ) the responses for commands send in this way?

  • Hi, 

    You can use the bt_dfu_smp_command() function to send a command; bt_dfu_smp_rsp_state() function to access the data of the current part of the response. Here is the central_smp_client sample showing how to send a simple OS/echo command and respond. Although it doesn't handle the shell command, it is still worth knowing the flow. 

    SP2AND said:
    Do you have any samples how to handle (smp_user_tst_rsp_proc() ) the responses for commands send in this way?

    I cannot find that function. Is that the correct name? Maybe this function could give you some inspiration. 

    If the above information cannot help, please provide the snippet code of your send_smp_shell_command and respond functions.

    Regards,
    Amanda H.    
     

Related