2022-07-29 20:48:10

by John Klug

[permalink] [raw]
Subject: GattCharacteristic1 WriteValue fails parameter validation in a GATT Client

I see this is in the example-gatt-server, but not in a client.? Does anyone have this in an example? Ideally written in C or C++ with libgio.

My issue is that the parameter list is rejected when I use libgio:

Error?message: Method "WriteValue"?with?signature "aya{sv}"?on?interface?"org.bluez.GattCharacteristic1"?doesn't exist

Turning on bluetoothd? -d, I am not seeing this error.? I see my service appear.? gdbus introspection shows the interface and the WriteValue method, but the call to WriteValue does not seem to generate any debug output in bluetoothd.

I wrote this up in https://discourse.gnome.org/t/how-does-one-find-the-valid-signatures-in-d-bus-for-an-interface-method/10579/6

I have tried both Ubuntu 20.04 on a PC, and on an ARM 32bit processor I have tried Linux 5.4.199 with BlueZ 5.64.

How does one write to a gatt characteristic in a client if one is not to use WriteValue?


2022-07-29 21:39:45

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: GattCharacteristic1 WriteValue fails parameter validation in a GATT Client

Hi John,

On Fri, Jul 29, 2022 at 1:48 PM John Klug <[email protected]> wrote:
>
> I see this is in the example-gatt-server, but not in a client. Does anyone have this in an example? Ideally written in C or C++ with libgio.
>
> My issue is that the parameter list is rejected when I use libgio:
>
> Error message: Method "WriteValue" with signature "aya{sv}" on interface "org.bluez.GattCharacteristic1" doesn't exist

This is for a GATT Server, application implements WriteValue, or for
GATT client, bluetoothd implementation of WriteValue? In case of the
later you need to check if you are generating the message with the
right signature, for instance this is how we construct the WriteValue
parameters on bluetoothctl:

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/client/gatt.c#n714

> Turning on bluetoothd -d, I am not seeing this error. I see my service appear. gdbus introspection shows the interface and the WriteValue method, but the call to WriteValue does not seem to generate any debug output in bluetoothd.
>
> I wrote this up in https://discourse.gnome.org/t/how-does-one-find-the-valid-signatures-in-d-bus-for-an-interface-method/10579/6
>
> I have tried both Ubuntu 20.04 on a PC, and on an ARM 32bit processor I have tried Linux 5.4.199 with BlueZ 5.64.
>
> How does one write to a gatt characteristic in a client if one is not to use WriteValue?

You can use AcquireWrite and then write directly to the fd received.

--
Luiz Augusto von Dentz

2022-07-30 00:41:45

by John Klug

[permalink] [raw]
Subject: Re: GattCharacteristic1 WriteValue fails parameter validation in a GATT Client

Luiz Augusto von Dentz wrote:
> This is for a GATT Server, application implements WriteValue, or for
> GATT client, bluetoothd implementation of WriteValue?
This is for the GATT client. I have to write a password to the server from the client.

I got a little further. I found that libgio requires the error parameter in the parameter list to be cleared before every invocation. I don't yet have some semaphores in, and my code was in a loop doing the WriteValue until success, but the error value is not overwritten once it is set by g_dbus_connection_call_sync().

I am setting "type" to "command" in the dictionary for the 2nd parameter because I want no response.

It turns out if I clear the error on every loop, the error I see after WriteValue is issued on the characteristic:

* 0x55e74e6ca860: print_error: Error message: GDBus.Error:org.bluez.Error.InvalidArguments: Invalid arguments in method call
* 0x55e74e6ca860: print_error: Remote error
* 0x55e74e6ca860: print_error: Raw message: org.bluez.Error.InvalidArguments

Unfortunately turning on debug in bluetoothd tells me nothing more.

This happens to be the characteristic path:

/org/bluez/hci0/dev_CC_F9_57_89_8C_2D/service0021/char0046:

I sent this:

method call time=1659138398.987176 sender=:1.3571 -> destination=org.bluez serial=11 path=/org/bluez/hci0/dev_CC_F9_57_89_8A_FB/service0021/char0046; interface=org.bluez.GattCharacteristic1; member=WriteValue
array of bytes "MyPasswd" + \0
array [
dict entry(
string "type"
variant struct {
string "command"
}
)
]
error time=1659138398.987326 sender=:1.3568 -> destination=:1.3571 error_name=org.bluez.Error.InvalidArguments reply_serial=11
string "Invalid arguments in method call"


Here is what was added earlier for this characteristic:

signal time=1659138398.895579 sender=:1.3568 -> destination=(null destination) serial=131 path=/; interface=org.freedesktop.DBus.ObjectManager; member=InterfacesAdded
object path "/org/bluez/hci0/dev_CC_F9_57_89_8A_FB/service0021/char0046"
array [
dict entry(
string "org.freedesktop.DBus.Introspectable"
array [
]
)
dict entry(
string "org.bluez.GattCharacteristic1"
array [
dict entry(
string "UUID"
variant string "edf50100-681e-4b92-999c-e16b3a8bc047"
)
dict entry(
string "Service"
variant object path "/org/bluez/hci0/dev_CC_F9_57_89_8A_FB/service0021"
)
dict entry(
string "Value"
variant array [
]
)
dict entry(
string "Flags"
variant array [
string "read"
string "write"
]
)
]
)


Luiz Augusto von Dentz wrote:
>You can use AcquireWrite and then write directly to the fd received.
If I do AcquireWrite, I do write(fd,buf,strlen(buf)), then close(fd)?

I am only writing 8 characters + maybe a NULL.

I will try the file handle method next.



2022-08-01 16:13:06

by John Klug

[permalink] [raw]
Subject: Re: GattCharacteristic1 WriteValue fails parameter validation in a GATT Client

Luiz Augusto von Dentz writes:

>You can use AcquireWrite and then write directly to the fd received.

I tried AcquireWrite as you suggest.? The result was "NotSupported". I
should mention that I have tried Nordic's NRF Connect on Android with
the same GATT Server, and it is able to write to this
UUID/characteristic just fine.


Using "dbus-monitor --system" I see both read and write flags on my characteristic "service0021/char0046" with the correct UUID:


signal time=1659368288.691466 sender=:1.3649 -> destination=(null
destination) serial=968 path=/;
interface=org.freedesktop.DBus.ObjectManager; member=InterfacesAdded

? ?object path "/org/bluez/hci0/dev_CC_F9_57_89_8B_D8/service0021/char0046"
? ?array [
? ? ? dict entry(
? ? ? ? ?string "org.freedesktop.DBus.Introspectable"
? ? ? ? ?array [
? ? ? ? ?]
? ? ? )
? ? ? dict entry(
? ? ? ? ?string "org.bluez.GattCharacteristic1"
? ? ? ? ?array [
? ? ? ? ? ? dict entry(
? ? ? ? ? ? ? ?string "UUID"
? ? ? ? ? ? ? ?variant ? ? ? ? ? ? ? ? ? string "edf50100-681e-4b92-999c-e16b3a8bc047"
? ? ? ? ? ? )
? ? ? ? ? ? dict entry(
? ? ? ? ? ? ? ?string "Service"
? ? ? ? ? ? ? ?variant ? ? ? ? ? ? ? ? ? object path "/org/bluez/hci0/dev_CC_F9_57_89_8B_D8/service0021"
? ? ? ? ? ? )
? ? ? ? ? ? dict entry(
? ? ? ? ? ? ? ?string "Value"
? ? ? ? ? ? ? ?variant ? ? ? ? ? ? ? ? ? array [
? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? )
? ? ? ? ? ? dict entry(
? ? ? ? ? ? ? ?string "Flags"
? ? ? ? ? ? ? ?variant ? ? ? ? ? ? ? ? ? array [
? ? ? ? ? ? ? ? ? ? ?string "read"
? ? ? ? ? ? ? ? ? ? ?string "write"
? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? )
? ? ? ? ?]
? ? ? )
? ? ? dict entry(
? ? ? ? ?string "org.freedesktop.DBus.Properties"
? ? ? ? ?array [
? ? ? ? ?]
? ? ? )
? ?]



However, AcquireWrite replies with "Not Supported" which is the text I see in the error message in my program:


method call time=1659368290.693590 sender=:1.3987 ->
destination=org.bluez serial=10
path=/org/bluez/hci0/dev_CC_F9_57_89_8B_D8/service0021/char0046;
interface=org.bluez.GattCharacteristic1; member=AcquireWrite

? ?array [
? ?]
error time=1659368290.693700 sender=:1.3649 -> destination=:1.3987 error_name=org.bluez.Error.NotSupported reply_serial=10
? ?string "Operation is not supported"

Any ideas on where in the BlueZ source I could look for this? Does anyone have an example of doing a GATT Write from a client?



John Klug

2022-08-01 16:36:23

by Adam Pigg

[permalink] [raw]
Subject: Re: GattCharacteristic1 WriteValue fails parameter validation in a GATT Client

On Mon, 1 Aug 2022 at 17:11, John Klug <[email protected]> wrote:
>
> Luiz Augusto von Dentz writes:
>
> >You can use AcquireWrite and then write directly to the fd received.
>
> I tried AcquireWrite as you suggest. The result was "NotSupported". I
> should mention that I have tried Nordic's NRF Connect on Android with
> the same GATT Server, and it is able to write to this
> UUID/characteristic just fine.
>
>
> Using "dbus-monitor --system" I see both read and write flags on my characteristic "service0021/char0046" with the correct UUID:
>
>
> signal time=1659368288.691466 sender=:1.3649 -> destination=(null
> destination) serial=968 path=/;
> interface=org.freedesktop.DBus.ObjectManager; member=InterfacesAdded
>
> object path "/org/bluez/hci0/dev_CC_F9_57_89_8B_D8/service0021/char0046"
> array [
> dict entry(
> string "org.freedesktop.DBus.Introspectable"
> array [
> ]
> )
> dict entry(
> string "org.bluez.GattCharacteristic1"
> array [
> dict entry(
> string "UUID"
> variant string "edf50100-681e-4b92-999c-e16b3a8bc047"
> )
> dict entry(
> string "Service"
> variant object path "/org/bluez/hci0/dev_CC_F9_57_89_8B_D8/service0021"
> )
> dict entry(
> string "Value"
> variant array [
> ]
> )
> dict entry(
> string "Flags"
> variant array [
> string "read"
> string "write"
> ]
> )
> ]
> )
> dict entry(
> string "org.freedesktop.DBus.Properties"
> array [
> ]
> )
> ]
>
>
>
> However, AcquireWrite replies with "Not Supported" which is the text I see in the error message in my program:
>
>
> method call time=1659368290.693590 sender=:1.3987 ->
> destination=org.bluez serial=10
> path=/org/bluez/hci0/dev_CC_F9_57_89_8B_D8/service0021/char0046;
> interface=org.bluez.GattCharacteristic1; member=AcquireWrite
>
> array [
> ]
> error time=1659368290.693700 sender=:1.3649 -> destination=:1.3987 error_name=org.bluez.Error.NotSupported reply_serial=10
> string "Operation is not supported"
>
> Any ideas on where in the BlueZ source I could look for this? Does anyone have an example of doing a GATT Write from a client?

I have a watch companion application called Amazfish which does a lot
of writing using the DBUS api. I wrote a simple Qt style wrapper
around the dbus part which is at https://github.com/piggz/qble , and
the app is at https://github.com/piggz/harbour-amazfish . Perhaps
something in there will help you.

Adam
>
>
>
> John Klug