[TW#11125] BLE connect to non-advertising peripheral
[TW#11125] BLE connect to non-advertising peripheral
Hello,
I have some BLE peripherals that intentionally do not advertise themselves. Using an Android app I wrote, I am able to connect to these devices - no problem at all. But I am unable to get this to work on the ESP32. Here I wait for ESP_GATTC_REG_EVT and then, instead of calling esp_ble_gap_set_scan_params(), I directly call esp_ble_gattc_open(gattc_if, [hardcoded target address], true). But this does not establish a connection. Is there maybe a hard requirement for BLE scanning to always go first, before a connection can be established? This should not be the case.
Thank you.
I have some BLE peripherals that intentionally do not advertise themselves. Using an Android app I wrote, I am able to connect to these devices - no problem at all. But I am unable to get this to work on the ESP32. Here I wait for ESP_GATTC_REG_EVT and then, instead of calling esp_ble_gap_set_scan_params(), I directly call esp_ble_gattc_open(gattc_if, [hardcoded target address], true). But this does not establish a connection. Is there maybe a hard requirement for BLE scanning to always go first, before a connection can be established? This should not be the case.
Thank you.
Re: BLE connect to non-advertising peripheral
In other words:
Is it true that BLE clients on ESP32 need to always scan for BLE peripherals, before they can connect?
The ESP32 sample code works this way. But in my judgement, if a target address is already known, the BT stack should NOT make scanning mandatory. Bluedroid (in Android) allows clients to connect to peripherals without scanning. ESP32 is also using Bluedroid. But scanning appears to be required. Is this intentional?
Is it true that BLE clients on ESP32 need to always scan for BLE peripherals, before they can connect?
The ESP32 sample code works this way. But in my judgement, if a target address is already known, the BT stack should NOT make scanning mandatory. Bluedroid (in Android) allows clients to connect to peripherals without scanning. ESP32 is also using Bluedroid. But scanning appears to be required. Is this intentional?
Re: BLE connect to non-advertising peripheral
Howdy,
I was playing with BLE last night (tinkering with C++ class wrappers) and was able to connect to a BLE device and retrieve GATT characteristics without first doing a BLE scan. So far, all working as expected.
I was playing with BLE last night (tinkering with C++ class wrappers) and was able to connect to a BLE device and retrieve GATT characteristics without first doing a BLE scan. So far, all working as expected.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: BLE connect to non-advertising peripheral
This is very encouraging. Are you doing more than just calling esp_ble_gattc_open() in response to ESP_GATTC_REG_EVT? This is what I do, but no cigar:
E (32137) BT: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0100
E (32137) BT: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0100
E (32137) TRemote: # OPEN_EVT gattc_if=4, status=133, mtu=0, REMOTE BDA=d8:50:e5:86:12:9a
(Why are there always two bta_gattc_conn_cback lines??)
As mentioned before, my other BLE-clients are able to connect to these none-advertising peripherals. Are your peripherals advertising themselves? Mine are totally silent. Could this make a difference to a client BLE-stack, even if the app is not actively scanning?
E (32137) BT: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0100
E (32137) BT: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0100
E (32137) TRemote: # OPEN_EVT gattc_if=4, status=133, mtu=0, REMOTE BDA=d8:50:e5:86:12:9a
(Why are there always two bta_gattc_conn_cback lines??)
As mentioned before, my other BLE-clients are able to connect to these none-advertising peripherals. Are your peripherals advertising themselves? Mine are totally silent. Could this make a difference to a client BLE-stack, even if the app is not actively scanning?
Re: BLE connect to non-advertising peripheral
Howdy sir,
To be honest, I'm absorbing books on BLE as fast as possible and don't consider myself an expert. I am testing with one BLE device which is (I believe) called an "iTag" which a $3 key fob that beeps when a connection formed to it is lost. However, it does behave as a GATT server etc etc.
While I am fumbling in the dark, if it would be useful to you, ping me on IRC channel #ESP32 (user kolban) and we can take a look at your code together. If nothing else, we can compare against mine and look at common messages and see where things digress.
To be honest, I'm absorbing books on BLE as fast as possible and don't consider myself an expert. I am testing with one BLE device which is (I believe) called an "iTag" which a $3 key fob that beeps when a connection formed to it is lost. However, it does behave as a GATT server etc etc.
While I am fumbling in the dark, if it would be useful to you, ping me on IRC channel #ESP32 (user kolban) and we can take a look at your code together. If nothing else, we can compare against mine and look at common messages and see where things digress.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: BLE connect to non-advertising peripheral
Hi,
according to BLE Core Spec 4.2 Vol 3 part C 9.3, there're several connection procedures. As the figure in 9.3.6 describes, general connection establish procedure will always including a scanning procedure. I think what you're trying to do is 9.3.8, direct connection establish procedure.
Current gattc open API seems to preform general connection establish procedure. Calling gattc open without scanning is able to connect to advertising devices.
Maybe we can dig deep on the bluedroid stack in components/bt to check if there're some other interface that will do the job.
according to BLE Core Spec 4.2 Vol 3 part C 9.3, there're several connection procedures. As the figure in 9.3.6 describes, general connection establish procedure will always including a scanning procedure. I think what you're trying to do is 9.3.8, direct connection establish procedure.
Current gattc open API seems to preform general connection establish procedure. Calling gattc open without scanning is able to connect to advertising devices.
Maybe we can dig deep on the bluedroid stack in components/bt to check if there're some other interface that will do the job.
Re: BLE connect to non-advertising peripheral
> I think what you're trying to do is 9.3.8, direct connection establish procedure.
This is correct.
Here something I noticed: while I am not able to sniff BLE radio (weep), I was able to raise the log level on the peripheral side to max. Now when I connect with my Android client, I immediately see a burst of bt_att activity, leading to a full connection quickly. But when I try to do the same with my ESP32, there is abs no activity on the other side. Nothing! And a few secs later I receive OPEN_EVT with status=133.
So, on the surface it looks like the ESP32 is doing "something". But with zero activity on the peripheral side, I get a different impression now. Could this be a simple thing to fix? Any suggestion as to where (in components/bt) I should take a look? It's easy for me to test this right now. - Thank you for helping me, both of you. Very kind!
This is correct.
Here something I noticed: while I am not able to sniff BLE radio (weep), I was able to raise the log level on the peripheral side to max. Now when I connect with my Android client, I immediately see a burst of bt_att activity, leading to a full connection quickly. But when I try to do the same with my ESP32, there is abs no activity on the other side. Nothing! And a few secs later I receive OPEN_EVT with status=133.
So, on the surface it looks like the ESP32 is doing "something". But with zero activity on the peripheral side, I get a different impression now. Could this be a simple thing to fix? Any suggestion as to where (in components/bt) I should take a look? It's easy for me to test this right now. - Thank you for helping me, both of you. Very kind!
Re: BLE connect to non-advertising peripheral
I tried from HCI command HCI_LE_Create_Connection, API to send this command is btsnd_hcic_ble_create_ll_conn in components/bt/bluedroid/stack/hcic/hciblecmds.c.
by checking the callers of btsnd_hcic_ble_create_ll_conn, I find GATT seems will finally call gatt_connect in components/bt/bluedroid/stack/gatt/gatt_api.c to create connection.
I think you may start from gatt_connect to check what happened if we don't have advertising events.
by checking the callers of btsnd_hcic_ble_create_ll_conn, I find GATT seems will finally call gatt_connect in components/bt/bluedroid/stack/gatt/gatt_api.c to create connection.
I think you may start from gatt_connect to check what happened if we don't have advertising events.
Re: BLE connect to non-advertising peripheral
esp_ble_gattc_open() -> GATT_Connect() -> gatt_act_connect() -> gatt_connect()
This is how connecting to a BLE peripheral starts. In gatt_connect(), the variable "transport" is playing an important role. On ESP32 "transport" is set to 2 (BT_TRANSPORT_LE), while on Android it is set to 1 (BT_TRANSPORT_BR_EDR). Because of this, ESP32 will continue with L2CA_ConnectFixedChnl() (will scan/wait for BLE advertisements before attempting to connect), while Android will continue with L2CA_ConnectReq() (will NOT scan for BLE adv; but will connect to non-advertising peripherals).
See: https://github.com/espressif/esp-idf/bl ... ain.c#L169
So Bluedroid on Android is switching to GATT over conventional Bluetooth, and it does so automatically, because the specified peripheral is not advertising itself. I found this so hard to believe, I had to log another session, this time connecting to an advertising peripheral. And yes, this time "transport" is set to 2 (BT_TRANSPORT_LE).
This seems to tell me, that connecting to a non-advertising peripheral may be a no-go with LE. Thoughts?
This is how connecting to a BLE peripheral starts. In gatt_connect(), the variable "transport" is playing an important role. On ESP32 "transport" is set to 2 (BT_TRANSPORT_LE), while on Android it is set to 1 (BT_TRANSPORT_BR_EDR). Because of this, ESP32 will continue with L2CA_ConnectFixedChnl() (will scan/wait for BLE advertisements before attempting to connect), while Android will continue with L2CA_ConnectReq() (will NOT scan for BLE adv; but will connect to non-advertising peripherals).
See: https://github.com/espressif/esp-idf/bl ... ain.c#L169
So Bluedroid on Android is switching to GATT over conventional Bluetooth, and it does so automatically, because the specified peripheral is not advertising itself. I found this so hard to believe, I had to log another session, this time connecting to an advertising peripheral. And yes, this time "transport" is set to 2 (BT_TRANSPORT_LE).
This seems to tell me, that connecting to a non-advertising peripheral may be a no-go with LE. Thoughts?
Re: BLE connect to non-advertising peripheral
Do you have a code sample we can look at to either see what your recipe is or, test ourselves against our devices?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Who is online
Users browsing this forum: No registered users and 143 guests