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

Parents
  • 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.    
     

  • Hello Amanda,
    thank you very much for your promt response and hints!
    First of all (as mentioned already before) - I use central smp_clinet and smp_srv samples as our reference samples.
    I can observe the "echo" command (when pressing Button 1), which is send from the SMP central client to
    the SMP server and received the 'echo' response. This in no problem at all.
    I also undestand the operation of:
    send_smp_echo() and smp_echo_rsp_proc() functions.
    The 'echo' belongs to OS group (0) and it has a header id of '0',
    see code snippet of the SMP client sample  below:
      smp_cmd.header.group_l8 = 0; /* OS */
      smp_cmd.header.id  = 0; /* ECHO */
    --
    As we want to extend the functionality for the SHELL commands - we defined
    another Button (2) with new set of handler functions:
    send_smp_user_tst() for sending SHELL Command
    and
    smp_user_tst_rsp_proc() for handling SHELL Response
    see code below:
    //-----------------------------------------------------------------------------
    // SHELL Command Sending
    static int send_smp_user_tst(struct bt_dfu_smp *dfu_smp,
                 const char *string) {
        static struct smp_buffer smp_cmd;
        zcbor_state_t zse[CBOR_ENCODER_STATE_NUM];
        size_t payload_len;

        zcbor_new_encode_state(zse, ARRAY_SIZE(zse), smp_cmd.payload,
                       sizeof(smp_cmd.payload), 0);

        /* Stop encoding on the error. */
        zse->constant_state->stop_on_error = true;

        zcbor_map_start_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT);
        zcbor_tstr_put_lit(zse, "d");
        zcbor_tstr_put_term(zse, string);
        zcbor_map_end_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT);

        if (!zcbor_check_error(zse)) {
            printk("Failed to encode SMP User packet, err: %d\n", zcbor_pop_error(zse));
            return -EFAULT;
        }
        payload_len = (size_t)(zse->payload - smp_cmd.payload);

        smp_cmd.header.op = 2; /* Write */
        smp_cmd.header.flags = 0;
        smp_cmd.header.len_h8 = (uint8_t)((payload_len >> 8) & 0xFF);
        smp_cmd.header.len_l8 = (uint8_t)((payload_len >> 0) & 0xFF);
        smp_cmd.header.group_h8 = 0;
        smp_cmd.header.group_l8 = 9; /* SHELL */
        smp_cmd.header.seq = 0;
        smp_cmd.header.id  = 0; /* SHELL command line execute  */

        return bt_dfu_smp_command(dfu_smp, smp_user_tst_rsp_proc,
                      sizeof(smp_cmd.header) + payload_len,
                      &smp_cmd);
    }

    // SHELL Command's RESPONSE decoding
    static void smp_user_tst_rsp_proc(struct bt_dfu_smp *dfu_smp) {
        uint8_t *p_outdata = (uint8_t *)(&smp_rsp_buff);
        const struct bt_dfu_smp_rsp_state *rsp_state;

        rsp_state = bt_dfu_smp_rsp_state(dfu_smp);
        printk("User response part received, size: %zu.\n", rsp_state->chunk_size);

        if (rsp_state->offset + rsp_state->chunk_size > sizeof(smp_rsp_buff)) {
            printk("Response size buffer overflow\n");
        } else {
            p_outdata += rsp_state->offset;
            memcpy(p_outdata, rsp_state->data, rsp_state->chunk_size);
        }

        if (bt_dfu_smp_rsp_total_check(dfu_smp)) {
            printk("Total User response received - decoding\n");

            if (smp_rsp_buff.header.op != 3 /* WRITE RSP*/) {
                printk("Unexpected operation code (%u)!\n", smp_rsp_buff.header.op);
                return;
            }

            uint16_t group = ((uint16_t)smp_rsp_buff.header.group_h8 << 8) |
                             smp_rsp_buff.header.group_l8;

            printk("Response group (%u)\n", group);
            printk("Rsp command Id (%u)\n", smp_rsp_buff.header.id);

            size_t payload_len = ((uint16_t)smp_rsp_buff.header.len_h8 << 8) |
                                 smp_rsp_buff.header.len_l8;
            zcbor_state_t zsd[CBOR_DECODER_STATE_NUM];
            struct zcbor_string key;
            bool ok;
            zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), smp_rsp_buff.payload, payload_len, 1);
            /* Stop decoding on the error. */
            zsd->constant_state->stop_on_error = true;
            // Start decoding the CBOR map
            ok = zcbor_map_start_decode(zsd);
            if (!ok) {
                printk("Failed to start CBOR map decoding err: %d\n", zcbor_pop_error(zsd));
                return;
            }
            // Decode the key
            ok = zcbor_tstr_decode(zsd, &key);
            if (!ok) {
                printk("Failed to decode key error: %d\n", zcbor_pop_error(zsd));
                return;
            }
            printk("Key decoded: %.*s\n", key.len, key.value);
            if (key.len == 2 && strncmp((char *)key.value, "rc", 2) == 0) {
                int64_t value;
                // Decode integer value
                ok = zcbor_int32_decode(zsd, &value);
                if (!ok) {
                    printk("Failed to decode value for key 'rc' error: %d\n", zcbor_pop_error(zsd));
                    return;
                }
                printk("Key 'rc' has value: %lld\n", value);
            } else {
                printk("Unexpected key: %.*s\n", key.len, key.value);
                return;
            }
            // End decoding the CBOR map
            ok = zcbor_map_end_decode(zsd);
            if (!ok) {
                printk("Failed to end CBOR map decoding error: %d\n", zcbor_pop_error(zsd));
                return;
            }
            printk("CBOR map decoding completed OK\n");
        }
    }
    --
    //-----------------------------------------------------------------------------
    // button 2 handler
    static void button_user(bool state) {
        if (state) {
            static unsigned int user_cnt;
            char buffer[32];
            int ret;

            ++user_cnt;
            printk("User test: %d\n", user_cnt);
            //snprintk(buffer, sizeof(buffer), "stats show");
            snprintk(buffer, sizeof(buffer), "show");
            // Send User message to SMP Server
            ret = send_smp_user_tst(&dfu_smp, buffer);
            if (ret) {
                printk("Echo command send error (err: %d)\n", ret);
            }
        }
    }

    --
    Additionally for smp_srv sample prj.conf (update since yesterday) we set:
    CONFIG_SHELL_BACKEND_SERIAL=n
    CONFIG_SHELL_BACKEND_DUMMY=y
    CONFIG_ZCBOR_VERBOSE=y
    to properly service SHELL (avoid using SERIAL Shell backend)
    and disply more decoding CBOR messages.

    With the above config/code we can send SHELL Group command from the SMP client to the server:
    smp_cmd.header.group_l8 = 9; /* SHELL */
    but we are not sure what to set in header.id  - see below:
     smp_cmd.header.id  = 0; /* SHELL command line execute  */
        
    and what to send as payload to this command (e.g. "stats show" or "show:" or anything else ?)
    --
    Below are our logs for smp_client Button 1:
    Echo test: 1
    bytes left: 127, byte: 0x61, elem_count: 0x0, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    bytes left: 125, byte: 0x6f, elem_count: 0x1, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    Echo response part received, size: 28.
    Total response received - decoding
    bytes left: 19, byte: 0x61, elem_count: 0xffffffef, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 17, byte: 0x6f, elem_count: 0xffffffee, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    {_"r": "Echo message: 1"}

    Below are our logs for smp_srv Button 1:
    [01:33:15.940,643] <inf> smp_bt_sample: Connected
    bytes left: 19, byte: 0x61, elem_count: 0xffffffef, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 17, byte: 0x6f, elem_count: 0xffffffee, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:62
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:339
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:355
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:483
    bytes left: 2466, byte: 0x61, elem_count: 0x0, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    bytes left: 2464, byte: 0x6f, elem_count: 0x1, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75

    ----
    Below are our logs for smp_client Button 2:
    User test: 1
    bytes left: 127, byte: 0x61, elem_count: 0x0, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    bytes left: 125, byte: 0x64, elem_count: 0x1, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    User response part received, size: 14.
    Total User response received - decoding
    Response group (9)
    Rsp command Id (0)
    bytes left: 5, byte: 0x62, elem_count: 0xffffffef, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    Key decoded: rc
    bytes left: 2, byte: 0x3, elem_count: 0xffffffee, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    Key 'rc' has value: 3
    CBOR map decoding completed OK

    --
    Below are our logs for smp_srv Button 2:
    bytes left: 8, byte: 0x61, elem_count: 0xffffffef, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 6, byte: 0x64, elem_count: 0xffffffee, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:62
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:339
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:355
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:483
    bytes left: 2466, byte: 0x62, elem_count: 0x0, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    bytes left: 2463, byte: 0x3, elem_count: 0x1, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75

    --
    So, as you can see - I can send Group 9 command with Id 0 and receive a response (Key 'rc' has value: 3)
    but I don't understand the error code...?
    I suspect it is (ZCBOR_ERR_LOW_ELEM_COUNT 3) defiend in:
    zcbor_common.h
    as:
    #define ZCBOR_SUCCESS 0
    #define ZCBOR_ERR_NO_BACKUP_MEM 1
    #define ZCBOR_ERR_NO_BACKUP_ACTIVE 2
    #define ZCBOR_ERR_LOW_ELEM_COUNT 3      <<<<<<<<<< Error 3
    #define ZCBOR_ERR_HIGH_ELEM_COUNT 4
    #define ZCBOR_ERR_INT_SIZE 5
    #define ZCBOR_ERR_FLOAT_SIZE 6
    #define ZCBOR_ERR_ADDITIONAL_INVAL 7 ///! > 27
    #define ZCBOR_ERR_NO_PAYLOAD 8
    #define ZCBOR_ERR_PAYLOAD_NOT_CONSUMED 9
    #define ZCBOR_ERR_WRONG_TYPE 10
    #define ZCBOR_ERR_WRONG_VALUE 11
    #define ZCBOR_ERR_WRONG_RANGE 12
    #define ZCBOR_ERR_ITERATIONS 13
    #define ZCBOR_ERR_ASSERTION 14
    #define ZCBOR_ERR_UNKNOWN 31
    --

    So (if my assumption is right) we are sending (to the SHELL) some wrong command's payload or arguments are incomplete .

    Could you help us - how the group / header id and other SMP frame's paramters should be specified for the
    SHELL commands?
    Best would be a working sample with prefdefined 'stats' commands (llike: show, clear or any other).
    Best Regards,
    Andy

Reply
  • Hello Amanda,
    thank you very much for your promt response and hints!
    First of all (as mentioned already before) - I use central smp_clinet and smp_srv samples as our reference samples.
    I can observe the "echo" command (when pressing Button 1), which is send from the SMP central client to
    the SMP server and received the 'echo' response. This in no problem at all.
    I also undestand the operation of:
    send_smp_echo() and smp_echo_rsp_proc() functions.
    The 'echo' belongs to OS group (0) and it has a header id of '0',
    see code snippet of the SMP client sample  below:
      smp_cmd.header.group_l8 = 0; /* OS */
      smp_cmd.header.id  = 0; /* ECHO */
    --
    As we want to extend the functionality for the SHELL commands - we defined
    another Button (2) with new set of handler functions:
    send_smp_user_tst() for sending SHELL Command
    and
    smp_user_tst_rsp_proc() for handling SHELL Response
    see code below:
    //-----------------------------------------------------------------------------
    // SHELL Command Sending
    static int send_smp_user_tst(struct bt_dfu_smp *dfu_smp,
                 const char *string) {
        static struct smp_buffer smp_cmd;
        zcbor_state_t zse[CBOR_ENCODER_STATE_NUM];
        size_t payload_len;

        zcbor_new_encode_state(zse, ARRAY_SIZE(zse), smp_cmd.payload,
                       sizeof(smp_cmd.payload), 0);

        /* Stop encoding on the error. */
        zse->constant_state->stop_on_error = true;

        zcbor_map_start_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT);
        zcbor_tstr_put_lit(zse, "d");
        zcbor_tstr_put_term(zse, string);
        zcbor_map_end_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT);

        if (!zcbor_check_error(zse)) {
            printk("Failed to encode SMP User packet, err: %d\n", zcbor_pop_error(zse));
            return -EFAULT;
        }
        payload_len = (size_t)(zse->payload - smp_cmd.payload);

        smp_cmd.header.op = 2; /* Write */
        smp_cmd.header.flags = 0;
        smp_cmd.header.len_h8 = (uint8_t)((payload_len >> 8) & 0xFF);
        smp_cmd.header.len_l8 = (uint8_t)((payload_len >> 0) & 0xFF);
        smp_cmd.header.group_h8 = 0;
        smp_cmd.header.group_l8 = 9; /* SHELL */
        smp_cmd.header.seq = 0;
        smp_cmd.header.id  = 0; /* SHELL command line execute  */

        return bt_dfu_smp_command(dfu_smp, smp_user_tst_rsp_proc,
                      sizeof(smp_cmd.header) + payload_len,
                      &smp_cmd);
    }

    // SHELL Command's RESPONSE decoding
    static void smp_user_tst_rsp_proc(struct bt_dfu_smp *dfu_smp) {
        uint8_t *p_outdata = (uint8_t *)(&smp_rsp_buff);
        const struct bt_dfu_smp_rsp_state *rsp_state;

        rsp_state = bt_dfu_smp_rsp_state(dfu_smp);
        printk("User response part received, size: %zu.\n", rsp_state->chunk_size);

        if (rsp_state->offset + rsp_state->chunk_size > sizeof(smp_rsp_buff)) {
            printk("Response size buffer overflow\n");
        } else {
            p_outdata += rsp_state->offset;
            memcpy(p_outdata, rsp_state->data, rsp_state->chunk_size);
        }

        if (bt_dfu_smp_rsp_total_check(dfu_smp)) {
            printk("Total User response received - decoding\n");

            if (smp_rsp_buff.header.op != 3 /* WRITE RSP*/) {
                printk("Unexpected operation code (%u)!\n", smp_rsp_buff.header.op);
                return;
            }

            uint16_t group = ((uint16_t)smp_rsp_buff.header.group_h8 << 8) |
                             smp_rsp_buff.header.group_l8;

            printk("Response group (%u)\n", group);
            printk("Rsp command Id (%u)\n", smp_rsp_buff.header.id);

            size_t payload_len = ((uint16_t)smp_rsp_buff.header.len_h8 << 8) |
                                 smp_rsp_buff.header.len_l8;
            zcbor_state_t zsd[CBOR_DECODER_STATE_NUM];
            struct zcbor_string key;
            bool ok;
            zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), smp_rsp_buff.payload, payload_len, 1);
            /* Stop decoding on the error. */
            zsd->constant_state->stop_on_error = true;
            // Start decoding the CBOR map
            ok = zcbor_map_start_decode(zsd);
            if (!ok) {
                printk("Failed to start CBOR map decoding err: %d\n", zcbor_pop_error(zsd));
                return;
            }
            // Decode the key
            ok = zcbor_tstr_decode(zsd, &key);
            if (!ok) {
                printk("Failed to decode key error: %d\n", zcbor_pop_error(zsd));
                return;
            }
            printk("Key decoded: %.*s\n", key.len, key.value);
            if (key.len == 2 && strncmp((char *)key.value, "rc", 2) == 0) {
                int64_t value;
                // Decode integer value
                ok = zcbor_int32_decode(zsd, &value);
                if (!ok) {
                    printk("Failed to decode value for key 'rc' error: %d\n", zcbor_pop_error(zsd));
                    return;
                }
                printk("Key 'rc' has value: %lld\n", value);
            } else {
                printk("Unexpected key: %.*s\n", key.len, key.value);
                return;
            }
            // End decoding the CBOR map
            ok = zcbor_map_end_decode(zsd);
            if (!ok) {
                printk("Failed to end CBOR map decoding error: %d\n", zcbor_pop_error(zsd));
                return;
            }
            printk("CBOR map decoding completed OK\n");
        }
    }
    --
    //-----------------------------------------------------------------------------
    // button 2 handler
    static void button_user(bool state) {
        if (state) {
            static unsigned int user_cnt;
            char buffer[32];
            int ret;

            ++user_cnt;
            printk("User test: %d\n", user_cnt);
            //snprintk(buffer, sizeof(buffer), "stats show");
            snprintk(buffer, sizeof(buffer), "show");
            // Send User message to SMP Server
            ret = send_smp_user_tst(&dfu_smp, buffer);
            if (ret) {
                printk("Echo command send error (err: %d)\n", ret);
            }
        }
    }

    --
    Additionally for smp_srv sample prj.conf (update since yesterday) we set:
    CONFIG_SHELL_BACKEND_SERIAL=n
    CONFIG_SHELL_BACKEND_DUMMY=y
    CONFIG_ZCBOR_VERBOSE=y
    to properly service SHELL (avoid using SERIAL Shell backend)
    and disply more decoding CBOR messages.

    With the above config/code we can send SHELL Group command from the SMP client to the server:
    smp_cmd.header.group_l8 = 9; /* SHELL */
    but we are not sure what to set in header.id  - see below:
     smp_cmd.header.id  = 0; /* SHELL command line execute  */
        
    and what to send as payload to this command (e.g. "stats show" or "show:" or anything else ?)
    --
    Below are our logs for smp_client Button 1:
    Echo test: 1
    bytes left: 127, byte: 0x61, elem_count: 0x0, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    bytes left: 125, byte: 0x6f, elem_count: 0x1, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    Echo response part received, size: 28.
    Total response received - decoding
    bytes left: 19, byte: 0x61, elem_count: 0xffffffef, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 17, byte: 0x6f, elem_count: 0xffffffee, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    {_"r": "Echo message: 1"}

    Below are our logs for smp_srv Button 1:
    [01:33:15.940,643] <inf> smp_bt_sample: Connected
    bytes left: 19, byte: 0x61, elem_count: 0xffffffef, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 17, byte: 0x6f, elem_count: 0xffffffee, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:62
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:339
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:355
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:483
    bytes left: 2466, byte: 0x61, elem_count: 0x0, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    bytes left: 2464, byte: 0x6f, elem_count: 0x1, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75

    ----
    Below are our logs for smp_client Button 2:
    User test: 1
    bytes left: 127, byte: 0x61, elem_count: 0x0, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    bytes left: 125, byte: 0x64, elem_count: 0x1, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    User response part received, size: 14.
    Total User response received - decoding
    Response group (9)
    Rsp command Id (0)
    bytes left: 5, byte: 0x62, elem_count: 0xffffffef, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    Key decoded: rc
    bytes left: 2, byte: 0x3, elem_count: 0xffffffee, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    Key 'rc' has value: 3
    CBOR map decoding completed OK

    --
    Below are our logs for smp_srv Button 2:
    bytes left: 8, byte: 0x61, elem_count: 0xffffffef, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 6, byte: 0x64, elem_count: 0xffffffee, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:124
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:62
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:339
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:355
    bytes left: 1, byte: 0xff, elem_count: 0xffffffed, err: 10, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_decode.c:483
    bytes left: 2466, byte: 0x62, elem_count: 0x0, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75
    bytes left: 2463, byte: 0x3, elem_count: 0x1, err: 0, WEST_TOPDIR/modules/lib/zcbor/src/zcbor_encode.c:75

    --
    So, as you can see - I can send Group 9 command with Id 0 and receive a response (Key 'rc' has value: 3)
    but I don't understand the error code...?
    I suspect it is (ZCBOR_ERR_LOW_ELEM_COUNT 3) defiend in:
    zcbor_common.h
    as:
    #define ZCBOR_SUCCESS 0
    #define ZCBOR_ERR_NO_BACKUP_MEM 1
    #define ZCBOR_ERR_NO_BACKUP_ACTIVE 2
    #define ZCBOR_ERR_LOW_ELEM_COUNT 3      <<<<<<<<<< Error 3
    #define ZCBOR_ERR_HIGH_ELEM_COUNT 4
    #define ZCBOR_ERR_INT_SIZE 5
    #define ZCBOR_ERR_FLOAT_SIZE 6
    #define ZCBOR_ERR_ADDITIONAL_INVAL 7 ///! > 27
    #define ZCBOR_ERR_NO_PAYLOAD 8
    #define ZCBOR_ERR_PAYLOAD_NOT_CONSUMED 9
    #define ZCBOR_ERR_WRONG_TYPE 10
    #define ZCBOR_ERR_WRONG_VALUE 11
    #define ZCBOR_ERR_WRONG_RANGE 12
    #define ZCBOR_ERR_ITERATIONS 13
    #define ZCBOR_ERR_ASSERTION 14
    #define ZCBOR_ERR_UNKNOWN 31
    --

    So (if my assumption is right) we are sending (to the SHELL) some wrong command's payload or arguments are incomplete .

    Could you help us - how the group / header id and other SMP frame's paramters should be specified for the
    SHELL commands?
    Best would be a working sample with prefdefined 'stats' commands (llike: show, clear or any other).
    Best Regards,
    Andy

Children
No Data
Related