KW38 - HCI Timeout on Pairing Request

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

KW38 - HCI Timeout on Pairing Request

Jump to solution
6,772 Views
jefthadsilva
Contributor III

I am writing a Client Application based on Temperature_collector example. On the Server side I have a custom BLE Service. With pairing disabled, the Client application can discover the Services on the Server and read Characteristic data. But when I enable Pairing, I see that Gap_Pair(peerDeviceId, &gPairingParameters) request is sent, but I do not receive a 'gConnEvtPairingResponse_c' in the ble_conn_manager.c. After some time I receive a HCI Connection timeout. Am I missing something here?

Client Side Pairing parameters:

gapPairingParameters_t gPairingParameters = {
    .withBonding = (bool_t)gAppUseBonding_d,
    .securityModeAndLevel = gSecurityMode_1_Level_3_c,
    .maxEncryptionKeySize = mcEncryptionKeySize_c,
    .localIoCapabilities = gIoKeyboardDisplay_c,
    .oobAvailable = FALSE,
    .centralKeys = (gapSmpKeyFlags_t) ( gLtk_c | gIrk_c ),
    .peripheralKeys = (gapSmpKeyFlags_t) ( gLtk_c | gIrk_c ),
    .leSecureConnectionSupported = TRUE,
    .useKeypressNotifications = FALSE,
};
 
Server Side Pairing Parameters:
gapPairingParameters_t gPairingParameters = {
    .withBonding = (bool_t)gAppUseBonding_d,
    .securityModeAndLevel = gSecurityMode_1_Level_3_c,
    .maxEncryptionKeySize = mcEncryptionKeySize_c,
    .localIoCapabilities = gIoDisplayOnly_c,
    .oobAvailable = FALSE,
    .centralKeys = (gapSmpKeyFlags_t) (gLtk_c | gIrk_c),
    .peripheralKeys = (gapSmpKeyFlags_t) (gLtk_c | gIrk_c),
    .leSecureConnectionSupported = TRUE,
    .useKeypressNotifications = FALSE,
};
Labels (1)
0 Kudos
Reply
1 Solution
6,483 Views
jefthadsilva
Contributor III

Hi,

We were finally able to root cause the issue. The issue was due to a watchdog timer in our code. The BLE_APP task was taking more than 40ms during pairing operation. This was happening when SecLib code was executed on the request of the BLE Host stack. Since the watchdog task could not get a chance to execute it would reset the system, causing HCI timeout on the other device. 

This was a little tricky to debug because if a debugger is connected then the watchdog gets disabled and the issue was not seen.

Your suggestion of running the code in EVM helped us during root causing the issue.

We have now moved the BLE App task to execute in the background so that the Watchdog can interrupt it. And now pairing works fine.

Thanks a lot for your support.

View solution in original post

0 Kudos
Reply
19 Replies
6,759 Views
nxf56274
NXP Employee
NXP Employee

Hi,

Do you enable the 'gAppUseBonding_d' in file 'app_preinclude.h'?

Prepare a phone that can scan the ble. When your service broadcast, use your phone to try to pair. Does your phone pop out the window like this?

IMG_20210803_104801.jpg

If so, I think that the problem may happens to client.

Please also refer the chapter 4.1.3 and 4.2.2 in attachment.

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
6,748 Views
jefthadsilva
Contributor III

Hi,

Thank you for your response.

gAppUseBonding_d and gAppUsePairing_d are enabled in both Central and Peripheral. Privacy is disabled in both.
 
I have tried with the phone using the "BLE Scanner" app on the phone. And Pairing and Bonding works fine. So I suspect the Central here. I am already referring to the Developer guide and I have followed the suggestions there.
 
Following is the sequence that happens during failure when I try with NXP Central and Peripheral:
1) Peripheral is Advertising
2) Central performs scanning, confirms from UUID if it is the right device to connect, stops scanning and initiates connection.
3) Connection successful.
4) Peripheral initiates pairing by sending "Gap_SendSlaveSecurityRequest()"
5) Central receives this request and calls Gap_Pair() api.
6) Peripheral receives the pair request in the 'gConnEvtPairingRequest_c' and calls 
Gap_AcceptPairingRequest() succesfully.
 
After this I am expecting a "gConnEvtPairingResponse_c" in the Central that never arrives. After a few seconds connection disconnects in Central with HCI Connection Timeout.
 
If Pairing and Bonding is disabled in Central side, the Central Rejects the Pairing attempt from the Peripheral and the connection remains stable. I can then read the Primary Services and GATT Characteristics that are not protected in the Peripheral without any issues.

0 Kudos
Reply
6,740 Views
nxf56274
NXP Employee
NXP Employee

Hi,

I use ble_shell example. I add this code in connection callback to test if the client can receive the gConnEvtPairingResponse_c when pair.

code.PNG

The result shows that the client can receive the 'gConnEvtPairingResponse_c'.

response.PNG

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
6,735 Views
jefthadsilva
Contributor III

Thanks again for your response. 

In my example I am waiting until the pairing is complete to even search for primary services. Do you think that can have an impact?

In your shell example that you executed was pairing done right after Connection establishment, before any GATT interactions are initiated?

Tags (1)
0 Kudos
Reply
6,714 Views
nxf56274
NXP Employee
NXP Employee

Hi,

Before doing the service discovery, I do the paring.

Actually, If you try other paring examples, they always ignore this case 'gConnEvtPairingResponse_c'. So I think we do not need to check 'gConnEvtPairingResponse_c'.

 

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
6,704 Views
jefthadsilva
Contributor III

Hi,

So if pairing is working before Service discovery in your case that means Pairing has no dependency on any GATT operation.

As for ignoring the 'gConnEvtPairingResponse_c', I specifically do not need this event, since I do not intend to take any action on it. But as soon as I start pairing I get HCI connection timeout. This is my main issue.

And as per the "Bluetooth Low Energy Application Developer's Guide.pdf", after the Pairing request from the Central, Pairing response is expected. So I suspect something is happening inside the Stack code that causes it to generate HCI timeout. Is there any debugging mechanism to further root cause the issue?

0 Kudos
Reply
6,698 Views
nxf56274
NXP Employee
NXP Employee

Hi,

How do you get the information about timeout? Which function returns this information? Show some code. 

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
6,695 Views
jefthadsilva
Contributor III

Hi,

HCI timeout is received in the "gConnEvtDisconnected_c" event with the corresponding reason.

Please find the snippet of the code attached that handles ScanCallBack and ConnectionCallBack.

Regards,

Jeftha

0 Kudos
Reply
6,692 Views
nxf56274
NXP Employee
NXP Employee

Hi,

Print every event we receive in here. Let's check the connection sequence. And check which event is handled by mcu before time out.

print.PNG

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
6,681 Views
jefthadsilva
Contributor III

Hi,

Following is the sequence of events on the hardware in the order they are received:

ConnectionCallBack events in Central:
gConnEvtConnected_c
gConnEvtSlaveSecurityRequest_c
gConnEvtLeDataLengthChanged_c
(after a gap of few seconds)
gConnEvtDisconnected_c (with reason HCI Connection Timeout)

ConnectionCallBack events In Peripheral:
gConnEvtConnected_c
gConnEvtPairingRequest_c
gConnEvtLeDataLengthChanged_c
(after a gap of few seconds)
gConnEvtDisconnected_c (with reason HCI Connection Timeout)

Also attached is the ble_conn_manager.c file that takes care of the pairing procedure. Same file is used in both peripheral and Central.

0 Kudos
Reply
6,672 Views
nxf56274
NXP Employee
NXP Employee

Hi,

Central
pConnectionEvent ->:0 gConnEvtConnected_c
Connected!

pConnectionEvent ->:2 gConnEvtSlaveSecurityRequest_c

pConnectionEvent ->:19 gConnEvtLeDataLengthChanged_c

pConnectionEvent ->:3 gConnEvtPairingResponse_c

pConnectionEvent ->:27 gConnEvtPairingAlreadyStarted_c

pConnectionEvent ->:5 gConnEvtPasskeyRequest_c

pConnectionEvent ->:11 gConnEvtEncryptionChanged_c

pConnectionEvent ->:9 gConnEvtKeysReceived_c

pConnectionEvent ->:8 gConnEvtKeyExchangeRequest_c

pConnectionEvent ->:12 gConnEvtPairingComplete_c



Peripheral

pConnectionEvent ->:0 gConnEvtConnected_c
Connected!

pConnectionEvent ->:1 gConnEvtPairingRequest_c

pConnectionEvent ->:19 gConnEvtLeDataLengthChanged_c

pConnectionEvent ->:7 gConnEvtPasskeyDisplay_c

pConnectionEvent ->:11 gConnEvtEncryptionChanged_c

pConnectionEvent ->:8 gConnEvtKeyExchangeRequest_c

pConnectionEvent ->:9 gConnEvtKeysReceived_c

pConnectionEvent ->:12 gConnEvtPairingComplete_c

This is the normal process.

You stopped at gConnEvtLeDataLengthChanged_c. But this case doesn't handled by mcu. So the problem may happens to the before message. Please debug the peripheral function 'Gap_AcceptPairingRequest', check if it accepts the paring request. The hci timeout is because after the 'gConnEvtLeDataLengthChanged_c', the master and slave doesn't send info to each other. 

 

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

6,664 Views
jefthadsilva
Contributor III

Hi,

To make sure that the AcceptPairing function works fine, I have handled the error case as below in ble_conn_mgr.c:

//(void)Gap_AcceptPairingRequest(peerDeviceId, &gPairingParameters);
bleResult_t res = Gap_AcceptPairingRequest(peerDeviceId, &gPairingParameters);
if (gBleSuccess_c != res)
{
panic(0, 0, 0, 0);

}

Additionally I put a break point at this function to make sure it is executed and I see that the functions returns with success. So that means that either the Peripheral stack did not process the AcceptPairingRequest() properly or the Central Stack did not process the Pairing response sent by the Peripheral. Sadly I do not have a Sniffer tool to capture what is happening over the air. Do you have any suggestions on what could be going wrong. For your information this is my SDK version "SDK_2.6.11_FRDM-KW38". Earlier we were using the "2.6.6" version on which this issue was originally observed and hence we upgraded to  "2.6.11".

Sincerely appreciating your support here.

0 Kudos
Reply
6,656 Views
nxf56274
NXP Employee
NXP Employee

Hi,

Do another test. Use the example 'temperature_collector ' without any modification. Use it to connect and bind. Does it work?

You need to modify the client scan callback. It will check if the scanned device has temperature profile. If your device doesn't contain, it won't connect to device. If your device doesn't contain the temperature profile, you would better comment this code. Use other way like device name to find specified device.

abbc.PNG

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 days after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

6,654 Views
jefthadsilva
Contributor III

Thanks for the suggestion. It might take me a day or two to try this out but I will come back with the results.

Thanks and Regards,

Jeftha

0 Kudos
Reply
6,607 Views
jefthadsilva
Contributor III

HI,

We were able to get our hands on the KW38 eval board. So I will use the temperature_collector example and will put my code in the "temperature_collector.c" and will check the results. Will let you know how it goes.

Regards,

Jeftha

0 Kudos
Reply
6,547 Views
jefthadsilva
Contributor III

With the KW38 Eval board (with MCUXpresso IDE) acting as the Central and our Custom hardware working as the Peripheral we see the same observation.

  1. Used the temp_collec example with the modifications you suggested to connect to the Peripheral. Connection is established but then when Pairing is initiated, we see the same timeout.
  2. Used my custom Central application on the Eval Board and I see the same issue again.

Is it possible to get logs of the Stack in MCUXpresso IDE for EVB to see what is going on inside?

Tags (1)
0 Kudos
Reply
6,528 Views
nxf56274
NXP Employee
NXP Employee

You'd better buy a ble sniffer. Analyzing the packet is more efficient.

0 Kudos
Reply
6,544 Views
nxf56274
NXP Employee
NXP Employee

The ble lib is invisible to us. So it's hard to get the information. The last way to try to find out the problem is  using the Test tool. Use another board flashed with the fsci_black_box. The test tool provides the hci interface and it has the log about the hci commander.

abcde.PNG

asc.PNG

Use this to control the device acting as the central. And check the log. This may help us. 

0 Kudos
Reply
6,484 Views
jefthadsilva
Contributor III

Hi,

We were finally able to root cause the issue. The issue was due to a watchdog timer in our code. The BLE_APP task was taking more than 40ms during pairing operation. This was happening when SecLib code was executed on the request of the BLE Host stack. Since the watchdog task could not get a chance to execute it would reset the system, causing HCI timeout on the other device. 

This was a little tricky to debug because if a debugger is connected then the watchdog gets disabled and the issue was not seen.

Your suggestion of running the code in EVM helped us during root causing the issue.

We have now moved the BLE App task to execute in the background so that the Watchdog can interrupt it. And now pairing works fine.

Thanks a lot for your support.

0 Kudos
Reply