I am running a BlueZ Gatt server based upon BlueZ V5.50 and the example-gatt-server.py file contained in the BlueZ test directory. Many times when the server program exits/terminates the D-Bus is left in an unstable condition and I cannot successfully execute the program again without rebooting.
The error message received follows. This error persists until the system is rebooted.
('adapter (val/add) = ', dbus.ObjectPath('/org/bluez/hci0/dev_62_D9_BD_2F_9D_DB/service0018/char0019/desc001b'), '/', '0x75e2a020')
('service_manager (val/loc) = ', <Interface <ProxyObject wrapping <dbus._dbus.SystemBus (system) at 0x75dbbea0> :1.7 /org/bluez/hci0/dev_62_D9_BD_2F_9D_DB/service0018/char0019/desc001b at 0x75e5bf90> implementing 'org.bluez.GattManager1' at 0x75db9f70>, '/', '0x75e168a0')
ERROR:dbus.connection:Unable to set arguments (dbus.ObjectPath('/'), {}) according to signature None: <type 'exceptions.ValueError'>: Unable to guess signature from an empty dict
Resting bluetooth adapter power off/on has no effect
The error occurs asynchronous to the program so pdb has not helped
System information:
GNU/Lunix 4.19.42-v7 #1219
Bluez 5.50 with experimental flag set
Related
I'm using the zbus crate to make a server able to get events from the dbus.
It works well my code (basically the same as the example from the documentation) is able to receive events so it's fine.
I use busctl to send an event like in the example:
busctl --user call org.zbus.MyGreeter /org/zbus/MyGreeter org.zbus.MyGreeter1 SayHello s "Maria"
And my code is able to receive the event with the parameter just fine.
The thing is I'm having some issues with udev and while I was trying to fix it I found some weird things:
If I send an event with another user it fails with Call failed: the name org.zbus.MyGreeter was not provided by any .service files while my program is running
When I do busctl list --acquired I don't see org.zbus.MyGreeter in the result
My question is: is it normal my program does not appear in the busctl list? Am I doing something wrong or do I use the wrong library to do what I want to do?
Ok it seems there are 2 busses and I was not using the system bus.
I had to replace the method session to system to indicates I want my program to run on the system bus.
Like this:
let _ = ConnectionBuilder::system()?
.name("org.zbus.MyGreeter")?
.serve_at("/org/zbus/MyGreeter", greeter)?
.build()
.await?;
Doing this is not enough because my program does not have to permission to create a service on the bus system. So I had to create a file in /usr/share/dbus-1/system.d where I did write the configuration needed.
BLE advertising can be enabled using HCI_LE_Set_Advertising_Enable[1] command which returns status 0x00 if HCI_LE_Set_Advertising_Enable command succeeded or status code 0x01 to 0xFF[2] if the command failed.
If the advertisement is already enabled (e.g. calling this command for the second time with Advertising_Enable parameter set to 0x01) then this or HCI_LE_Set_Advertising_Data commands will return status 0x0C (Command Disallowed).
There are (at least) two problems with this:
Enabling advertising when it is already enabled can cause the random
address to change. Disabling advertising when it is already disabled
has no effect. [1]
BlueZ stack contains the following piece of code at the end of most HCI library functions:
if (status) {
errno = EIO;
return -1;
}
which causes e.g. hci_le_set_advertise_enable function to return generic fail code -1 and set errno to EIO, which is indistinguishable from any other BlueZ error, HCI error or an actual IO error (HCI layer uses UART).
How to check if the LE advertisement is already enabled to be able to perform safe/strict error handling? I cannot find any command for Get Advertising Status in the BT Core Specs. I cannot rely on something like
if ((rc == -1) && (errno == EIO)) {
/* Actually OK, advertising is already enabled */
return 0;
}
Thank you.
References:
[1] BT CS 5.2 [Vol 4] Part E, Section 7.8.9
[2] BT CS 5.2 [Vol 1] Part F, Controller Error Codes
The idea is that the Bluetooth stack on the host side should know if it has started advertising or not. That's how it should work. If you manually bypass the Bluetooth stack on the host side (which you shouldn't do unless you are debugging or something), sending your own hci command, then you can't know.
I have a test board for amlogic S905X chip. (p212 reference board) When I burn my ROM into it, the bluetooth constantly shows "stopping" dialog.
The logfile (tombstone) is quite long but the important part is here:
01-01 00:24:15.708 28953 28986 I bt_hci : hci_initialize
01-01 00:24:15.710 28953 28970 D bt_hci : hci_module_start_up starting async portion
01-01 00:24:15.711 28953 28986 I bt_hci : hci_initialize: IBluetoothHci::getService() returned 0xa1b91560 (remote)
01-01 00:24:16.209 28953 28987 F : [0101/002416.209517:FATAL:hci_layer_android.cc(78)] Check failed: status == Status::SUCCESS.
It seems the hardware is initialized but the the HCI can not be started. Is it related to kernel drivers or android user space and HAL modules? or even framework(?!)
How can I approach this problem to solve it?
the full tombstone log file is pasted here
Thanks
EDIT :
logcat is pasted here.
Your tombstone tells you that your process terminated because the assertion CHECK(status == Status::SUCCESS) failed in hci_layer_android.cc:78.
That problem goes back to the Bluetooth HAL calling initializationComplete(Status::INITIALIZATION_ERROR).
You have to check your Bluetooth HAL implementation for how this can happen.
Checking logcat for messages from android.hardware.bluetooth#1.0-impl could help.
The reasons for a failure and the corresponding log messages from the default bluetooth HAL implementation can be found here.
I have been trying to get data from my PolarH10 with my raspberry-pi. I have been successfully getting data through the commandline with bluez, but have been unable to reproduce that in python. I am using pygatt(gatttool bindings) and python3.
I have been closely following the examples provided on bitbucket and was able to detect my device and filter out it's MAC address by filtering it by name. I however was unable to get either of the "reading data asyncronously" examples to work.
#This doesnt work...
req = gattlib.GATTRequester(mymac)
response = gattlib.GATTResponse()
req.read_by_handle_async(0x15, response) # what does the 0x15 mean?
while not response.received():
time.sleep(0.1)
steps = response.received()[0]
...
#This doesn't work either
class NotifyYourName(gattlib.GATTResponse):
def on_response(self, data):
print("your data is: {}".format(data))
response = NotifyYourName()
req = gattlib.GATTRequester(mymac)
req.read_by_handle_async(0x15, response)
while True:
# here, do other interesting things
time.sleep(1)
I don't know and cannot extract from the "documentation(s)" how to subscribe to/read notifications from a characteristic(heart rate) of my sensor(PolarH10). The error I am getting is when calling GATTRequester.connect(True) is
RuntimeError: Channel or attrib not ready.
Please tell me how correctly connect to a BLE device via Python on Debian and how to programatically identify offered services and their characteristics and how to get their notifications asyncronously in python using gattlib(pygatt) or any other library. Thanks!
The answer is: Just use bleak.
I have a device that presents the same behavior. In my case, the problem was that it does not have a channel of type public, I should use random instead (like in gatttool -b BE:BA:CA:FE:BA:BE -I -t random).
Just calling the connect() method with the parameter channel_type to random could fix it:
requester.connect(True, channel_type="random")
PD: Sorry for the late response (maybe it will be helpful to others).
I try to connect my raspberry pi (with raspbian weezy) with a strip LED module. To do this, I use the UART connection of RBPi in order to communicate with RS485 strip connection.
My trouble : I can (yes I can) send data but I don't received ACK or anything else. However my strip LED module send data frame to the RBPi (I can see it on oscilloscope).
EDIT :
I think it's due to the following error that appears when the program opened UART connection. NO : The following error is due to an non-user permission
[ERROR] [DAAPI] iso=-1:cannot open /dev/mem
Well, But I don't receive message...
END EDIT
I write the following javaME code to do this :
UARTConfig config = new UARTConfig((int)Integer.valueOf(this.getPortCom()),(int)Integer.valueOf(this.getPortCom()), this.getBaudrate(),
this.getBitsperchar(), this.getUARTParity(), getStopBits(), UARTConfig.FLOWCONTROL_NONE);
this.uart = (UART)DeviceManager.open(config);
InputStream serialInputStream = Channels.newInputStream(uart);
BufferedReader serialBufferedReader = new BufferedReader(new InputStreamReader(serialInputStream));
this.tSerialOutput = new Thread( new SerialWriter( Channels.newOutputStream(uart) ) );
this.tSerialOutput.start();
this.tSerialInput = new Thread( new SerialReader( serialBufferedReader ));
this.tSerialInput.start();
"this" is my class which manage serial communication.
The error message is getting after the "DeviceManager.open"
I have follow the recommendation of the following ticket :
https://community.oracle.com/message/12513726
But it's not really the answer of my issue (I think...)
I have no idea.... So please, help me ^^
First, you must be sure Serial Port is not already used by Linux Console. Here is how to disable this:
Edit /etc/inittab and disable the following line by adding a # character in front of it
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
then reboot.
If this is still not working, then you may try to execute JavaME runtime with elevated privileges:
sudo ./runSuite.sh <yourapp>
If this is working, there is a permission problem somewhere.
Finally, you should try to get latest version of JavaME (currently, it is 8.1).