I've developed embedded software on a central board and a peripheral board, using Broadcom's WICED v1.0.1 API.
When my central scans, it detects the peripheral advertisement.
When my central then connects, that works, and the peripheral detects this.
My central can then send a write request, which the peripheral detects and responds to by sending back a notification, which the central receives ok.
BUT, when the central then disconnects, so it can poll next peripheral, nothing happens; the peripheral does not fire its link down (disconnection) callback.
To disconnect, my central executes this Broadcom API function:
blecm_CreateConnectionCancel();
blecm_disconnect(BT_ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST);
Related
I am fairly new to working with Bluetooth and the ESP32 Bluetooth stack, so forgive me if I don't use the right terminology.
I can get the ESP-IDF Development example "A2DP_Source" working perfect only if I enable the headphones pairing mode first. After it is paired, and the bonding is stored in the Bluetooth, it will reconnect to the headphones without issue, but it then does not notify the app through the call back functions that it has connected. The app then continues to search for a bluetooth device and the audio streams sporadically, or not at all.
I've tried multiple speakers, and headphones, all with the same results.
I can see the bonded device list also and the device is there.
Is there callback function in the bluetooth stack that needs to be initialized to notify the app that the bluetooth connected to a previously paired device instead of just a device in pairing mode?
These are the three callback functions setup currently that run when connected through pairing mode, but don't run when the bluetooth connects in non-pairing mode.
...
/* register GAP callback function */
esp_bt_gap_register_callback(bt_app_gap_cb);
/* initialize AVRCP controller */
esp_avrc_ct_init();
esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
/* initialize A2DP source */
esp_a2d_register_callback(&bt_app_a2d_cb);
esp_a2d_source_register_data_callback(bt_app_a2d_data_cb);
...
Any help or pointers would be appreciated. Thanks.
Did you mean ESP32 A2DP cannot connect a device without the push of a PAIR button?
The example "A2DP_Source" does not seem to connect the bonded device.
It just tries to discover the device with the certain name ("ESP_SPEAKER" in the original code) calling the function esp_bt_gap_start_discovery.
If the device is found, bt_app_gap_cb is called and then the connect to peer will start via esp_a2d_source_connect.
So I suggest fixing the code so as to connect peer instead of calling esp_bt_gap_start_discovery if there is any bonded device.
You can use the function esp_bt_gap_get_bond_device_list and find out the address of the bonded device which is required by esp_a2d_source_connect.
The API reference is available in https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_bt.html and https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_a2dp.html.
Working through this problem more, I found that using C++ to call the native C code was the issue. I don't have a strong enough background in coding to understand the "why" it did not work, but once I returned all the code back to "C" it started working without issue. Hope this helps someone else who may make the same mistake.
I am trying to keep the bluetooth sco connected for a device running android from the time the bluetooth headset is connected to when the headset is disconnected or more specifically I would like the sco link not torn down by an app while the bluetooth headset is connected. It is okay for a user while in the VOIP call menu to select the BT/speaker icon button and tear down and bring back up the sco link (as it is user initiated).
When a VOIP call ends (eg whatsApp, google hangouts, skype, viber etc) while using a bluetooth headset, the sco link gets torn down. I would like the sco link to be either not torn down when the VOIP call ends (preferred operation) or re-established through "some" mechanism.
Things I have tried (with no success):
1) Trying to detect VOIP call start/end but reading other SO posts, looks like this is not possible. There are a lot of hooks to detect a sim-based call and end but not for VOIP based calls.
2) Start sco using startVoiceRecognition() like below. This seemed to work...almost...
audioManager.setMode(MODE_IN_COMMUNICATION)
audioManager.startVoiceRecognition()
There were two problems with this approach.
An incoming whatsApp call tears down the sco established by using
the startVoiceRecognition() api
While in a VOIP call (hangouts, whatsApp etc), the in-call audio route options do not work
I have gone over several SO posts on this but with no success.
3) I observed that Audiomanager.setMode gets set to MODE_NORMAL (0) when a VOIP call ends and I can startBlueToothSco() there but there is no listener for AudioManager mode changes and I do not want to poll it.
I also observed that depends on the VOIP app attempting to stop sco on a call end, checking the mode may not work as the app could call stopBluetoothSco after the mode change.
4) Make a dummy call using ConnectionService api's that makes android think its in a call but that prevents VOIP calls from being established and hence the sco link will not be disconnected. (not desirable as I need VOIP calls to happen)
Any ideas/suggestions will be appreciated.
I use nrf51822 sdk130 (central device) and nrf51822 sdk110(peripheral device). I want to continuously get rssi value of the peripheral device using the central device without connection. Normally I start the scan_start function using button_handler function. Then connection establish occurs. But I dont want to do that. I want to Connect automatically device without press the button (without button_handler function). And I want the device not to reconnect until it leaves the bluetooth signal range.(think like KEYLESS GO - Mercedes). Is it possible?
it is possible to send non-connectable advertisement from the peripheral. This is intended to broadcast some information without being connected. using this central device can read the rssi of the peripheral's advertisement. The second part of your question is not very clear.if the application in the central does not see an advertisement it is possible to detect the absence of the peripheral.
see passive scanning sequence below.
see active scanning sequence below, the only requirement is that the active scanner should send at least one scan Request.
active vs passive scanning:
Once connection is established, RSSI can be read using following HCI command.
The relevant section for LE connection is as follows.
I study the bluetooth low energy. During studying, I have a question.
As I know, possible data transaction Role is observer-broadcaster(connectionless) and central-peripheral(connection) in BLE.
But, What I wonder is data transaction between observer and peripheral?? Is that possible?? In other words, Can observer scan the peripheral's broadcasting message?
If that is possible, Can central receive the broadcaster's advertising packet? and Can central scan the broadcaster's advertising packet?
An observer can scan the advertisements from the broadcaster, unless the advertiser (broadcaster)'s advertisements are of type nonconnectable.
There are two types of scanning in Bluetooth Smart (Bluetooth Low Energy): passive and active.
Passive scanning just listens to advertisements (which contains advertisement data).
Active scanning when an advertisement is received it sends a scan request and the advertiser then sends a scan response (which contains scan response data) back.
There are different types of advertisements in Bluetooth Smart:
general advertisement: The typical advertisement whereto connections can be initiated. It supports active scanning.
direct advertisement: The advertiser wants a particular device to connect to it instantly. It does not support active scanning and does not have any advertising data (except the connection addresses of both devices).
discoverable advertisement: The advertiser supports active scanning, but can not be connected to. (i.e. broadcast of data).
nonconnectable advertisement: The advertiser does not support active scanning, and can not be connected to. (i.e broadcast of data).
We are testing Bluetooth in WEC2013 with a USB based dongle from generic vendor on iMx6 platform. We are using the default HCI Transport layer provided with WEC2013 BSP.
BT is turned on and able to scan all the nearby devices.
We have enabled following set of sysgen variables and registry entry.
Sysgen Variables:
SYSGEN_BTH (Bluetooth stack with universal loadable driver)
SYSGEN_BTH_BTHUTIL (Bluetooth Profile Management APIs)
SYSGEN_BTH_HID_KEYBOARD (Bluetooth HID - Keyboard)
SYSGEN_BTH_HID_MOUSE (Bluetooth HID - Mouse)
SYSGEN_BTH_AG (Bluetooth HS/HF and Audio gateway service)
SYSGEN_BTH_SETTINGS (Bluetooth settings UI)
SYSGEN_OBEX_CLIENT (Obex client)
SYSGEN_OBEX_SERVER (Obex server)
SYSGEN_OBEX_FILEBROWSER (OBEX file browser)
SYSGEN_OBEX_INBOX (OBEX Inbox)
SYSGEN_FTPD (FTP server)
SYSGEN_BTH_BTHSSVC(Support Secure Simple Pairing)
Registry entry:
[HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\Default\224_1_1\Default\Bluetooth_USB_Driver]
"DLL"="bthusb.dll"
[HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\Default\Default\224_1_1\Bluetooth_USB_Driver]
"DLL"="bthusb.dll"
[HKEY_LOCAL_MACHINE\Software\Microsoft\Bluetooth\Transports\PnP\{B3DD867A-1E6E-4215-8AA7-EAC1DFC46548}]
"flags"=dword:80000000
"driver"="bthusb.dll"
"resetdelay"=dword:0
"PacketSize"=dword:200
"BlockSize"=dword:5
[HKEY_LOCAL_MACHINE\ControlPanel\Bluetooth]
"PinAttemptInterval"=dword:200000
"PinEntries"=multi_sz:"0000","8888"
We observed different scenario's in pairing to a device.
Connecting to mobile from board(imx6+usb dongle running with WEC2013)
Here pairing is success when pair is initiated through bthsettings UI. It will trigger the 6-digit automated passkey on both the sides.
Connecting from mobile to board without opening bthsettings UI.
Here pairing is success once. When the UI is not open (BT is ON in background), pairing is initiated from mobile, both will be paired using automated
6-digit passkey method. But this will internally invoke bthsettings UI, so next time when we give pairing from mobile, mobile side will ask for manual
key insertion. As soon as the key is entered on mobile and pair is pressed, pairing rejected notification will be observed on mobile terminal.
So pairing is failed in this case.
Connecting from mobile to board when bthsettings is opened.
Here pairing is failed. When pair is initiated from mobile, manual key insertion UI will be invoked and when key is inserted and pair is pressed,
pairing rejected notification will be displayed on mobile terminal and pairing is failed.
In these failed senarios, the upper layer is responding with "Pin code request negative reply command" for "Pin code request event" from chip.
We need input on this pairing process. Why this automated key and manual key generation methods are invoked based on whether UI is open or never opened? And why manual key case is failing?
Are we missing any registry entry or stack feature ?
It all got to do with SSP(Secured Simple Pairing), which decides the pairing authentication model. This is affected in WEC8(2013) through the changes under bthsettings.
Under WEC8 they disable SSP(via function EnbaleSSP()) whenever a connection is initiated from external device and enable back SSP when conenction is initiated internally. Though this is the logic, I'm not aware of why this is introduced(and is it a bug, that'll be fixed in upcoming updates as they initially did for NDIS 5 wireless driver connection).
And as a workaround to this, disable EnableSSP().
Also SYSGEN_BTH_BTHSSVC is implicitly needed by SYSGEN_BTH_SETTINGS component, and the link is broken under WEC8.
Microsoft has provided the fix in April 2015 update. Details available here.