how can i get the number BLE TX re transmissions

hello Nordic

i am working with nrf52832 and nrf52840 socs, with ncs v2.1.0

i would like to know how many of the BLE packets i am sending has to be resent (and if it is possible to know the reason of resent, in case there is another reason beside packet missed some bytes/bits on the OTA way, that would be great as well ) 

any idea how can i get that info ?

also another question, if i move (with BLE 4.2 and above) to extended length packets, to increase throughput, should there be more resent packets since the risk of loosing data in a larger packet is greater ?

hope to read you soon

best regards

Ziv

Parents Reply Children
  • hi Sigurd

    You can get this info as an QoS Connection Event Report.

    i looked at the link you added and i have some questions, 

    1. if i want the count of re-transmission i actually need to sum the count of naks, crc fails and rx timeouts ? is there a better way to get how many BLE packets i sent more then once ? 

    2. when referring to event counter, does it counts number of connection event with in an established connection ? and does the above counts are counted within a connection event or throughout all the time the 2 devices are connected ? 

    one clarification, i m tx'ing a lot of data so in one connection session i will probably have many BLE connection events  

    3. if i can get the number of connection events, is it possible for me from one side (peripheral) to dictates / ask for a longer connection event in order to have less connection intervals and so more throughput ?

    4. at some point i will move to BLE 4.2 or above on the non Nordic central and then i will be able to use extended BLE packet length, sending bigger packets, might result in more packets needed to be resend cause bigger packets may have greater risk of missing some data on transmission ?

    hope to read you soon

    best regards

    Ziv

  • Hi,

    ziv123 said:

    1. if i want the count of re-transmission i actually need to sum the count of naks, crc fails and rx timeouts ? is there a better way to get how many BLE packets i sent more then once ? 

    2. when referring to event counter, does it counts number of connection event with in an established connection ? and does the above counts are counted within a connection event or throughout all the time the 2 devices are connected ? 

    Yes, it's per connection event(that happens every connection interval), so you need to sum it to get it the amount over time. This is the way to do it.

    ziv123 said:
    3. if i can get the number of connection events, is it possible for me from one side (peripheral) to dictates / ask for a longer connection event in order to have less connection intervals and so more throughput ?

    The central has the final say in what connection interval to use.

    ziv123 said:
    4. at some point i will move to BLE 4.2 or above on the non Nordic central and then i will be able to use extended BLE packet length, sending bigger packets, might result in more packets needed to be resend cause bigger packets may have greater risk of missing some data on transmission ?

    I have not seen any complaints or issues with that before. If you are sending a lot of data, that are split into many small packets, then the total on-air time is reduced with a Data Packet Length Extension, since you don't have the overhead/header data for multiple packets. Also with BLE 5.0, you have 2M PHY, so packets are sent 2x faster, that also reduces the risk of packets being affected by RF interference. 

  • Hi

    Yes, it's per connection event(that happens every connection interval), so you need to sum it to get it the amount over time. This is the way to do it.

    1. our connection interval is the minimum 7.5mlsec, is it enough time to get all the info summed (we also read data from external flash and build packets while transmitting) ?

    2. i did not understood from your question if i need to sum the

    (nak count + crc_fail count + rx_timeout count = re tx count) , or am i missing something ? 

    3.  if the report is per connection event then the event counter is llike a running index counting how many connection event there have been so far, meaning the last one is the total connection event happend in one connection session between 2 devices ?

    The central has the final say in what connection interval to use.

    the central does have the final say but if i want the peripheral to ask for longer connection events, how can i do it ?

    I have not seen any complaints or issues with that before

    i am not complaining :) and obviously throughput should be better, but i just wonder if there is some data or some ratio of packet size vs probability to have to resent it since our devices are sometimes installed in challenging environments BLE wise

  • 1. our connection interval is the minimum 7.5mlsec, is it enough time to get all the info summed (we also read data from external flash and build packets while transmitting) ?

    Yeah, that shouldn't be a problem.

    2. i did not understood from your question if i need to sum the

    (nak count + crc_fail count + rx_timeout count = re tx count) , or am i missing something ? 

    Yes, you need to sum it.

    3.  if the report is per connection event then the event counter is llike a running index counting how many connection event there have been so far, meaning the last one is the total connection event happend in one connection session between 2 devices ?

    One report will be generated every connection event. If you add some counter in your application, that you increment each time you get this event, then yes, that would be the total amount of connection events happened in one connection session between 2 devices.(Assuming your device is only connected to 1 device.)

    the central does have the final say but if i want the peripheral to ask for longer connection events, how can i do it ?

    By default, we extend the connection event as long as there are packets to be sent. If there is no more data to send, the connection event is closed. There is no option in the spec to ask the central for "longer connect events".

  • hi Sigurd

    i tried to use the same function as in the example, with some minor modifications. 

    static bool on_vs_evt(struct net_buf_simple *buf)
    {
        uint8_t                                      code;
        sdc_hci_subevent_vs_qos_conn_event_report_t *evt;
    
        code = net_buf_simple_pull_u8(buf);
        if (code != SDC_HCI_SUBEVENT_VS_QOS_CONN_EVENT_REPORT)
        {
            return false;
        }
    
        evt = (void *)buf->data;
        con_event_info.nak_count += evt->nak_count;
        con_event_info.crc_err_count += evt->crc_error_count;
        con_event_info.timeout_disconnection_count += evt->rx_timeout;
    
        con_event_info.con_event_count += evt->event_counter;
    
        return true;
    }
    
    static int enable_qos_conn_evt_report(void)
    {
        int             err;
        struct net_buf *buf;
    
        err = bt_hci_register_vnd_evt_cb(on_vs_evt);
        if (err)
        {
            printk("Failed registering vendor specific callback (err %d)\n", err);
            return err;
        }
    
        sdc_hci_cmd_vs_qos_conn_event_report_enable_t *cmd_enable;
    
        buf = bt_hci_cmd_create(SDC_HCI_OPCODE_CMD_VS_QOS_CONN_EVENT_REPORT_ENABLE, sizeof(*cmd_enable));
        if (!buf)
        {
            printk("Could not allocate command buffer\n");
            return -ENOMEM;
        }
    
        cmd_enable = net_buf_add(buf, sizeof(*cmd_enable));
        cmd_enable->enable = true;
    
        err = bt_hci_cmd_send_sync(
            SDC_HCI_OPCODE_CMD_VS_QOS_CONN_EVENT_REPORT_ENABLE, buf, NULL);
        if (err)
        {
            printk("Could not send command buffer (err %d)\n", err);
            return err;
        }
    
        printk("Connection event reports enabled\n");
        return 0;
    }

    where should i put the ' enable_qos_conn_evt_report() ' call ? cause if i put it when i init the BLE here:

    static void augu_com_start_ble(void)
    {
        int rc;
    
        rc = STATS_INIT_AND_REG(smp_svr_stats, STATS_SIZE_32, "smp_svr_stats");
        __ASSERT(rc == 0, "failed in STATS_INIT_AND_REG");
    
    
        ///////////////////////
        enable_qos_conn_evt_report();
    ///////////////////////
    #ifdef CONFIG_FILE_SYSTEM
        fs_mgmt_register_group();
        os_mgmt_register_group();
        img_mgmt_register_group();
        stat_mgmt_register_group();
    #endif
        /* Enable Bluetooth. */
        rc = bt_enable(bt_ready);
        if (rc != 0)
        {
            AUGU_LOG_ERR("Bluetooth init failed (err %d)", rc);
            return;
        }
    
        bt_conn_cb_register(&conn_callbacks);
    
        /* Initialize the Bluetooth mcumgr transport. */
        smp_bt_register();
    
        commands_service_init();
    #if defined(CONFIG_BOARD_CANARY_TYPE)
        testing_service_init();
    #endif
        halo_svc_init();
        cts_init();
    
        if (IS_ENABLED(CONFIG_BT_SETTINGS))
        {
            settings_load();
        }
    
        k_sem_take(&bt_ready_sem, K_FOREVER);
    }

    then i get 

    00> ASSERTION FAIL [err == 0] @ WEST_TOPDIR/zephyr/subsys/bluetooth/host/hci_core.c:327
    00> 
    00>   k_sem_take failed with err -11
    00> 
    00> [00000010] <err> os: r0/a1:  0x00000003  r1/a2:  0x00000002  r2/a3:  0x00000001
    00> [00000010] <err> os: r3/a4:  0x20003cd8 r12/ip:  0x0000000a r14/lr:  0x00022087
    00> [00000010] <err> os:  xpsr:  0x41000000
    00> [00000010] <err> os: s[ 0]:  0x00000000  s[ 1]:  0x00000000  s[ 2]:  0x00000000  s[ 3]:  0x00000000
    00> [00000010] <err> os: s[ 4]:  0x00000000  s[ 5]:  0x00000000  s[ 6]:  0x00000000  s[ 7]:  0x00000000
    00> [00000010] <err> os: s[ 8]:  0x00000000  s[ 9]:  0x00000000  s[10]:  0x00000000  s[11]:  0x00000000
    00> [00000010] <err> os: s[12]:  0x00000000  s[13]:  0x00000000  s[14]:  0x00000000  s[15]:  0x00000000
    00> [00000010] [1;31m<err> os: fpscr:  0x20006518
    00> [00000010] <err> os: r4/v1:  0x2002446c  r5/v2:  0x00000000  r6/v3:  0xfffffff5
    00> [00000010] <err> os: r7/v4:  0x20022a10  r8/v5:  0x0000fd04  r9/v6:  0x20008250
    00> [00000010] <err> os: r10/v7: 0x00000000  r11/v8: 0x00000000    psp:  0x200229a8
    00> [00000010] <err> os: EXC_RETURN: 0x0
    00> [00000010] <err> os: Faulting instruction address (r15/pc): 0x00022092
    00> [00000046] <err> os: ***** HARD FAULT *****
    00> [00000046] <err> os:   Debug event
    00> [00000046] <err> os: r0/a1:  0x00000000  r1/a2:  0x00000000  r2/a3:  0x45524f43
    00> [00000046] <err> os: r3/a4:  0x80000000 r12/ip:  0x0000000a r14/lr:  0x00054fb9
    00> [00000046] <err> os:  xpsr:  0x8100000b
    00> [00000046] <err> os: s[ 0]:  0x00000000  s[ 1]:  0x00000000  s[ 2]:  0x00000000  s[ 3]:  0x00000000
    00> [00000046] <err> os: s[ 4]:  0x00000000  s[ 5]:  0x00000000  s[ 6]:  0x00000000  s[ 7]:  0x00000000
    00> [00000046] [1;31m<err> os: s[ 8]:  0x00000000  s[ 9]:  0x00000000  s[10]:  0x00000000  s[11]:  0x00000000
    00> [00000046] <err> os: s[12]:  0x00000000  s[13]:  0x00000000  s[14]:  0x00000000  s[15]:  0x00000000
    00> [00000046] <err> os: fpscr:  0x200220e0
    00> [00000046] <err> os: r4/v1:  0x20022158  r5/v2:  0x0000244d  r6/v3:  0x2000b5f4
    00> [00000046] <err> os: r7/v4:  0x20022188  r8/v5:  0x200220f4  r9/v6:  0x00000003
    00> [00000046] [1;31m<err> os: r10/v7: 0x00000003  r11/v8: 0x20022170    psp:  0x200229a8
    00> [00000046] <err> os: EXC_RETURN: 0xffffffe1
    00> [00000046] <err> os: Faulting instruction address (r15/pc): 0x0005430c
    00> [00000046] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
    00> [00000046] <err> os: Fault during interrupt handling
    00> 
    00> [00000046] <err> os: Current thread: 0x20006518 (main)[0m
    00> [00000047] <err> fatal_error: Resetting system
    00> *** Booting Zephyr OS build v3.1.99-ncs1  ***

    if i move it to other place in the BLE init call:

    static void augu_com_start_ble(void)
    {
        int rc;
    
        rc = STATS_INIT_AND_REG(smp_svr_stats, STATS_SIZE_32, "smp_svr_stats");
        __ASSERT(rc == 0, "failed in STATS_INIT_AND_REG");
    
    #ifdef CONFIG_FILE_SYSTEM
        fs_mgmt_register_group();
        os_mgmt_register_group();
        img_mgmt_register_group();
        stat_mgmt_register_group();
    #endif
        /* Enable Bluetooth. */
        rc = bt_enable(bt_ready);
        if (rc != 0)
        {
            AUGU_LOG_ERR("Bluetooth init failed (err %d)", rc);
            return;
        }
    
        bt_conn_cb_register(&conn_callbacks);
    
        ///////////////////////
        enable_qos_conn_evt_report();
        ///////////////////////
        /* Initialize the Bluetooth mcumgr transport. */
        smp_bt_register();
    
        commands_service_init();
    #if defined(CONFIG_BOARD_CANARY_TYPE)
        testing_service_init();
    #endif
        halo_svc_init();
        cts_init();
    
        if (IS_ENABLED(CONFIG_BT_SETTINGS))
        {
            settings_load();
        }
    
        k_sem_take(&bt_ready_sem, K_FOREVER);
    }

    then i get '0' for all event report values (i know i am transferring data so there must be connection events and packet transfers).

    if i put the enable qos call it in the 'connected' callback then again i get '0' for all values in the event report

    (p.s. what qos and vs stands for ?)

    hope to read you soon

    best regards

    Ziv 

Related