I have a peripheral device that needs to be paired with a pin to access its characteristics or perform read/write operations.
Here is a code snippet of what I have been doing till now.
const server = await device.gatt.connect();
console.log(`Bluetooth: Got server:`, server);
const service = await server.getPrimaryService(currentService.uuid);
let characteristic2 = await this.state.service.getCharacteristic(
currentService.characteristicsUUID[1]
);
await characteristic2.writeValue(new Int8Array([1]).buffer);
It shows that characteristicAttrib2.writeValue() is not permitted, even though the read and write access is provided by the characteristic of this service because the device has not been paired using pin. I just want to know if there's any API in web-ble using which the browser can request PIN while paring with the device? And only after pairing with that pin it will provide access to the peripheral device.
The Chromium team is currently working on adding support for pairing with devices when necessary to access protected characteristics. This currently happens automatically on Android and macOS but not on Windows, Linux and Chrome OS.
Follow along on this issue for updates.
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 play audio from Raspbian to a bluetooth speaker using A2DP.
From looking at test/simple-endpoint in the bluez source, it appears that running it without arguments should register an endpoint with the A2DP_SOURCE_UUID of 0000110A-0000-1000-8000-00805F9B34FB. However, I don't see any of the endpoint's callback methods being called (SelectConfiguration/SetConfiguration) when using bluetoothctl to connect to a bluetooth speaker. I tried with two different types of bluetooth speakers.
If I instead run simple-endpoint in "sbcsink" mode, and then connect my phone to it, I do see the endpoint's methods called (SelectConfiguration/SetConfiguration). So endpoints appear to be working for the A2DP sink uuid, but not the source one.
I'm able to find a org.bluez.MediaTransport1 corresponding to the bluetooth speaker by iterating through dbus managed objects:
import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('org.bluez', '/'), 'org.freedesktop.DBus.ObjectManager')
for path, ifaces in manager.GetManagedObjects().items():
transport = ifaces.get('org.bluez.MediaTransport1')
if transport is None:
continue
transport_obj = dbus.Interface(bus.get_object('org.bluez', path), 'org.bluez.MediaTransport1')
(fd, read_mtu, write_mtu) = transport_obj.Acquire('w')
taken_fd = fd.take()
print(path, fd, taken_fd, read_mtu, write_mtu)
I'm able to write to the transport's file descriptor taken_fd, but I can't control the audio configuration like I think I would if the transport had been acquired via a org.bluez.MediaEndpoint1. Also this seems kinda hacky, I'm not sure this transport is meant for me to access in this way. I would expect to get access to the transport via MediaEndpoint1's SetConfiguration.
I observed this behavior with bluez 5.43 on Rasbian Stretch. I also tried updating to the latest bluez 5.50 and saw the same behavior.
What is the expected way to use bluez as an audio source?
I figured out the problem by running bluetoothd in debug mode, and found that SetConfiguration/SetConfiguration was being called on a previously registered endpoint with a path of /A2DP/SBC/Source/1. Searching online for this path led me to discover that it was associated with bluealsa, which was registering the endpoint on system startup, and then was receiving the media endpoint callbacks instead of my endpoint. After killing bluealsa, my audio source endpoint was then able to receive the media endpoint callbacks as expected.
I'm a newbie of BLE programming on android.
In my first apps using BLE on android, I have a big problem.
I got a ScanRecord from Apple Bluetooth Headset using this function.
#Override
public void onScanResult(int callbackType, ScanResult result)
and I got a manufacturer data using Apple corp, ID(0x4C).
after that, I don't know how to decode a manufacturer data.
I want to auxiliary bluetooth headset information such as battery info, direction info etc. but I don't know how to decode the manufacturer data.
I also searched Apple development document(https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf)
But that guide document didn't help me.
Anyway, anyone who tell me how to resolve this problem?!!?!
Thank you to read my question.
Ok so from your comment it looks like you scanned the device over BLE and want to use one of the services it offers to get information like battery info.
The first thing you will need to do establish a connection to the BLE device.
The scanresult you pasted has a method getDevice you'll need to call
After you get the device you can call its connectGatt method. This will attempt to connect your phone and BLE device.
The connectGatt method from step 2 requires a callback. When the connection is successful or unsuccessful the callback will fire onConnectionStateChanged. If successful it will have the success status. This method will also give you a gatt device we will use in step 4.
If step 3 was successful we can assume your phone is connected. The next thing we want to do is discover services. You do this by using the gatt devices discoverServices method.
When the services are discovered your callback will fire onServicesDiscovered. At this point you can now use services. Depending on the API of the headphones they'll want you to read, or subscribe to a services characteristic and descriptor. Since I don't know the API I can't help you further. But you'll end up needing to use one or more of the following:
setCharacteristicNotification
readCharacteristic
readDescriptor
And the value will return to your callback on. Keep in mind you must wait for the callback for each request before write/reading/subscribing to another characteristic or descriptor.
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.
As part of my requirement, we need to have paring connection between microcontroller (Cortox M3) and Mobile or Pc. We are using Alpwise stack for our purpose. My problem is with the controller configurations, not with the mobile, because without paring i am able to work with it.
Where should i the API "BLESMP_InitiatePairing" api. Presently i am calling the api inside GAP_callback function, inside BLEGAP_EVENT_CONNECTED.
Is this a correct location to call at this API, because if i call over here, control goes to BLEEVENT_PAIRING_COMPLETE (returning SMERROR_UNKNOWREASON) then it goes into BLEEVENT_PAIRING_REQUEST then once again it goes into
BLEEVENT_PAIRING_COMPLETE (returning SMERROR_UNKNOWREASON). Whereas when i call "BLESMP_InitiatePairing" api, it returns me with success message
(You listed the core-bluetooth tag, so I'm assuming you want to use iOS.)
I don't know the specific stack you are using. However, if you are developing an LE peripheral and want to connect with an iOS device as central, it is sufficient to reply to a read / write request with an InsufficientAuthentication error code. iOS will then initiate pairing from its side.
More details on this process can be found in the Bluetooth Accessory Design Guidelines for Apple Products Section 3.9.