DBus Introspection incomplete/wrong - bluetooth-lowenergy

I'm trying to work with Bluetooth LE on a RPI4, and am following the Bluetooth® Technology for Linux Developers official guide. The python code works fine, but I have to do it in c++, and as of now, I'm blocking at the Advertising step.
I then tried to Intospect the service created by the python programme to compare to what I'm doing in c++, but the introspection result is strange : Intospection in d-feet
I don't understand why the org.bluez.LEAdvertisingManager1 interface is there instead of the org.bluez.LEAdvertisement1 interface. Have I broken dbus ? or are invisible interfaces just a thing ?
Edit
I compared the code for the server_advertising.py example of the Bluetooth® Technology for Linux Developers guide, and for the example-advertisement of the bluez git, and found out that most likely, in the first one, they are implementing the org.bluez.LEAdvertisement1interface while naming it org.bluez.LEAdvertisingManager1...
That would be why I get the same result when introspecting the two, whith only the interface name changing.
As for why I can't see the Properties, from what I now understand, they appear (in both examples) to not have properly registered them, and just overrode the GetAll method to return whatever value they have in their programs. (╯°□°)╯︵ ┻━┻
Thanks to you I now understand the result i got, but I am sad to learn that the introspection won't be usefull...

BlueZ uses a technique where an interface (org.bluez.LEAdvertisement1) is defined for the developer to create the advertisement and publish it to D-Bus.
The location of that created interface implementation is given to BlueZ using the RegisterAdvertisement command on the org.bluez.LEAdvertisingManager1 interface.
This is why the interfaces that need to be implemented are documented as:
Object path: freely definable
Because the relevant Register* command will be used to tell BlueZ the object path of the interface that has been implemented.
To state this a different way, BlueZ provides a blueprint for D-Bus services that it needs to do certain things. e.g. advertising or an agent. The documented interface has no implementation. This is created for the specific instance (e.g. what is to be to advertised). BlueZ is told where to find this interface implementation with the specific Register* command.
Using the example at https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-advertisement.
I can see that I have started the service but I am not able to introspect it because there is no introspection information given.
To advertise:
$ python3 example-advertisement
In another window I can see a new service is published but there is no access to introspect on the service:
$ busctl list | grep python
:1.862 23113 python3 pi :1.862 session-1820.scope 1820 -
$ busctl introspect :1.862 /org/bluez/example/advertisement0
Failed to introspect object /org/bluez/example/advertisement0 of service :1.862: Access denied
The GetAll method is implemented so I can call that (with sudo):
$ sudo busctl call :1.862 /org/bluez/example/advertisement0 org.freedesktop.DBus.Properties GetAll s org.bluez.LEAdvertisement1
a{sv} 7 "Type" s "peripheral" "ServiceUUIDs" as 2 "180D" "180F" "ManufacturerData" a{qv} 1 65535 ay 4 0 1 2 3 "ServiceData" a{sv} 1 "9999" ay 5 0 1 2 3 4 "LocalName" s "TestAdvertisement" "Includes" as 1 "tx-power" "Data" a{yv} 1 38 ay 3 1 1 0

Related

bluetoothctl: using gatt menu commands in non-interactive mode

On my Raspberry Pi 4, I would like to use bluetoothctl in non interactive mode but cannot figure out how to access the gatt menu. The command should be something like "bluetoothctl gatt menu list-attributes" but this syntax doesn't work.
For info, in interactive mode one must type "menu gatt" to switch to gatt menu and then commands like "list-attributes" are available.
Thanks in advance !
Eric
bluetoothctl allows for the commands to be specified using a dot to indicate the hierarchy. e.g gatt.list-attributes
For accessing information with code BlueZ provides APIs using D-Bus bindings.
For example, to get all the information BlueZ has can be done like this:
import pydbus
bus = pydbus.SystemBus()
obj_mngr = bus.get('org.bluez', '/')
mngd_objs = obj_mngr.GetManagedObjects()
for path, obj in mngd_objs.items():
print(obj)
The API is documented at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
Examples are available at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test

Can I use wildcard on info-plist for Bonjour services

My apps using bonjour service to conversation with each other via local network.
I am facing a problem on Xcode12 with OS14 device.
A device publish a service with server type name depends on self device IP address
(example: 192.168.33.20 -> _1921683320._tcp)
B device searching a service with service type depends on A device IP address
(example: _1921683320._tcp)
According to apple document..From OS14~
https://developer.apple.com/documentation/multipeerconnectivity
Important
Apps that use the local network must provide a usage string in their Info.plist with the key NSLocalNetworkUsageDescription. Apps that use Bonjour must also declare the services they browse, using the NSBonjourServices key.
because my service type name is named by local network ip, it is changeable base on local network setting, so I am thinking about to using wildcard to define the service type name.
example: _*._tcp
but seems wildcard is not available on this definition.(I tried it)
I am also thinking about changing the naming method on A device
(example: 192.168.33.20 -> _20._tcp)
and add _1.tcp ~ _255.tcp to info-plist
But if I changed the naming method, B device could not find A device until version up.
Any idea for this problem? Please help.
I'm currently working through the same issue - Bonjour service name is dynamically created based off the iPad name to form a local mesh network. The conclusion that I have came to is com.apple.developer.networking.multicast is required for this to function without completely overhauling how all that logic is done. (More info here)
You will have to request permission from apple by filling out a form here. Let me know if this works for you!
The thing I am finding is, you "might" not be able to use a wildcard, but you can put multiple entries in the plist:
Item 0 _multicastapp0-p._tcp
Item 1 _multicastapp1-p._tcp
Item 2 _multicastapp2-p._tcp
Item 3 _multicastapp3-p._tcp
etc
Item N _multicastappN-p._tcp
So for some reason if you are trying to have multiple "Groups" of 8 or have a device have it's own "collection" i.e. be a server and have 3 devices connect to that, you can.
I haven't "fully" tested but I am going to be doing this in my apps, I did test using multiple keys tho, but not fully, no errors...

No such interface 'org.freedesktop.DBus.Properties' on object at path /org/freedesktop/NetworkManager/ActiveConnection/

I start my qt application in the user's .profile file (not root) to make the app start on boot. Sometimes when my application start, it reports an warning as below:
"No such interface 'org.freedesktop.DBus.Properties' on object at path /org/freedesktop/NetworkManager/ActiveConnection/1"
I searched on google but did not find a explanation.
It seems my app is still working fine, but I want to locate the problem.
The application is running on ubuntu and using Qt5.
Thanks in advance.
Edit
I tried to debug dbus based on Eligijus Pupeikis's help with running:
gdbus introspect --system \
--dest org.freedesktop.NetworkManager \
--object-path /org/freedesktop/NetworkManager/ActiveConnection
it returns:
node /org/freedesktop/NetworkManager/ActiveConnection {
node 0 {
};
};
So, this means there is no such object just as the error message said, right?
And also, this gns3 team member says this problem is about Qt and Ubuntu.
Does this mean I don't need to solve it? I not familiar with the relationship between dbus and qt.
Most likely there is no such object "/org/freedesktop/NetworkManager/ActiveConnection/1" and because of that it can't find 'org.freedesktop.DBus.Properties' interface.
From documentation org.freedesktop.NetworkManager.Connection.Active :
Objects that implement the Connection.Active interface represent an attempt to connect to a network using the details provided by a Connection object. The Connection.Active object tracks the life-cycle of the connection attempt and if successful indicates whether the connected network is the "default" or preferred network for access. NetworkManager has the concept of connections, which can be thought of as settings, a profile or a configuration that can be applied on a networking device. Such settings-connections are exposed as D-Bus object and the active-connection expresses this relationship between device and settings-connection. At any time a settings-connection can only be activated on one device and vice versa. However, during activation and deactivation multiple active-connections can reference the same device or settings-connection as they are waiting to be activated or to be deactivated.
You can't know that that ActiveConnection object with specifically index 1 exists so you need to check by reading ActiveConnections property from /org/freedesktop/NetworkManager object's org.freedesktop.NetworkManager interface.
To have better visualize and understand how it looks I suggest D-Bus debugger. If you are using Gnome check out D-Feet.

Stonestreet One's Bluetopia how do you request a MTU change?

Or more specifically how do you request an MTU change when operating at the "Platform Manager" level?
More details
I'm using the sample program LinuxGATM_CLT which acts as a GATT client and it uses the Bluetopia Platform Manager Framework.
I'm using TI's WL183xMOD WiLink hardware which uses Bluetopia (previously owned by Stonestreet One).
The API call exists
The function exists, but seems to be at stack layer lower than the PM:
~/src/ti_bluetopia/ $ grep GATT_Exchange_MTU_Request ./BluetopiaPM/Bluetopia/include/GATTAPI.h
BTPSAPI_DECLARATION int BTPSAPI GATT_Exchange_MTU_Request(unsigned int BluetoothStackID, unsigned int ConnectionID, Word_t RequestedMTU, GATT_Client_Event_Callback_t ClientEventCallback, unsigned long CallbackParameter);
But its not callable from the "Platform Manager" level
Everything within BluetopiaPM/sample/LinuxGATM/LinuxGATM_CLT.c uses GATM functions from BluetopiaPM/include/client/GATMAPI.h
It feels like the GATT_Exchange_MTU_Request() function has not been exposed at the PM level. Its hard to dig deeper into how the PM works because they only ship binaries (doesn't seem to be open-source). For example the only match is the GATTAPI.h header file and a binary library file:
~/src/ti_bluetopia/ $ grep -ri GATT_Initialize ./
Binary file ./BluetopiaPM/Bluetopia/lib/libSS1BTGAT.a matches
I feel like the solution is to find methods to report my current Platform Manager BluetoothStackID, ConnectionID, and callback parameters so that I can call the GATT_Exchange_MTU_Request() function directly.
In short, the workaround is to get an earlier version of Stonestreet One's Bluetopia, before they created the "Platform Manager". These earlier versions (suchas 4.012 and 4.013) don't have the advantage of the Platform Manager, but they do allow you to have more control, operating at a lower level where you can call:
GATT_Initialize() and
GATT_Exchange_MTU_Request()
One good example is 4.013's SPPLEDemo.c which calls the above-mentioned methods.

Exporting GSSCredential to byte array and vice versa

I am implementing S4U protocol using GSS in java. Since java 7 does not support this protocol, I plan to write a JNI wrapper over the gss api methods in C that do not have equivalent in java.
As part of this I am writing a JNI over gss_acquire_cred_impersonate_name as described in
http://k5wiki.kerberos.org/wiki/Projects/Services4User#gss_acquire_cred_impersonate_name .
This method takes an previously populated input credential handle (gss_cred_id_t) and populates an output credential handle. In my java code I have a GSSCredential created which I need to pass to C function in form of gss_cred_id_t and convert the output credential handle from gss_cred_id_t back to GSSCredential for further use.
How can I export GSSCredential object to byte array and vice versa in order to communicate with the C function ?
Thanks
You should rather Java 8 code, it has built-in support.
Export cred us a custom extension for GSS-API and therefore not available. The Globus JGSS implementation support this extension.
When I had a similar problem I used https://github.com/cconlon/kerberos-java-gssapi and did all my GSS-API work though the wrapper. (But that was only a temporary stage before discarding Java altogether.)

Resources