This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nRF Sniffer BLE4 Packets Malformed using RADIO Peripheral

Hello,

I am using the RADIO peripheral to send BLE 4 advertising packets back and forth between 2 DK's (nrf52840 as transmitter, nrf52833 as receiver) following the radio examples given in the nRF5 SDK. I modified the RADIO configuration to conform to BLE 4 and sending a data packet between the 2 DK's works as expected with seeing the same packet on the receiving side as the transmitting side. I am trying to view the raw data using nRF Sniffer with a nrf52840 Dongle as the device with the nRF Sniffer firmware on it following the guide here: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fstruct_sdk%2Fstruct%2Fsdk_nrf5_latest.html&cp=7_1 

It appears the dongle is working correctly because I can see other bluetooth devices in my room when the DK's are off (speakers, mouse etc.). When I turn on the transmitter DK, I can see an influx of Malformed packets start to appear on Wireshark. The RSSI isn't too bad (~40) as I have the dongle placed virtually right beside the transmitter so I don't think this is the issue as suggested in a similar q: https://devzone.nordicsemi.com/f/nordic-q-a/8319/nrf-sniffer-only-showing-malformed-packets-not-detecting-the-ble-packets 

I will post all relevant code and settings below in case there is something wrong in my setup. Would appreciate any advice. Thanks.

RADIO configuration:

#define BLE4_PDU_HEADER_PDU_TYPE_SIZE       (1UL)  // Size in bytes, holds PDU Type
#define PACKET_S0_FIELD_SIZE                BLE4_PDU_HEADER_PDU_TYPE_SIZE

#define BLE4_PDU_HEADER_RFU_SIZE            (2UL) // Size in bits, unused bits in MSB
#define PACKET_S1_FIELD_SIZE                BLE4_PDU_HEADER_RFU_SIZE

#define BLE4_PDU_HEADER_LENGTH_FIELD_SIZE   (6UL) // Size in bits, signifies length of payload
#define PACKET_LENGTH_FIELD_SIZE            BLE4_PDU_HEADER_LENGTH_FIELD_SIZE

//!< Size in bytes, set to 3 since total address length with prefix will be 4 after adding the prefix
#define BLE4_PACKET_BASE_ADDRESS_SIZE       (3UL)
#define PACKET_BALEN_FIELD_SIZE             BLE4_PACKET_BASE_ADDRESS_SIZE

#define BLE4_PACKET_PAYLOAD_MAX_SIZE        (37UL) // follows BLE4 max payload size of 37 bytes
#define PACKET_MAXLEN_FIELD_SIZE            BLE4_PACKET_PAYLOAD_MAX_SIZE

// BLE uses freq b/t 2400-2483.5 MHz. Freq set to 2400 + reg value
#define BLE4_ADV_CHANNEL_37                 (2UL)
#define BLE4_ADV_CHANNEL_38                 (26UL)
#define BLE4_ADV_CHANNEL_39                 (80UL)


void radio_init()
{
    NRF_RADIO->TXPOWER   = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos);
    NRF_RADIO->FREQUENCY = BLE4_ADV_CHANNEL_37;
    NRF_RADIO->MODE      = (RADIO_MODE_MODE_Ble_1Mbit << RADIO_MODE_MODE_Pos);

    /* Configure Access Address according to the BLE standard which is 0x8E89BED6 for advertising
     LSB is transmitted first hence the prefix being "after" the base */
    NRF_RADIO->PREFIX0 = 0x8e;
    NRF_RADIO->BASE0 = 0x89bed6;
    
    /* Use logical address 0 (prefix0 + base0) = 0x8E89BED6 when transmitting and receiving */
    NRF_RADIO->TXADDRESS   = 0x00UL;
    NRF_RADIO->RXADDRESSES = (RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos);

    /* PCNF-> Packet Configuration. 
     * Need to configure the sizes S0, S1 and length field to match the
     * datapacket format of the BLE4 advertisement packets. */
    NRF_RADIO->PCNF0 = (
      ((PACKET_S0_FIELD_SIZE << RADIO_PCNF0_S0LEN_Pos)     & RADIO_PCNF0_S0LEN_Msk) |
      ((PACKET_S1_FIELD_SIZE << RADIO_PCNF0_S1LEN_Pos)     & RADIO_PCNF0_S1LEN_Msk) |
      ((PACKET_LENGTH_FIELD_SIZE << RADIO_PCNF0_LFLEN_Pos) & RADIO_PCNF0_LFLEN_Msk)
    );

    // Packet configuration
    NRF_RADIO->PCNF1 = (
      //((RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) & RADIO_PCNF1_WHITEEN_Msk) |
      ((RADIO_PCNF1_WHITEEN_Enabled  << RADIO_PCNF1_WHITEEN_Pos) & RADIO_PCNF1_WHITEEN_Msk) |
      ((RADIO_PCNF1_ENDIAN_Little    << RADIO_PCNF1_ENDIAN_Pos)  & RADIO_PCNF1_ENDIAN_Msk)  |
      ((PACKET_BALEN_FIELD_SIZE      << RADIO_PCNF1_BALEN_Pos)   & RADIO_PCNF1_BALEN_Msk)   |
      ((PACKET_MAXLEN_FIELD_SIZE     << RADIO_PCNF1_MAXLEN_Pos)  & RADIO_PCNF1_MAXLEN_Msk)
    );

    /* CRC config, skip Address when computing CRC as per BLE standard */
    NRF_RADIO->CRCCNF  = (RADIO_CRCCNF_LEN_Three << RADIO_CRCCNF_LEN_Pos) |
                         (RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos); 
    NRF_RADIO->CRCINIT = 0x555555;
    NRF_RADIO->CRCPOLY = 0x00065B;                                 
}

Packet being transmitted:

static uint8_t packet[10] =
{
  0x02,                               // BLE Header (PDU_TYPE: ADV_NONCONN_IND, RXadd: 0 (public address)
  0x07,                               // Length of payload
  0x00,                               // Padding bits for S1
  0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, // AdvA, 6 bytes
  0x03                                // Payload, remaining bytes from total size - (6 + 2)
};

On Wireshark, I set the Adv Hop to be only channel 37. Another annoying thing is that filtering by source doesn't seem to work on the nRF Sniffer so all my other devices are still showing up even though I set the filter to remove those particular sources. One area I believe could be the culprit is data whitening, which I turned on and off but no change in the behaviour. 

Here is an example of a malformed packet on Wireshark:

  • Hi,

    As a start, could you do a quick comparison of your radio settings to this: https://github.com/NordicPlayground/nRF51-multi-role-conn-observer-advertiser/blob/master/btle_hci/advertiser/ts_peripheral.c#L66

    This is an older project originally written for the nRF51. But as far as I can see it should be similar for nRF52. Maybe check that you have configured the data whitening channel correctly?

  • Thank you for the resource, I added NRF_RADIO->DATAWHITEIV = 37 and looks like I had everything else right except for the NRF_RADIO->BASE0 which should be 0x89bed600 (I had 0x89bed6). After making this last change, I can at least see that the address (seen as the source in the screenshot below is de:de:de:de:de:de as expected. The raw data looks correct to me because the byte after the address is 03 as expected from the packet I am transmitting and PDU header + length fields match what's expected as well. However, the packet is still malformed.

    This leads me to believe the CRC might be the issue. The Bluetooth specification says the polynomial should be x24 + x10 + x9 + x6 + x4 + x3 + x + 1 however there are not 25 bits available in the CRCPOLY register. The example code you provided and other places I looked all use 0x00065B as the CRC polynomial which does match the polynomial in question excluding the x24. Not sure if this is by design or if potentially something else is still incorrect here.

  • Hi,
    Are you sure you are configuring your packet correctly? Seems that after the address you add only 0x03? Which means length = 0x03, which in turn means you need 3 more bytes. I.e.

    So the packet should typically look like this:

    github.com/.../main.c

  • Edit: I see what you mean after reading the suggested portion of the Bluetooth 4.2 Specification. Basically, wireshark / nRF Sniffer expect the advertising packets to follow the format shown below

    The packet I was previously sending did not respect this so wireshark was showing it as malformed.

    I guess this also explains the behaviour seen when trying to turn off data whitening where the packets are not picked up correctly because it no longer meets bluetooth spec. 

Related