cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB P2P Server/Client Reducing Reconnection Time

Daniel L
Associate III

Hi,

I am currently using the P2P Server/Client example as a base for one of my projects. The server is constantly sleeping, waking up and reconnecting. After connecting the Services & Characteristics have to be rediscovered and notification re-enabled before data can be sent. This is taking a few seconds and is causing data to be lost. What steps can I take to reduce the time for the connection to reestablished?

Thanks,

Daniel

7 REPLIES 7
Remi QUINTIN
ST Employee

There are a few way to reduce the reconnection time.

  • One is to stay connected with long connection intervals. The STM32WB will enter in deep low power mode in between 2 connection events.
  • Another one is to ask for a direct connection knowing the device address from a previous connection. In this case, no need to discover the services. If the GATT servers (peripherals) are not changing, the GATT client can connect directly to those servers if it maintains a data base with all services offered by each server. Note that it is the way the ST Android apk on mobile phone is doing for a reconnection.

We are currently using standby mode for a lower power consumption, so a direct connection would be ideal. Do you have and examples on how to implement this on the STM32WB GATT client?

Remi QUINTIN
ST Employee

​Unfortunately not.

Unfortunately not. But we can confirm that the server device is maintaining the GATT data base in Flash memory. So if a notification was requested by a client, enabled by the server and the 2 devices were paired and bonded, the server will continue to notify the client after the reconnection.

On client side, the application can keep all the info related to services and characteristics for each server and make a direct connection without any service discovery phase. The client could also reconnect and asking for services with a connection_interval = 7.5ms. It is quite quick. And then a connection_update .

Use the p2pClient application and modify it to include the management of the service data base in Flash memory on the client side.

Hugues DE CARVALHO
Associate III

Hi Daniel,

You're asking how the connection/reconnection time could be decreased in order to reduce the power consumption of the sensor/server. Remi had suggested you use Direct Connection and upon investigation I found that you could also skip the discovery procedure as you’re always connecting to the same sensor/server.

I will detail below how to achieve each of those steps:

  1. Bypass Service & Characteristics Discovery : Replacing the Services and Characteristics procedure by a Flash read ( Services and Characteristics had been stored previously).
  2. Direct Connection : We won’t actually do that, explanation below.

  1. Bypass Service & Characteristics Discovery :

This step involves the following modifications in BLE_p2pClient:

  • Storing Services and characteristics in flash without disturbing the BLE stack
  • Reading Services and characteristics from flash if available
  • Redirecting the program flow to skip the discovery if possible

This is done in the BLE_p2pClient_SerChaDiscBypass example code attached. This example is based on the BLE_p2pClient example. Below is the Program flow for the scan/discovery/connection process which starts with SW1 being pressed:

  • Boxes with red lines are what has been added compared to BLE_p2pClient.
  • The algorithm just aims to understand the program flow and isn’t exhaustive. For instance dotted arrow attempt to represent conditional transitions.
  • Pink arrows represent time as measured with Systick, optimization off.
  • Find .png, .html, .drawio attached. You can modify those figures on draw.io.

0693W000000W8bJQAS.png

Other files attached:

  • Projects Code.7z : All projects
  • BLE_p2pClient to BLE_p2pClient_SerChaDiscBypass.docx: This file attempts to list the modifications from BLE_RfWithFlash to BLE_p2pClient_SerChaDiscBypass. It might not be exhaustive and it’s somewhat of a mess so you might be better off referring to the algorithm and code.
  • HCI Command list compare AN and code.docx: you might have noticed some API/ACI names aren’t the same in AN5270 and in the code, for instance “HCI_LE_CONNECTION_COMPLETE_EVENT�? is referred to as “case EVT_LE_CONN_COMPLETE:�? in the code. I listed all API/ACI with their AN5270 names and code names in “. That’s what I use to ctrl+f my way in the program flow.

As you can see on the algorithm, the connection time from Connect_Request() to aci_gatt_write_char_desc is reduced from 1800ms to 60ms when Flag_ServicesCharacteristics_In_Flash == 1. That is when the Services and Characteristics were stored in Flash and the discovery ACI aci_gatt_disc_all_primary_services and aci_gatt_disc_all_char_of_service are bypassed.

Moreover, stopping the scan once a server has been detected instead of waiting for it to timeout reduces the scan time from 10042ms to 50ms.

How to test BLE_p2pClient_SerChaDiscBypass:

  • Load Board1 with BLE_p2pServer
  • Wipe the flash on Board2 (set readout protection to BB then back to AA with cube programmer)
  • Load Board2 with BLE_p2pClient_SerChaDiscBypass
  • Reset Board1 to start advertising and press SW1 on Board2. Discovery takes about 2s. (Note that the blue LED is turned off before the discovery starts)
  • Once connected use SW1 on Board1 and Board2 to trigger the LED.
  • Reset Board1 to start advertising, Reset Board2 to start advertising and press SW1 on Board2. Discovery takes about 200ms. -> you can measure the time with the start/end/time commented in the code.

@Note: On the algorithm, when two “paths�? are available, go left and top option first and go back to the nod when you get to a dead-end.

  1. Direct Connection:

As shown on the algorithm above, I modified case EVT_LE_ADVERTISING_REPORT: in SVCCTL_App_Notification to terminate aci_gap_start_general_discovery_proc as soon as any server is detected, thereby not waiting for the 10.24s hardcoded timeout (which is observed as a 10.42s delay). A condition could be added to check the SERVER_REMOTE_BDADDR against a previously stored address. (Would have been stored in flash in a similar manner to storing the services and characteristics). The stored address could even be potentially used to directly connect and skip the scan.

0693W000000W3rbQAC.jpg

This however has nothing to do with Direct Connection.

In order to implement Direct Connection we must modify the BLE_p2pServer example to use aci_gap_set_direct_connectable. Yet, I haven’t managed to do so and the division told me it wouldn’t lead to a faster reconnection time.

If you do still want to try and implement it, you could try the following:

0693W000000W8b9QAC.png

Note that the only LOW_DUTY_CYCLE_DIRECTED_ADV (0x04) can be used for the Directed_Advertising_Type argument of ACI_GAP_SET_DIRECT_CONNECTABLE.

Moreover, bd_address and initiator_addr must be swapped: if bd_address=0x333333222222, initiator_addr=0x222222333333.

FYI, when I tried implementing ACI_GAP_SET_DIRECT_CONNECTABLE, I was never able to observe a HCI_LE_CONNECTION_COMPLETE_EVENT despite the AN5270 saying it should be triggered.

Regards,

Hugues

Kolab
Senior

Hello! @Remi QUINTIN​  how can I enable notification in the client board?I'm using Nucleo wb55. I can enable notification in the ST BLE Sensor app but not in p2p_client_app.c

Hugues DE CARVALHO
Associate III

Hi @Kolab​, please create your own thread and be more specific on what you want to do.

If you want to toggle the LED on the server from the client, see P2PC_APP_SW1_Button_Action in p2p_client_app.c:

void P2PC_APP_SW1_Button_Action(void)

{

 UTIL_SEQ_SetTask(1<<CFG_TASK_SW1_BUTTON_PUSHED_ID, CFG_SCH_PRIO_0);

}

Kolab
Senior

Hello @Community member​ I don't want to toggle a LED. I have created a case where I describe what I am trying to do.