cancel
Showing results for 
Search instead for 
Did you mean: 

ST25R3920B for OOB Bluetooth Pairing

JPortilha
Associate II

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.

 

28 REPLIES 28

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

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
JPortilha
Associate II

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

JPortilha
Associate II

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

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

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

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

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
JPortilha
Associate II

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.

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

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
JPortilha
Associate II

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

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

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.