Search code examples
c#cbluetooth-lowenergybare-metalspp

EFR32BG22 BLE in SPP mode with PC (Windows 10) won't connect


EFR32BG22 BLE in SPP mode with PC (Windows) won't connect.

Hello everyone, I'm trying to run a bluetooth connection between Thunderboard and PC in SPP mode. The whole project is based on examples provided by Sillicon Labs however I can't find the reason why is it not working.

How the project looks like

  • On the board side I'm running an example called bluetooth_spp_server which is originally made to communicate between two Thunderboard boards
  • On the PC side I'm running an example called bluetooth_spp_with_windows which is made exactly for the purpouse I need.

The behaviour

Even when the projects are made exactly for what I need somehow I can't make it run. When I'm running the precompiled .exe application, which is in the project files, everything works exactly how it should but when I compile the source code by myself and then run mine .exe app the PC won't connect. Well to be clear somehow I made it try to connect like 5 times but I hadn't change anything and since that nothing works. The PC see the board, board is advertising as a server and still, nothing happens and no event is found.

After some debugging

After few debugging sessions I found out that the board is advertising just fine, I can see it in the bluetooth devices etc. (I don't have it paired because that makes even the precompiled .exe app work weirdly). However when it comes to connecting, the board can't find any event (I can't see if it's different from PC side thanks to lack of visibility in the win api). Advertising is basically the only thing the board is doing after initialization and advertising start.

To provide atleast some code right here, there's the initialization and connection opening:

The sl_bt_step() function which is called from the main loop on the board side

#define SL_STATUS_OK 0

SL_WEAK bool sl_bt_can_process_event(uint32_t len) {
   (void)(len);
   return true;
}

void sl_bt_step(void) {
   sl_bt_msg_t evt;
   sl_bt_run(); // API function - can't see what's going on inside
   uint32_t event_len = sl_bt_event_pending_len(); // API function - can't see what's going on inside
   if( ( event_len == 0 ) || ( !sl_bt_can_process_event( event_len ) ) )
      {
      return; // After init I'm always ending right here.
      }
   sl_status_t status = sl_bt_pop_event( &evt );
   if( status != SL_STATUS_OK )
      {
      return;
      }
   sl_bt_process_event( &evt );
}

void sl_bt_process_event(sl_bt_msg_t *evt) {   
   sl_bt_in_place_ota_dfu_on_event(evt);
   sl_gatt_service_device_information_on_event(evt);
   sl_bt_on_event(evt); 
}

Initialization and event occured handler on the board side

void sl_bt_on_event(sl_bt_msg_t *evt) {
   uint16_t max_mtu_out;
   sl_status_t sc;
   switch (SL_BT_MSG_ID(evt->header)) {
/// First thing after turning on the MCU
      case sl_bt_evt_system_boot_id:
         app_log("SPP Role: SPP Server\r\n");
         reset_variables();
         sc = sl_bt_gatt_server_set_max_mtu(247, &max_mtu_out);
         app_assert_status(sc);
         sc = sl_bt_advertiser_create_set(&advertising_set_handle);
         app_assert_status(sc);
         sc = sl_bt_legacy_advertiser_generate_data(advertising_set_handle,
                                                 sl_bt_advertiser_general_discoverable);
         app_assert_status(sc);
         sc = sl_bt_advertiser_set_timing(
            advertising_set_handle,
            160,   // min. adv. interval (milliseconds * 1.6)
            160,   // max. adv. interval (milliseconds * 1.6)
            0,     // adv. duration
            0);    // max. num. adv. events
         app_assert_status(sc);
         sc = sl_bt_legacy_advertiser_start(advertising_set_handle,
                                         sl_bt_legacy_advertiser_connectable);
         app_assert_status(sc);
         break;

/// After an event "in the air" occure - I can't get into this since the board can't see any event
      case sl_bt_evt_connection_opened_id:
         conn_handle = evt->data.evt_connection_opened.connection;
         app_log("Connection opened\r\n");
         main_state = STATE_CONNECTED;
         sl_bt_connection_set_parameters(conn_handle, 24, 40, 0, 200, 0, 0xFFFF);
         break;
   }
}
  • The evt->header is set by the bluetooth peripheral and after initialization where the return iteration sequence is 17 14 6 7 it returns only 0. I can't debug or see anything that's happening with this variable, only the values that are set by the bluetooth peripheral.

Conclusion

What really can't get over my head is the fact that the precompiled .exe app works everytime even when the board is paired with windows which only leads to an attempts to connect. That's still further than any try (except the random 5 ones) with the .exe app version compiled by me.

From what I know there're two functions in win api which are made to connect bluetooth device. I already tried each variation of them by changing the provided code for PC side.

I already tried the silabs forum but the answer didn't help and they still haven't replied to the second one so I thought I should try my luck on other forums.

Does anyone know what may cause this weird behaviour? Is it possible that the precompiled .exe app was compiled with some old libraries/frameworks and now it's not supported anymore with the new ones? (the precompiled version was uploaded to github 2 years ago).

I hope someone knows what's happening because after hours of googling and trying things, someone's help seems to by my last chance. Thank you in advance for any efforts to help me.


Solution

  • Problem seems to be solved

    So it still can't get over my head how can the provided .exe application work since I couldn't find any cause of the described problem.

    The solving

    However after another hours of work I decided to try another example called bluetooth_secured_spp_over_ble. The applications isn't that much different. The key differences are:

    • Showcase of how you can setup your bonding setting.
    • The program isn't only advertising the data. It advertise the data, then bonding is being handled and then you can send/receive data.
    • There's setup for extracting the unique device ID and then writing it in the right format on the gatt server. This might be the key difference

    Honestly, I didn't have much time to find what the key difference was. My best stuggest is getting and setting the unique device ID.

    Anyways, with this example everything seems to be working.

    I believe my collegue also swapped into using this BLE console provided by Microsoft but the original example is working too.