This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Increasing BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT

I'm attempting to increase the size of the TX Queue in an effort to increase notification performance.   

I'm using nRF52840 with an S140 soft device.   I use Segger Embedded Studio and am using the Laird Connectivity BL-654 DVK evaluation board.

The following defines have been modified in sdk_config.h

#define NRF_SDH_BLE_GAP_DATA_LENGTH 251

#define NRF_SDH_BLE_GAP_EVENT_LENGTH 320

#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247

I call:

void connEvtLenExtSet(bool onOff) {
  ret_code_t err_code;
  ble_opt_t opt;

  memset(&opt,0,sizeof(opt));
  opt.common_opt.conn_evt_ext.enable= onOff ? 1 : 0;

  err_code= sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
  APP_ERROR_CHECK(err_code);
}

after gap and gatts are initialized:

    // Configure and initialize the BLE stack.
    ble_stack_init();

    // Initialize modules.
    timers_init();
    buttons_leds_init(&erase_bonds);
    gap_params_init();
    gatt_init();
    //dataLenExtSet();
    connEvtLenExtSet(true);
    advertising_init();
    services_init();
    sensor_simulator_init();
    conn_params_init();
    peer_manager_init();

    // Initialize the Queues
    bleNotificationsWritten= 0;
    bleNotificationsSent= 0;
    bleNotificationsFailed= 0;
    bleNotificationsReceived= 0;
    bleNotificationsAvailable= BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT;

This code also initializes some counters to keep track of notifications, including "bleNotificationsAvailable" that should monitor how many TX Queue entries are available.

I update the Phy to use 2MBPS using:

void updatePhy(uint16_t handle) {
  ret_code_t err_code;
  ble_gap_phys_t phys = {
    //.tx_phys = BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_1MBPS,
    //.rx_phys = BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_1MBPS

    .tx_phys = BLE_GAP_PHY_2MBPS,
    .rx_phys = BLE_GAP_PHY_2MBPS
  };
  NRF_LOG_DEBUG("PHY update set.");

  err_code= sd_ble_gap_phy_update(handle, &phys);
  APP_ERROR_CHECK(err_code);
}

This is called after the connection is established:

        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("Connected");
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
            APP_ERROR_CHECK(err_code);
            updatePhy(m_conn_handle);
            break;

I keep track of the number of notifications being processed using the variable "bleNotificationsAvailable".   It is initialized to BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT.

I changed BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT to 20 in ble_gatts.h

This variable is incremented by the number of notifications sent in the BLE callback:

        case BLE_GATTS_EVT_HVN_TX_COMPLETE:
            bleNotificationsSent= bleNotificationsSent + p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count;
            bleNotificationsAvailable= bleNotificationsAvailable + p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count;
            NRF_LOG_DEBUG("HVN_TX_COMPLETE: Packets: %d",p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count);
            // Wake the Send process
            xTaskNotify(SendTaskHandle,SEND_PACKET_QUEUED,eSetBits);
            break;

        case BLE_GATTS_EVT_HVC:
            bleNotificationsReceived++;
            break;

and is decremented when a notification is requested to be sent:

Since Notifications can be sent by multiple sensors, the "Send" code is consolidated in one FreeRTOS task.   This is the body of the task:

for (;;) {
    // Block until something appears in the queue...
    // Only bit that should cause Notification is SEND_PACKET_QUEUED, so don't even check...
    xTaskNotifyWait(0x00,             // Don't clear any bits on entry
                    ~0x00,            // Clear all bits on exit
                    &bleSendNotifyBits,
                    portMAX_DELAY);   // Block indefinitely
    
    // While there is space in the BLE queue AND there are packets to send...
    while(    (bleNotificationsAvailable > 2) 
           && (uxQueueMessagesWaiting(characteristicQueue) > 0) ) {
      // Still room in TX QUEUE and a characteristic is waiting in the queue
      // Read the queue item
      xStatus= xQueueReceive(characteristicQueue,&charToSend,0);
      if( xStatus == pdPASS ) {	// Read from queue was successful
        ble_gatts_hvx_params_t hvx_params;

        memset(&hvx_params, 0, sizeof(ble_gatts_hvx_params_t));

        size                   = charToSend.size;

        hvx_params.handle      = charToSend.charHandle;
        hvx_params.type        = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset      = 0;
        hvx_params.p_len       = &size;
        hvx_params.p_data      = charToSend.charPtr;

        err_code= sd_ble_gatts_hvx(charToSend.connHandle,&hvx_params);
        // size will reflect the number of bytes sent
        if(    (err_code == NRF_SUCCESS)
            && (charToSend.size == size)
          ) {
          bleNotificationsAvailable--;
        } else {
          bleNotificationsFailed++;
          NRF_LOG_DEBUG("Packet Send Failure: %d : %d",err_code,bleNotificationsAvailable);
          break;
          //APP_ERROR_CHECK(err_code);
        }
      } else {
        break;
      }
    }
  }

This task will send Notifications as long as there is TX queue space available and as long as a notification is present in the queue (from other tasks that handle sensors).

I thought using this code would eliminate getting NRF_ERROR_RESOURCES errors, but I still get them.  If I increase the connect intervals (from 7.5 ms to 15 or 30 ms) the number of errors increases.

When an error occurs, the error code indicates NRF_ERROR_RESOURCES and the value of bleNotificationsAvailable is 16.    So (theoretically) there should be queue space.

Here is the code where the intervals are defined:

#define MIN_CONN_INTERVAL                   MSEC_TO_UNITS(7.5, UNIT_1_25_MS)        /**< Minimum acceptable connection interval (0.4 seconds). */
#define MAX_CONN_INTERVAL                   MSEC_TO_UNITS(650, UNIT_1_25_MS)        /**< Maximum acceptable connection interval (0.65 second). */

I though that perhaps there was some sort of race condition, so I increased the comparison (as shown above) for the number of free TX queue entries to 2.   So when I activate the "Send" task, there should be at least 2 free TX queue slots or no call to sd_ble_gatts_hvn should be made.

However, I still get a lot of debug print statements indicating packet failures with NRF_ERROR_RESOURCES and supposedly 16 empty TX queue slots.

For completion, here is the code for a testing task that sends packets.   For now I'm just using one that sends a packet about every 7.6 ms.   The characteristic size is 244 bytes.

    // Send value if connected and notifying
    if (service->conn_handle != BLE_CONN_HANDLE_INVALID) {

        charQueueItem          thisChar;

        thisChar.connHandle      = service->conn_handle;
        thisChar.charHandle      = service->mic_data_handles.value_handle;
        thisChar.size            = sizeof(micDataCharacteristic);
        thisChar.charPtr         = (uint8_t *)charToSend;

        // Send the packet info
        xStatus= xQueueSendToBack(characteristicQueue, &thisChar, 0);
        if(xStatus != pdPASS ) {
          itemsInQueue= uxQueueMessagesWaiting(characteristicQueue);
          //fprintfsock("Could not send MIC packet to the queue.\n");
          while(1);
        }
        // Increment the written count
        bleNotificationsWritten++;
        // Wake the Send process
        xTaskNotify(SendTaskHandle,SEND_PACKET_QUEUED,eSetBits);

    } else {
        err_code = NRF_ERROR_INVALID_STATE;
    }

This creates a FreeRTOS queue item that includes information about the connection handle, the characteristic handle, a pointer to the characteristic value to be sent, etc. and sends it to the queue.   It also wakes the Send task to actually send the notification if conditions permit.     If the notification can't be sent, the queue item won't be consumed.   When a BLE_GATTS_EVT_HVN_TX_COMPLETE arrives, the bleNotificationsAvailable variable is updated and the Send Task is notified to check if anything should be sent.

I didn't expect to see the NRF_ERROR_RESOURCES.   Are there any other conditions (besides the TX QUEUE being overrun) that I should consider?   My variable indicates that there are 16 slots available when the error occurs.

I am attempting to receive the notifications on a Samsung S8 running Android 9.   I have used LightBlue, nRF Connect, and my own Android app as receiving apps (central) and all do pretty much the same thing. 

I'm not getting anywhere near the data rate I expected.   I need to send 244 bytes every 7.5 ms, which is just over 256 Kbps.   Shouldn't this be possible with BLE 5.x?

What am I doing wrong???

Thanks!

  • Hi,

    I changed BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT to 20 in ble_gatts.h

    Changing defines in SDK headers is not a right way. You're free to adjust settings in sdk_config.h and via SoftDevice API, but changing anything in SDK header files could only break things down.

    To set the number of TX buffers explicitly, use sd_ble_cfg_set() call with BLE_CONN_CFG_GATTS and ble_gatts_conn_cfg_t.hvn_tx_queue_size. According to this thread, Softdevice will adjust buffer count when you change event length, but this logic is unclear - in your case it seems the queue is increased to four entries.

    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.4 seconds). */
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(650, UNIT_1_25_MS) /**< Maximum acceptable connection interval (0.65 second). */
    

    Don't you think the window is too wide? The central will decide whether to choose 7.5 or 650 msec interval. The length of connection event is also depends on central - some Android phones don't allow to send more than 1 packet per connection event and limited with 23-byte MTU - in worst case you will have a throughput of 20 bytes per 0.65 second. In general, phones don't allow long connection events because they have a single radio shared between Bluetooth and wifi. To increase throughput, you should set as lower connection interval as possible.

    If you already have an RTOS queue, it makes no sense to have another long HVN queue inside Softdevice - it's just a waste of memory. The HVN queue should be long enough to not interrupt a connection event because of empty queue if RTOS is not in time to put next message.

  • Thanks for your response!

    I changed BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT back to 1 in ble_gatts.h and used sd_ble_cfg_set() to set the TX queue size to 4. 

    I also changed the MAX_CONN_INTERVAL to 50 ms, so the min/max is now 7.5/50 ms  (Later I tried 15/50.)

    I increased the RTOS queue depth to 32 and changed the comparison of bleNotificationsAvailable to 0 in the Send task (eg. if  bleNotificationsAvailable > 0    where it had compared to 2).

    I can see verification of the ATT MTU size being increased to 247 and the request for the data length to be 251 (as set in sdk_config.h (#define NRF_SDH_BLE_GAP_DATA_LENGTH 251)) in the Debug Terminal log, but later the log shows the max_rx/tx_octets to be 27.     

    I've read "conflicting" posts as to whether or not there is a specific call to enable DLE (Data Length Enable) on the S140 soft device.   I'm currently under the belief that setting NRF_SDH_BLE_GAP_EVENT_LENGTH to 320 is enough to automatically enable DLE and that there will be enough time to transmit characteristics of at least 244 bytes.

    Is there anything else I need to do to enable sending 244 byte characteristics in a single transmission?   Or to enable > 1 Notification per connect interval?

    My example runs for a short period before stopping at the "while(1)" in the "testing" task since the RTOS queue of characteristics to send fills up.

    I believe that the Nordic demo video showing (almost real-time) video uses a Samsung S8 conversing with the nRF52840.

    Here is the output of the Debug Terminal

    <debug> nrf_sdh: Notify observer 0x000391FC => ready
    <debug> nrf_sdh: State change: 0x00000000
    <debug> nrf_sdh: State change: 0x00000001
    <debug> nrf_sdh_ble: RAM starts at 0x20002EE0
    <debug> nrf_sdh_freertos: Creating a SoftDevice task.
    <info> app: HRS FreeRTOS example started.
    <debug> nrf_sdh_freertos: Enter softdevice_task.
    <info> app: Fast advertising.
    <debug> nrf_sdh_ble: BLE event: 0x10.
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
    <debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
    <info> app: Connected
    <debug> app: PHY update set.
    <debug> nrf_sdh_ble: BLE event: 0x24.
    <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 27
    <debug> nrf_ble_gatt: max_tx_octets: 27
    <debug> nrf_ble_gatt: max_rx_time: 328
    <debug> nrf_ble_gatt: max_tx_time: 328
    <debug> nrf_sdh_ble: BLE event: 0x3A.
    <debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
    <debug> nrf_sdh_ble: BLE event: 0x22.
    <debug> nrf_sdh_ble: BLE event: 0x22.
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <debug> nrf_sdh_ble: BLE event: 0x55.
    <debug> nrf_ble_gatt: Peer on connection 0x0 requested an ATT MTU of 247 bytes.
    <debug> nrf_ble_gatt: Updating ATT MTU to 247 bytes (desired: 247) on connection 0x0.
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <debug> nrf_sdh_ble: BLE event: 0x50.
    <debug> nrf_sdh_ble: BLE event: 0x12.

    Thanks!

  • One more comment:

    I attempted to manually enable DLE using:

    void dataLenExtSet(void) {
      ble_gap_data_length_params_t dl_params;
      uint32_t err_code;
      // Clearing the struct will effectively set members to @ref BLE_GAP_DATA_LENGTH_AUTO.  
      memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t));
      dl_params.max_tx_octets= 251;
      dl_params.max_rx_octets= 251;
      dl_params.max_tx_time_us= BLE_GAP_DATA_LENGTH_AUTO;
      dl_params.max_rx_time_us= BLE_GAP_DATA_LENGTH_AUTO;
      err_code = sd_ble_gap_data_length_update(m_conn_handle, &dl_params, NULL);
      APP_ERROR_CHECK(err_code);
      
        
      err_code = nrf_ble_gatt_data_length_set(&m_gatt, BLE_CONN_HANDLE_INVALID, 251);
      APP_ERROR_CHECK(err_code);  
    }

    This is called after a connection has been established:

            case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("Connected");
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
                APP_ERROR_CHECK(err_code);
                updatePhy(m_conn_handle);
                NRF_LOG_DEBUG("Phy updated");
                dataLenExtSet();
                NRF_LOG_DEBUG("DLE Set");
                break;

    But the log shows that max_tx_octets is still 27.   Should it be 251 after the call?

    <debug> nrf_sdh_freertos: Enter softdevice_task.
    <info> app: Fast advertising.
    <debug> nrf_sdh_ble: BLE event: 0x10.
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
    <debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
    <info> app: Connected
    <debug> app: PHY update set.
    <debug> app: Phy updated
    <debug> app: DLE Set
    <debug> nrf_sdh_ble: BLE event: 0x24.
    <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 27
    <debug> nrf_ble_gatt: max_tx_octets: 27
    <debug> nrf_ble_gatt: max_rx_time: 328
    <debug> nrf_ble_gatt: max_tx_time: 328
    <debug> app: GAP Data Length Update: 27
    <debug> nrf_sdh_ble: BLE event: 0x3A.
    <debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
    <debug> nrf_sdh_ble: BLE event: 0x22.
    <debug> nrf_sdh_ble: BLE event: 0x22.
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <debug> app: GAP Param update
    <debug> nrf_sdh_ble: BLE event: 0x55.
    <debug> nrf_ble_gatt: Peer on connection 0x0 requested an ATT MTU of 247 bytes.
    <debug> nrf_ble_gatt: Updating ATT MTU to 247 bytes (desired: 247) on connection 0x0.
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <debug> app: GAP Param update
    <debug> nrf_sdh_ble: BLE event: 0x50.
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <debug> app: GAP Param update

    Is dataLenExtSet being called at the wrong time?

    Thanks!

  • SDK library also updates MTU and data length parameters on connection established event, I dont think there's any mistake here. Could you take a trace of your connection with sniffer?

  • I found that I was using the wrong Samsung device!   Once connected to the S8, I see the 247 octet MTU accepted.

    But I'm still having problems transferring 244 byte characteristics reliably.

    I'm trying to send "continuous" notifications from a Nordic nRF52840 (peripheral) to a Samsung S8 (central) running Android 9. The phone reports that the Kernel version is: 4.4.111-17263988. I request an MTU of 247 and a Phy of 2MBPS. The characteristics being sent are 244 bytes in size and include a sequence number. Right now, I have a test loop in the peripheral that sends 1 notification every 15ms (I'd like to get it to one every 7.5ms eventually). But first, I'd like to get the notifications transmitted/received correctly! (By the way, things work well if I only send notifications every 30 ms, so this appears to be notification transmission rate dependent.)

    I set up a BLEManager as a service in the Android app, and the connection from the peripheral to the central is made, the notification is subscribed, and a command is sent from the central to the peripheral to start sending sensor data. I'm using the "stock" Android BLE library in the central (running on the S8).

    The stream of characteristics starts, with sequence numbers 0, 1, 2, and 3, but then it appears that packet 6 arrives 3 times. (in place of 4, 5, and 6). The next characteristic reported is 0x000a, so sequence numbers 7, 8, and 9 appear to have been lost.

    Originally, when a characteristic was received, I passed it to the MainActivity via "broadcastUpdate", but I thought perhaps there was too much overhead doing this, so I moved the test code that reports the notifications directly into the "OnCharacteristicChanged" callback:

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
    BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicChanged(gatt, characteristic);
        Timber.d("onCharacteristicChanged: ");
        Timber.d(" characteristic UUID: %s", characteristic.getUuid().toString());
    
    
        //broadcastUpdate(ACTION_GATT_DATA_READY, characteristic);
    
        final byte[] data = characteristic.getValue();
        ByteBuffer buf = ByteBuffer.wrap(data);
        buf.order(ByteOrder.LITTLE_ENDIAN);
    
        if (characteristic.getUuid().toString().equals(MIC_DATA_UUID)) {
            Timber.d("Data received from Microphone: %d", data.length);
    
            buf.asShortBuffer().get(micData, micWriteIndex, MIC_SAMPLES_PER_PACKET);
    
            // Service the rotating buffer write pointer
            micWriteIndex = micWriteIndex + MIC_SAMPLES_PER_PACKET;
            if (micWriteIndex >= MIC_BUFFER_SIZE) micWriteIndex = 0;
            // Read the sequence number...
            // buf pointer is still at the beginning, so
            // index of NNN skips over data we just read.
            micSeqNum = buf.getShort(MIC_SAMPLES_PER_PACKET * MIC_SAMPLE_SIZE_IN_BYTES);
            micChkSum = buf.getShort();
            Timber.d(" Mic seq: %04x Mic chk: %04x", micSeqNum, micChkSum);
    
        }
    }

    Here is a portion of the log that is produced:

    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 0000 Mic chk: 0000
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 0001 Mic chk: 0078
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 0002 Mic chk: 00f0
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 0003 Mic chk: 0168
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 0006 Mic chk: 02d0
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 0006 Mic chk: 02d0
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 0006 Mic chk: 02d0
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 000a Mic chk: 04b0
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 000b Mic chk: 0528
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 000b Mic chk: 0528
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 000b Mic chk: 0528
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 000e Mic chk: 0690
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 000e Mic chk: 0690
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 000e Mic chk: 0690
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 000e Mic chk: 0690
    > D/BLEManager: onCharacteristicChanged: D/BLEManager: characteristic
    > UUID: f000af03-0807-0605-0403-020100000000 D/BLEManager: Data received
    > from Microphone: 244 D/BLEManager: Mic seq: 0012 Mic chk: 0870

    I believe the code to receive the notifications is correct.

    I captured the btsnoop_hci (Android) log and viewed it in WireShark. It shows the same info as represented in the log above. The log of notifications being sent from the peripheral, shows all of the characteristics being sent in the correct order.

    I posted this question on an Android support site, and they claim the problem is with the peripheral (nRF52840 duplicating/dropping notifications),  My logs show the characteristics being delivered to sd_ble_gatts_hvx in order.  This function always returns NRF_SUCCESS.

    I currently don't have an air sniffer...    Is there anything else I can check to verify that the notifications are transmitting the correct characteristics?

    Thanks!

Related