Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot get notifications from HCI service #62

Open
DrCWO opened this issue Nov 1, 2023 · 2 comments
Open

Cannot get notifications from HCI service #62

DrCWO opened this issue Nov 1, 2023 · 2 comments

Comments

@DrCWO
Copy link

DrCWO commented Nov 1, 2023

Hi out there,
I got an issue I cannot solve by myself so some help would be appreciated. Here my configuration.

I am on a Raspberry with Raspbian. I have a Microsoft Surface Dial (which is a HCI device). The Surface Dial is paired with the Raspberry. I did this with bluetoothctl.

I like to get notifications directly from D-Bus so I disabled the HCI service in /lib/systemd/system/bluetooth.service by setting ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=sap,input,hog to be able to access the HCI service via D-Bus.

In my first implementation I used RAW HCI to get the data but after a disconnect of the device it takes more than three seconds after touching the Surface Dial until the HCI-Service was available again. This is much to long as rotating the dial a sudden reaction must occur. This is why I tried to use D-Bus. So in this implementation here I get the connect event immediately but I was not able to get the data any more 👎

I used the code below to get notification from the HCI Report Characteristic of the Surface Dial but it failed:

var deviceUuid = '70:BC:10:87:C1:B8';
var genericServiceUuid = '1812';
var genericCharacteristicUuid = '2a4d';


async function startBleServer() {

	console.log('************************************** Start BLE-Server: ' + deviceUuid);

	var { createBluetooth } = require('node-ble');
	var { bluetooth, destroy } = createBluetooth();
	var adapter = await bluetooth.defaultAdapter();
	console.log('adapter: ');

	// discover surfache Dial
	if (! await adapter.isDiscovering()) {
		console.log('Start discovery: ');
		await adapter.startDiscovery()
	}

	console.log('Wait for device: ' + deviceUuid);
	var device = await adapter.waitDevice(deviceUuid);

	device.on('disconnect', function () {
		console.log('######## Ble >>>>> EVENT: ' + 'Device disconnected');
	})

	device.on('connect', function () {
		console.log('######## Ble >>>>> EVENT: ' + 'Device connected');
	})

	console.log('stop discovery');
	await adapter.stopDiscovery()

	console.log('discovered, wait till connected');
	await device.connect()


	console.log('connected, wait for GATT server');
	var gattServer = await device.gatt();
	console.log('gatt server ready!');

	// Get service UUIDs and search for service 1812
	var myServices = await gattServer.services();
	var hciServiceUuid = null;
	for (var i = 0; i < myServices.length; i++) {
		if (myServices[i].indexOf(genericServiceUuid + '-') >= 0) hciServiceUuid = myServices[i];
	}
	console.log('HCI service UUID: ' + hciServiceUuid);

	// If I found the UUID of the HCI-Service get the HCI service
	if (hciServiceUuid) {

		//********************* get hciService
		var hciService = await gattServer.getPrimaryService(hciServiceUuid);
		console.log('Serice ' + hciServiceUuid + ' discovered');

		// get the characteristic UUIDs
		var myCharacteristics = await hciService.characteristics();
		console.log('Got HCI characteristic UUIDs');

		// find Reprt Characteristi UUIDs suchen
		var reportCharacteristicUuid = null;
		for (var i = 0; i < myCharacteristics.length; i++) {
			if (myCharacteristics[i].indexOf(genericCharacteristicUuid + '-') >= 0) reportCharacteristicUuid = myCharacteristics[i];
		}
		console.log('HCI Characteristic UUID' + reportCharacteristicUuid);

		// get Report Characteristic 
		var reportCharacteristic = await hciService.getCharacteristic(reportCharacteristicUuid);
		console.log('Report Characteristics ' + reportCharacteristicUuid + ' found');

		// Setup callback for Notifications
		reportCharacteristic.on('valuechanged', buffer => {
			console.log('Data received');
			console.log(buffer)
		})
		console.log('callback set');

		await reportCharacteristic.startNotifications();
		console.log('Notification started');

	}
}

startBleServer();

Running this code anything worked fine at the beginning. The service and the characteristic were found. But trying to setup the notification I get an error message. See output below:

root@DrCWO:/home/pi# node xx_ble.js
************************************** Start BLE-Server: 70:BC:10:87:C1:B8
adapter:
Start discovery:
Wait for device: 70:BC:10:87:C1:B8
stop discovery
discovered, wait till connected
######## Ble >>>>> EVENT: Device connected
connected, wait for GATT server
gatt server ready!
HCI service UUID: 00001812-0000-1000-8000-00805f9b34fb
Serice 00001812-0000-1000-8000-00805f9b34fb discovered
Got HCI characteristic UUIDs
HCI Characteristic UUID00002a4d-0000-1000-8000-00805f9b34fb
Report Characteristics 00002a4d-0000-1000-8000-00805f9b34fb found
callback set
/home/pi/rooExtend/node_modules/dbus-next/lib/bus.js:343
            return reject(new DBusError(reply.errorName, reply.body[0], reply));
                          ^

DBusError: Operation is not supported
    at _methodReturnHandlers.<computed> (/home/pi/rooExtend/node_modules/dbus-next/lib/bus.js:343:27)
    at handleMessage (/home/pi/rooExtend/node_modules/dbus-next/lib/bus.js:101:11)
    at EventEmitter.<anonymous> (/home/pi/rooExtend/node_modules/dbus-next/lib/bus.js:151:9)
    at EventEmitter.emit (node:events:513:28)
    at /home/pi/rooExtend/node_modules/dbus-next/lib/connection.js:132:14
    at USocket.<anonymous> (/home/pi/rooExtend/node_modules/dbus-next/lib/message.js:65:9)
    at USocket.emit (node:events:513:28)
    at emitReadable_ (node:internal/streams/readable:590:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:81:21) {
  type: 'org.bluez.Error.NotSupported',
  text: 'Operation is not supported',
  reply: Message {
    type: 3,
    _sent: false,
    _serial: 3374,
    path: undefined,
    interface: undefined,
    member: undefined,
    errorName: 'org.bluez.Error.NotSupported',
    replySerial: 100,
    destination: ':1.3859',
    sender: ':1.3820',
    signature: 's',
    body: [ 'Operation is not supported' ],
    flags: 1
  }
}

Node.js v18.7.0

Any idea why I cannot start the notification?

Best DrCWO

@lesha369
Copy link

your connect is destroying when you get characteristics.
this problem in hardware bluetooth.

@DrCWO
Copy link
Author

DrCWO commented Nov 11, 2023

Hi Alexey and thank's for your reply.
I still don't understand how to make it work. Using the default HCI-Driver in the kernel the hardware works but delayed after reconnect.
I believe that the hardware is OK as the HCI-driver can use it.
So I want to know what to do to make it work?
Are you able to help with a solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants