Am 30.03.23 um 20:25 schrieb Luiz Augusto von Dentz:
Hi Martin,
On Thu, Mar 30, 2023 at 11:16 AM Martin Petzold <martin.petzold@xxxxxxxx> wrote:
Dear Luiz,
I now have another issue with remote control HID integration
(non-system; direct implementation).
I am using Java with d-bus BlueZ 5.55 on Debian Linux. I have "hid" and
"input" plugin disabled on bluetooth startup.
I have one remote integrated and working. With this one after boot and
while application startup I iterate over all paired devices with
existing HID service (check for existing service UUID) and then iterate
all Report characteristics and enabling notifying for all of them (if
supported). Everything is running well with this (legacy) remote. After
pairing it also auto-connects using my own registered object manager, as
suggested by you.
Now we received our final custom remote control from our manufacturer
(other chip) and this approach does not work any more. I have tried a
lot of things now. Once the remote control is paired (which is also
somehow still buggy) and I rebooted the system with our application, the
device is found in the list as paired, BUT I cannot access the HID
service any more. Therefore, I cannot enable notifying for this remote.
What I realized is, that this remote control seems to have something
like MAC address randomization enabled (probably for security reasons).
It also does not propagate device information unless I start pairing
mode. Because of MAC address randomization it also seems that pairing is
buggy - only works sometimes with some special procedure.
I know this remote works, because if I connected in manually via
bluetoothctl sometimes I works with enabling of notifying. Also directly
after pairing it seemed to work.
Have you seen something like this before? What should I do?
It is probably using the privacy (aka Resolvable Private Address/RPA),
there were quite a few fixes since 5.55 so you might want to update
your version to the latest to see if pairing works properly, note that
the D-Bus object might use the RPA address when it is first paired but
after that if you restart the daemon it will use the Identity Address,
so the any code using the device objects shall not attempt to store
and access the object based on their addresses since that can change
due to these conditions.
Okay, thanks. I will check new version somehow. Unfortunately I cannot
change Kernel (currently 5.10) because of several drivers, devices and
patches. I am not sure how to selectively update BlueZ and if this even
works. Debian package in sid seems to be 5.66, but aren't this only the
user space tools?
However, my object manager implementation is quite simple / dumb. There
is no relation to MAC in there (find code below).
Aren't the service and characteristics information stored in the file
system using the MAC address? This would explain, why they are not found
after the MAC address randomized.
-----
package technology.tavla.platform.os.runtime.core.system.bluetooth;
import java.util.HashMap;
import java.util.Map;
import org.freedesktop.dbus.DBusPath;
import org.freedesktop.dbus.interfaces.ObjectManager;
import org.freedesktop.dbus.types.Variant;
import
technology.tavla.platform.os.runtime.common.service.system.bus.BusManager.Bus;
import
technology.tavla.platform.os.runtime.common.service.system.bus.BusManager.BusException;
import
technology.tavla.platform.os.runtime.core.system.bluetooth.object.AbstractLocalObject;
import
technology.tavla.platform.os.runtime.core.system.bluetooth.object.LocalObject;
import
technology.tavla.platform.os.runtime.core.system.bluetooth.profile.HID;
public class LocalObjectManager extends AbstractLocalObject implements
ObjectManager {
private Map<DBusPath, Map<String, Map<String, Variant<?>>>> objects
= new HashMap<DBusPath, Map<String, Map<String, Variant<?>>>>();
private Map<String, Map<String, Variant<?>>> properties = new
HashMap<String, Map<String, Variant<?>>>();
public LocalObjectManager(final Bus bus) throws BusException {
super("/" + LocalObjectManager.class.getName().replace(".", "/"));
bus.exportObject(this.getObjectPath(), this);
HID profile = new HID();
this.addObject(profile);
bus.exportObject(profile.getObjectPath(), profile);
}
@Override
public Map<DBusPath, Map<String, Map<String, Variant<?>>>>
GetManagedObjects() {
return this.objects;
}
@Override
public Map<String, Map<String, Variant<?>>> getProperties() {
return this.properties;
}
public <T extends LocalObject> void addObject(T object) {
this.objects.put(new DBusPath(object.getObjectPath()),
object.getProperties());
}
}
-----
package technology.tavla.platform.os.runtime.core.system.bluetooth.profile;
import java.util.HashMap;
import java.util.Map;
import org.bluez.GattProfile1;
import org.freedesktop.dbus.types.Variant;
import
technology.tavla.platform.os.runtime.common.service.system.bluetooth.BluetoothManager.BluetoothService;
public class HID extends AbstractLocalProfile {
private Map<String, Map<String, Variant<?>>> properties = new
HashMap<String, Map<String, Variant<?>>>();
public HID() {
super("/" + HID.class.getName().replace(".", "/"));
Map<String, Variant<?>> map = new HashMap<>();
map.put("UUIDs", new Variant<>(new String[] {
BluetoothService.Type.HUMAN_INTERFACE_DEVICE.getFullUUID()
}));
this.properties.put(GattProfile1.class.getName(), map);
}
@Override
public void Release() {
// TODO Auto-generated method stub
}
@Override
public <A> A Get(String interfaceName, String key) {
//return this.properties.get(interfaceName).get(key);
return null;
}
@Override
public <A> void Set(String interfaceName, String key, A value) {
}
@Override
public Map<String, Variant<?>> GetAll(String interfaceName) {
return this.properties.get(interfaceName);
}
@Override
public Map<String, Map<String, Variant<?>>> getProperties() {
return this.properties;
}
}
-----
Best regards,
Martin