Skip to main content
Explorer
January 16, 2025
Solved

ST25R3920B for OOB Bluetooth Pairing

  • January 16, 2025
  • 16 replies
  • 6206 views

Hello everyone,

I am using the X-NUCLEO-NFC08A1 NFC Shield that has the ST25R3920B chip. I want to know if it is possible to use this to make OOB Bluetooth with my android smartphone, and if so how can I achieve it. I read some documentation regarding the demos in X-Cube-NFC6 with card emulation, but I don´t if that is suitable for what I am trying to achieve.

 

    This topic has been closed for replies.
    Best answer by Brian TIDAL

    Hi,

    the NFC Forum "Bluetooth® Secure Simple Pairing Using Version 1.3" application document only defines the following mimes types:

    • application/vnd.bluetooth.ep.oob (BR/EDR)
    • application/vnd.bluetooth.le.oob (BLE)

    In this document, "application/vnd.bluetooth.le.oob" is being used even with Secure Connections Random Value EIR and Secure Connections Confirmation Value EIR.

    Can you try to encode your record using application/vnd.bluetooth.le.oob (NDEF_TYPE_ID_BLUETOOTH_LE) and with your:

    • LE Role EIR
    • LE Bluetooth Device Address EIR
    • Secure Connections Random Value EIR
    • Secure Connections Confirmation Value EIR

    Rgds

    BT

    16 replies

    JPortilhaAuthor
    Explorer
    January 24, 2025

    Hello,

    I have a small update. If I initiate the record as Bluetooth Classic everything is okay I can sucessfully pair my smartphone. However, when I use Bluetooth LE record I start to have the mentioned problems. Can you tell me why? Is there any additional code that I should add?

    BR.

    Technical Moderator
    January 24, 2025

    Hi,

    what is the content of the memory when using the Bluetooth LE record? Can you scan it with ST25NFCTap if you disable Felica or with TagInfo if you want to emulate both Felica and T4T.

    Make sure that your encode function does not return an error.

    Rgds

    BT

    JPortilhaAuthor
    Explorer
    January 27, 2025

    Hello,

    For some reason whenever the logs in terminal indicate "Activated in CE NFC-A mode", from the demoCycle function my smartphone does not detect the tag. Only when the log indicates "Activated in CE NFC-F mode" is possible to read. Do you know why this is happening?

    Additionaly, when I use the ndefBluetoothBrEdrInit, I can sucessfully read the memory using TagInfo application (print below). However when I use the ndefBluetoothLeInit the application says that the tag memory is empty. Can this be an hardware problem rather than software?

    Screenshot_2025-01-27-09-20-28-765_com.nxp.taginfolite.jpg

     

    BR

     

    Technical Moderator
    January 27, 2025

    Hi

    "Do you know why this is happening?" difficult to comment on this. Have you tried with another Androïd phone?

    "Can this be an hardware problem rather than software?" As the tag memory is software emulated, this can hardly be an hardware problem. If the tag memory is reported as empty, this is because demoEncodeBluetoothRecord encounters an error: run the debugger and step into demoEncodeBluetoothRecord and check the content of ndefFile[] when returning from demoEncodeBluetoothRecord (in particular ndefFile[0] and ndefFile[1] that encode the NDEF file length).

    Rgds

    BT

    JPortilhaAuthor
    Explorer
    January 27, 2025

    Hello, 

    Yes I have tried with Samsung Galaxy A13 (older smartphone) and a Xiaomi 14T (late 2024 smartphone) and the result is the same with both.

    From debug the demoEncodeBluetoothRecord returns 0, so no error. Here is my code snippet:

    static uint8_t ndefFile[128]; 
    const uint8_t *demoNdefFile = ndefFile; 
    uint32_t demoNdefFileLen = sizeof(ndefFile);
    
    rc = bleHandler.SetOOBPairData(ndefFile, sizeof(ndefFile));
     if(rc != ERR_NONE)
     Log("Error encoding\n");
     Log("Ndef file: %s\n", hex2Str(ndefFile, sizeof(ndefFile)));

    The output of the ndefFile is:
     002BD2200E6170706C69636174696F6E2F766E642E626C7565746F6F74682E6C652E6F6F6207094343435F444B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    This means that the memory has data, however is seems that is not being correctly written in the tag.

    BR

    Technical Moderator
    January 27, 2025

    Hi,

    "however is seems that is not being correctly written in the tag": there is no tag... This is card emulation. The card emulation reads the data from the ndefFile[] buffer.

    The content of ndefFile is wrongly encoded.

    002B Length of the NDEF (43 bytes)

    D2 Record Header

    20 Record type Length (32)

    0E Payload Length (14 bytes)

    ==> the message length is

    • 1 byte for the record header +
    • 1 byte for the record type length byte+
    • 1 byte for the payload length byte +
    • 32 bytes for the record type
    • 14 bytes for the payload

    Total is 49 types. As the 2 first bytes indicates a total length of 43 bytes, the message cannot be decoded by the mobile phone.

    With the proper message length (i.e. 0x31), the BLE pairing record is correctly decoded:

    BrianTIDAL_0-1737981594127.png

    Make sure to properly encode your BLE pairing record and to update ndefFile[0] and ndefFile[1] with the proper NDEF message length.

    Rgds

    BT

    Technical Moderator
    January 27, 2025

    Hi,

    the bufDeviceAddress should be populated only in BR/DR case. Therefore the following lines:

    BrianTIDAL_0-1737998064327.png

    should be replaced by:

    /* Mandatory field: bufDeviceAddress - Device Address (only for BR/EDR) */
     ndefConstBuffer bufDeviceAddress = { (uint8_t *) oob_data.addr.a.val, 0 };
     bluetooth.bufDeviceAddress = bufDeviceAddress;

    Having bufDeviceAddress different from 0 in case of BLE causes a side effect on the payload length computation. I have reported this to the development team in order to improve the robustness.

    The payload should now have the correct length and it should be possible to properly decode the NDEF message.

    Rgds

    BT

    JPortilhaAuthor
    Explorer
    January 27, 2025

    Hello, quick update: I have now this function to set LE record with informations like flags, Random and Confirmation value, as well as TK (necessary for OOB Pairing in LE secure connections). This is my function:

     

    int BLEHandler::SetOOBPairData(uint8_t *buffer, uint32_t length)
    {
     ndefTypeBluetooth bluetooth;
     ndefRecord record;
     ndefType ndefBt;
     ndefStatus rc;
    
     if (buffer == NULL)
     return ERR_PARAM;
    
     /* Reset bluetooth record */
     rc = ndefBluetoothReset(&bluetooth);
     if (rc != ERR_NONE)
     return rc;
    
     /* Get bluetooth informations - Address, Address Type, Random and Confirm value */
     rc = bt_le_oob_get_local(0, &oob_data);
    
     /* Mandatory field: bufDeviceAddress - Device Address (only for BR/EDR) */
     ndefConstBuffer bufDeviceAddress = { (uint8_t *) oob_data.addr.a.val, 6 };
     bluetooth.bufDeviceAddress = bufDeviceAddress;
    
     /* Optional fields: Extended Inquiry Responses. Up to 8 data structures
     * According to BLE spec, the data format should be: Length, EIR Data Type, EIR Data
     */
     /* EIR Field 0: LE Flags */
     uint8_t eirLeFlags[3] = { 2, NDEF_BT_EIR_FLAGS, 0x02 };
     
     /* EIR Field 1: LE Device Address - 6 LSB bytes: Device address, 7th byte: Address type (Public/Random) */
     uint8_t eirLeAddress[9] = { 8, NDEF_BT_EIR_LE_DEVICE_ADDRESS };
     memcpy(&eirLeAddress[2], oob_data.addr.a.val, 6);
     eirLeAddress[8] = oob_data.addr.type;
    
     /* EIR Field 2: LE Role - Peripheral */
     uint8_t eirLeRole[] = { 2, NDEF_BT_EIR_LE_ROLE, NDEF_BLE_ROLE_PERIPH_ONLY };
    
     /* EIR Field 3: Device local name */
     uint8_t localName[] = { 'C', 'C', 'C', '_', 'D', 'K' };
     uint8_t eirLocalName[8] = { 1 + sizeof(localName), NDEF_BT_EIR_COMPLETE_LOCAL_NAME };
     memcpy(&eirLocalName[2], localName, sizeof(localName));
    
     /* EIR Field 4: Temporary Key (TK) for secure pairing */
     /* Generate random TK */
     uint8_t tk[16];
     rc = bt_rand(tk, 16);
     if(rc)
     Log("Error generating TK value\n");
     uint8_t eirTk[18] = { 17, NDEF_BT_EIR_SECURITY_MANAGER_TK_VALUE };
     memcpy(&eirTk[2], tk, sizeof(tk)); // Append the TK value after the length
    
     /* EIR Field 5: Confirmation Value - Needed for LE Secure Connections */
     uint8_t eirSecureConnConfirmation[18] = { 17, NDEF_BT_EIR_LE_SECURE_CONN_CONFIRMATION_VALUE };
     memcpy(&eirSecureConnConfirmation[2], oob_data.le_sc_data.c, 16);
    
     /* EIR Field 6: Randomizer Value - Needed for LE Secure Connections */
     uint8_t eirSecureConnRandom[18] = { 17, NDEF_BT_EIR_LE_SECURE_CONN_RANDOM_VALUE };
     memcpy(&eirSecureConnRandom[2], oob_data.le_sc_data.r, 16);
    
     rc = ndefBluetoothSetEir(&bluetooth, (uint8_t *) &eirLeFlags);
     if (rc != ERR_NONE)
     {
     Log("Erro encoding flags\n");
     return rc;
     }
     
     rc = ndefBluetoothSetEir(&bluetooth, (uint8_t *) &eirLeAddress);
     if (rc != ERR_NONE)
     {
     Log("Erro encoding address\n");
     return rc;
     }
    
     rc = ndefBluetoothSetEir(&bluetooth, (uint8_t *) &eirLeRole);
     if (rc != ERR_NONE)
     {
     Log("Erro encoding LE role\n");
     return rc;
     }
    
     rc = ndefBluetoothSetEir(&bluetooth, (uint8_t *) &eirLocalName);
     if (rc != ERR_NONE)
     {
     Log("Erro encoding local name\n");
     return rc;
     }
    
     rc = ndefBluetoothSetEir(&bluetooth, (uint8_t *) &eirTk);
     if (rc != ERR_NONE)
     {
     Log("Erro encoding TK\n");
     return rc;
     }
    
     rc = ndefBluetoothSetEir(&bluetooth, (uint8_t *) &eirSecureConnConfirmation);
     if (rc != ERR_NONE)
     {
     Log("Erro encoding Confirm\n");
     return rc;
     }
    
     rc = ndefBluetoothSetEir(&bluetooth, (uint8_t *) &eirSecureConnRandom);
     if (rc != ERR_NONE)
     {
     Log("Erro encoding Random\n");
     return rc;
     }
     
     rc = ndefBluetoothLeInit(&ndefBt, &bluetooth);
     if (rc != ERR_NONE)
     {
     Log("Erro Init LE\n");
     return rc;
     }
    
     rc = ndefTypeToRecord(&ndefBt, &record);
     if (rc != ERR_NONE)
     return rc;
    
     /* Encode the record starting after the first two bytes that are saved to store the NDEF file length */
     ndefBuffer bufRecord = { &buffer[2], length - 2 };
     rc = ndefRecordEncode(&record, &bufRecord);
     if (rc != ERR_NONE)
     {
     Log("Erro Encode: %d\n", rc);
     return rc;
     }
    
     /* Store the NDEF file length on the two first bytes */
     buffer[0] = bufRecord.length >> 8;
     buffer[1] = bufRecord.length & 0xFF;
    
     Log("NDEF file length: %d\n", bufRecord.length);
    
     return rc;
    }

    I was abble to read some information with my smartphone, however I got "No DEF Data Storage Populated" and the pairing does not work as in classical.
    Screenshot_2025-01-27-12-23-03-508_com.nxp.taginfolite.jpg

    JPortilhaAuthor
    Explorer
    January 28, 2025

    Hello, 

    Yes that seems correct, now I can start a legacy BLE pairing. Does the same logic apply to LE Secure Connections? When I init a LESC record instead of a normal one I stop being able to start pairing. I am sending Random and Confirm value instead of TK. Do I need anything else?

    BR.

    Technical Moderator
    January 28, 2025

    Hi,

    when using secure BLE pairing record, have you checked with TagInfo that the record is properly decoded ?

    Then, I have no specific information about how Android supports secure BLE pairing record.

    Rgds

    BT

    JPortilhaAuthor
    Explorer
    January 28, 2025

    Hello,

    I think everything is OK with the record, the smartphone can decode it as a LE Secure Connection Bluetooth Record, however when I tap the phone the pairing does not start as it happens with normal BLE.

    Screenshot_2025-01-28-12-12-33-148_com.nxp.taginfolite.jpgScreenshot_2025-01-28-12-12-27-951_com.nxp.taginfolite.jpg

    BR

    Technical Moderator
    January 28, 2025

    Hi,

    the NFC Forum "Bluetooth® Secure Simple Pairing Using Version 1.3" application document only defines the following mimes types:

    • application/vnd.bluetooth.ep.oob (BR/EDR)
    • application/vnd.bluetooth.le.oob (BLE)

    In this document, "application/vnd.bluetooth.le.oob" is being used even with Secure Connections Random Value EIR and Secure Connections Confirmation Value EIR.

    Can you try to encode your record using application/vnd.bluetooth.le.oob (NDEF_TYPE_ID_BLUETOOTH_LE) and with your:

    • LE Role EIR
    • LE Bluetooth Device Address EIR
    • Secure Connections Random Value EIR
    • Secure Connections Confirmation Value EIR

    Rgds

    BT