Re: [PATCH BlueZ v2] src/gatt-client: always check properties in WriteValue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi David,

On Tue, Apr 28, 2020 at 10:19 AM David Lechner <david@xxxxxxxxxxxxxx> wrote:
>
> On 4/28/20 12:03 PM, Luiz Augusto von Dentz wrote:
> > Hi David,
> >
> > On Tue, Apr 28, 2020 at 7:39 AM David Lechner <david@xxxxxxxxxxxxxx> wrote:
> >>
> >> On 4/27/20 11:28 AM, Luiz Augusto von Dentz wrote:
> >>> Hi David,
> >>>
> >>> On Mon, Apr 27, 2020 at 8:07 AM David Lechner <david@xxxxxxxxxxxxxx> wrote:
> >>>>
> >>>> This modifies the GATT client characteristic WriteValue D-Bus method to
> >>>> always check that the characteristic supports the requested type of
> >>>> write by checking for the corresponding property before attempting to
> >>>> write.
> >>>>
> >>>> Before this change, if the "type" option was used and it was set to
> >>>> "reliable" or "request", then BlueZ would attempt the write even if the
> >>>> characteristic does not support that write type. On the other hand, if
> >>>> "type" was set to "command" or was not specified, the method would
> >>>> return a org.bluez.Error.NotSupported error without attempting to write.
> >>>>
> >>>> After this change, the WriteValue method will consistently return
> >>>> org.bluez.Error.NotSupported if the corresponding property flag is not
> >>>> set for all types of writes.
> >>>> ---
> >>>>
> >>>> v2 changes:
> >>>> - remove extra check of test variable not NULL
> >>>> - fix one line over 80 chars
> >>>>
> >>>>    src/gatt-client.c | 8 ++++----
> >>>>    1 file changed, 4 insertions(+), 4 deletions(-)
> >>>>
> >>>> diff --git a/src/gatt-client.c b/src/gatt-client.c
> >>>> index a9bfc2802..f80742fbb 100644
> >>>> --- a/src/gatt-client.c
> >>>> +++ b/src/gatt-client.c
> >>>> @@ -1016,8 +1016,8 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn,
> >>>>            *     - If value is larger than MTU - 3: long-write
> >>>>            *   * "write-without-response" property set -> write command.
> >>>>            */
> >>>> -       if ((!type && (chrc->ext_props & BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE))
> >>>> -                       || (type && !strcasecmp(type, "reliable"))) {
> >>>> +       if ((!type || !strcasecmp(type, "reliable")) && chrc->ext_props &
> >>>> +                               BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE) {
> >>>>                   supported = true;
> >>>>                   chrc->write_op = start_long_write(msg, chrc->value_handle, gatt,
> >>>>                                                   true, value, value_len, offset,
> >>>> @@ -1026,8 +1026,8 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn,
> >>>>                           return NULL;
> >>>>           }
> >>>>
> >>>> -       if ((!type && chrc->props & BT_GATT_CHRC_PROP_WRITE) ||
> >>>> -                       (type && !strcasecmp(type, "request"))) {
> >>>> +       if ((!type || !strcasecmp(type, "request")) && chrc->props &
> >>>> +                                               BT_GATT_CHRC_PROP_WRITE) {
> >>>>                   uint16_t mtu;
> >>>>
> >>>>                   supported = true;
> >>>> --
> >>>> 2.17.1
> >>>
> >>> As far I can remember this is on purpose so the application can
> >>> overwrite the type if it needs to disabling the checks on the client
> >>> side, though the kernel can still return not supported, so if we want
> >>> to change this it will now not be possible to overwrite it anymore.
> >>>
> >>
> >> If this is the case, does it make sense to make the following change
> >> instead so that write without response can also be forced?
> >>
> >> diff --git a/src/gatt-client.c b/src/gatt-client.c
> >> index f80742fbb..3153f571f 100644
> >> --- a/src/gatt-client.c
> >> +++ b/src/gatt-client.c
> >> @@ -1050,8 +1050,8 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn,
> >>                           return NULL;
> >>           }
> >>
> >> -       if ((type && strcasecmp(type, "command")) || offset ||
> >> -                       !(chrc->props & BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP))
> >> +       if ((type && strcasecmp(type, "command")) || offset || (!type &&
> >> +                       !(chrc->props & BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP)))
> >>                   goto fail;
> >>
> >>           supported = true;
> >
> > Yes, that is probably one of the use cases to use the type to force
> > sending a command if the client don't care about the response but the
> > server don't mark write without response as supported, is that what
> > you are after? That sounds like a bug since it appears the intention
> > was to allow commands all along.
> >
>
> I just noticed the inconsistency here while trying to implement
> writeValueWithResponse() and writeValueWithoutResponse() in the Web
> Bluetooth API for the Chromium browser and thought that it should
> probably all be one way or the other.
>
> FWIW, in the particular case I am working with, the device has both
> the WRITE and WRITE_WITHOUT_RESP properties set so I am using "type"
> to force writing without response since write with response would
> be selected otherwise.
>
> I will send a proper patch to fix the write without response case.

Great, that indeed shall be supported since both are allowed
bluetoothd will prefer Write since that gives a response, there is
also some means to mark the D-Bus message don't expect a reply as well
which might be another to solve this if you don't want to use type.

-- 
Luiz Augusto von Dentz



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux