Re: [PATCH BlueZ 1/3] input/hog-lib: Add support to gatt-db

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

 



Hi Petri,

On Fri, Dec 30, 2016 at 2:47 AM, Petri Gynther <pgynther@xxxxxxxxxx> wrote:
> Hi Luiz,
>
> Are these 3 patches supposed to eliminate re-reading the HoG report
> map from the device on reconnect? And get it from GATT DB instead?

Nope, there is no caching for values only handles so this is working
as intended, though in the future we may allow the profile to store
the values directly in the db which should indicate the core to store
it on file but if we were strictly following the spec the values could
in fact change.

> I merged the tip of BlueZ and tried it with our HoG remote. But, I
> still see Read Blob Requests & Responses being sent over air to
> re-read the report map:
>
> 15,3601,88379000,-;btmon: < ACL Data TX: Handle 128 flags 0x00 dlen 9
>             [hci0] 00:35:56.596115
> 15,3602,88379000,-;btmon:       ATT: Read Blob Request (0x0c) len 4
> 15,3603,88379000,-;btmon:         Handle: 0x0041
> 15,3604,88379000,-;btmon:         Offset: 0x0016
> --
> 15,3609,88402000,-;btmon: > ACL Data RX: Handle 128 flags 0x02 dlen 27
>             [hci0] 00:35:56.624487
> 15,3610,88402000,-;btmon:       ATT: Read Blob Response (0x0d) len 22
> 15,3611,88402000,-;btmon:         81 02 95 01 75 08 81 01 95 05 75 01
> 05 08 19 01  ....u.....u.....
> 15,3612,88402000,-;btmon:         29 05 91 02 95 01
>             ).....
> --
> 15,3704,88585000,-;btmon: < ACL Data TX: Handle 128 flags 0x00 dlen 9
>             [hci0] 00:35:56.805750
> 15,3705,88585000,-;btmon:       ATT: Read Blob Request (0x0c) len 4
> 15,3706,88585000,-;btmon:         Handle: 0x0041
> 15,3707,88585000,-;btmon:         Offset: 0x002c
> --
> 15,3712,88609000,-;btmon: > ACL Data RX: Handle 128 flags 0x02 dlen 27
>             [hci0] 00:35:56.831684
> 15,3713,88609000,-;btmon:       ATT: Read Blob Response (0x0d) len 22
> 15,3714,88609000,-;btmon:         75 03 91 01 95 06 75 08 15 00 25 73
> 05 07 19 00  u.....u...%s....
> 15,3715,88610000,-;btmon:         29 73 81 00 c0 05
>             )s....
> --
> 15,3842,89855000,-;btmon: < ACL Data TX: Handle 128 flags 0x00 dlen 9
>             [hci0] 00:35:58.074749
> 15,3843,89855000,-;btmon:       ATT: Read Blob Request (0x0c) len 4
> 15,3844,89855000,-;btmon:         Handle: 0x0041
> 15,3845,89855000,-;btmon:         Offset: 0x0042
> --
> 15,3850,89882000,-;btmon: > ACL Data RX: Handle 128 flags 0x02 dlen 27
>             [hci0] 00:35:58.104341
> 15,3851,89882000,-;btmon:       ATT: Read Blob Response (0x0d) len 22
> 15,3852,89882000,-;btmon:         0c 09 01 a1 01 85 03 05 0c a1 02 19
> 00 2a 3c 02  .............*<.
> 15,3853,89882000,-;btmon:         15 00 26 3c 02 95
>             ..&<..
> --
> 15,3984,90013000,-;btmon: < ACL Data TX: Handle 128 flags 0x00 dlen 9
>             [hci0] 00:35:58.235072
> 15,3985,90016000,-;btmon:       ATT: Read Blob Request (0x0c) len 4
> 15,3986,90016000,-;btmon:         Handle: 0x0041
> 15,3987,90016000,-;btmon:         Offset: 0x0058
> --
> 15,3992,90041000,-;btmon: > ACL Data RX: Handle 128 flags 0x02 dlen 27
>             [hci0] 00:35:58.263061
> 15,3993,90041000,-;btmon:       ATT: Read Blob Response (0x0d) len 22
> 15,3994,90041000,-;btmon:         01 75 10 81 00 c0 c0 06 00 ff 09 07
> a1 01 85 81  .u..............
> 15,3995,90041000,-;btmon:         19 00 2a ff 00 15
>             ..*...
> --
> 15,4062,90309000,-;btmon: < ACL Data TX: Handle 128 flags 0x00 dlen 9
>             [hci0] 00:35:58.529604
> 15,4063,90309000,-;btmon:       ATT: Read Blob Request (0x0c) len 4
> 15,4064,90309000,-;btmon:         Handle: 0x0041
> 15,4065,90309000,-;btmon:         Offset: 0x006e
> --
> 15,4073,90623000,-;btmon: > ACL Data RX: Handle 128 flags 0x02 dlen 16
>             [hci0] 00:35:58.843074
> 15,4074,90623000,-;btmon:       ATT: Read Blob Response (0x0d) len 11
> 15,4075,90623000,-;btmon:         00 26 ff 00 75 08 95 01 81 02 c0
>             .&..u......
> 15,4076,90623000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb() HoG inspecting report
> map
> 15,4077,90623000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb() Report MAP:
> 15,4078,90623000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          05 01
> 15,4079,90623000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          09 06
> 15,4080,90623000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          a1 01
> 15,4081,90623000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          85 02
> 15,4082,90623000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          05 07
> 15,4083,90624000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          19 e0
> 15,4084,90625000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          29 e7
> 15,4085,90625000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          15 00
> 15,4086,90627000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          25 01
> 15,4087,90627000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          75 01
> 15,4088,90629000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          95 08
> 15,4089,90630000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          81 02
> 15,4090,90633000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          95 01
> 15,4091,90634000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          75 08
> 15,4092,90637000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          81 01
> 15,4093,90638000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          95 05
> 15,4094,90641000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          75 01
> 15,4095,90641000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          05 08
> 15,4096,90642000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          19 01
> 15,4097,90642000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          29 05
> 15,4098,90645000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          91 02
> 15,4099,90646000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          95 01
> 15,4100,90647000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          75 03
> 15,4101,90649000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          91 01
> 15,4102,90650000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          95 06
> 15,4103,90650000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          75 08
> 15,4104,90656000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          15 00
> 15,4105,90658000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          25 73
> 15,4106,90658000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          05 07
> 15,4107,90661000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          19 00
> 15,4108,90662000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          29 73
> 15,4109,90669000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          81 00
> 15,4110,90669000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          c0
> 15,4111,90672000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          05 0c
> 15,4112,90672000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          09 01
> 15,4113,90673000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          a1 01
> 15,4114,90673000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          85 03
> 15,4115,90676000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          05 0c
> 15,4116,90676000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          a1 02
> 15,4117,90677000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          19 00
> 15,4118,90678000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          2a 3c 02
> 15,4119,90678000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          15 00
> 15,4120,90680000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          26 3c 02
> 15,4121,90681000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          95 01
> 15,4122,90683000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          75 10
> 15,4123,90684000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          81 00
> 15,4124,90686000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          c0
> 15,4125,90688000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          c0
> 15,4126,90689000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          06 00 ff
> 15,4127,90690000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          09 07
> 15,4128,90694000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          a1 01
> 15,4129,90694000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          85 81
> 15,4130,90695000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          19 00
> 15,4131,90696000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          2a ff 00
> 15,4132,90696000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          15 00
> 15,4133,90697000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          26 ff 00
> 15,4134,90697000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          75 08
> 15,4135,90698000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          95 01
> 15,4136,90698000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          81 02
> 15,4137,90699000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb()          c0
> 15,4140,90713000,-;bluez: bluetoothd[2345]:
> profiles/input/hog-lib.c:report_map_read_cb() HoG created uHID device
>
> On Thu, Dec 29, 2016 at 5:23 AM, Luiz Augusto von Dentz
> <luiz.dentz@xxxxxxxxx> wrote:
>> Hi,
>>
>> On Tue, Dec 27, 2016 at 2:40 PM, Luiz Augusto von Dentz
>> <luiz.dentz@xxxxxxxxx> wrote:
>>> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>>>
>>> This add support of passing a gatt-db to avoid having to discover the
>>> services again, this should also make it easier to port to bt_gatt_client
>>> once Android code support it.
>>> ---
>>>  android/hidhost.c        |   4 +
>>>  profiles/input/hog-lib.c | 247 +++++++++++++++++++++++++++++++++++++++++------
>>>  profiles/input/hog-lib.h |   4 +-
>>>  profiles/input/hog.c     |  61 ++++++------
>>>  unit/test-hog.c          |   6 ++
>>>  5 files changed, 255 insertions(+), 67 deletions(-)
>>>
>>> diff --git a/android/hidhost.c b/android/hidhost.c
>>> index 591ca95..fe0ea2f 100644
>>> --- a/android/hidhost.c
>>> +++ b/android/hidhost.c
>>> @@ -38,9 +38,13 @@
>>>  #include "lib/bluetooth.h"
>>>  #include "lib/sdp.h"
>>>  #include "lib/sdp_lib.h"
>>> +#include "lib/uuid.h"
>>>  #include "src/shared/mgmt.h"
>>>  #include "src/shared/util.h"
>>>  #include "src/shared/uhid.h"
>>> +#include "src/shared/queue.h"
>>> +#include "src/shared/att.h"
>>> +#include "src/shared/gatt-db.h"
>>>  #include "src/sdp-client.h"
>>>  #include "src/uuid-helper.h"
>>>  #include "src/log.h"
>>> diff --git a/profiles/input/hog-lib.c b/profiles/input/hog-lib.c
>>> index e376c2b..ed38916 100644
>>> --- a/profiles/input/hog-lib.c
>>> +++ b/profiles/input/hog-lib.c
>>> @@ -45,6 +45,8 @@
>>>  #include "src/shared/util.h"
>>>  #include "src/shared/uhid.h"
>>>  #include "src/shared/queue.h"
>>> +#include "src/shared/att.h"
>>> +#include "src/shared/gatt-db.h"
>>>  #include "src/log.h"
>>>
>>>  #include "attrib/att.h"
>>> @@ -59,6 +61,7 @@
>>>  #include "profiles/input/hog-lib.h"
>>>
>>>  #define HOG_UUID               "00001812-0000-1000-8000-00805f9b34fb"
>>> +#define HOG_UUID16             0x1812
>>>
>>>  #define HOG_INFO_UUID          0x2A4A
>>>  #define HOG_REPORT_MAP_UUID    0x2A4B
>>> @@ -83,6 +86,7 @@ struct bt_hog {
>>>         uint16_t                vendor;
>>>         uint16_t                product;
>>>         uint16_t                version;
>>> +       struct gatt_db_attribute *attr;
>>>         struct gatt_primary     *primary;
>>>         GAttrib                 *attrib;
>>>         GSList                  *reports;
>>> @@ -110,9 +114,11 @@ struct report {
>>>         struct bt_hog           *hog;
>>>         uint8_t                 id;
>>>         uint8_t                 type;
>>> +       uint16_t                handle;
>>> +       uint16_t                value_handle;
>>> +       uint8_t                 properties;
>>>         uint16_t                ccc_handle;
>>>         guint                   notifyid;
>>> -       struct gatt_char        *decl;
>>>         uint16_t                len;
>>>         uint8_t                 *value;
>>>  };
>>> @@ -181,6 +187,10 @@ static void read_char(struct bt_hog *hog, GAttrib *attrib, uint16_t handle,
>>>         struct gatt_request *req;
>>>         unsigned int id;
>>>
>>> +       /* Ignore if not connected */
>>> +       if (!attrib)
>>> +               return;
>>> +
>>>         req = create_request(hog, user_data);
>>>         if (!req)
>>>                 return;
>>> @@ -334,7 +344,7 @@ static void report_ccc_written_cb(guint8 status, const guint8 *pdu,
>>>
>>>         report->notifyid = g_attrib_register(hog->attrib,
>>>                                         ATT_OP_HANDLE_NOTIFY,
>>> -                                       report->decl->value_handle,
>>> +                                       report->value_handle,
>>>                                         report_value_cb, report, NULL);
>>>
>>>         DBG("Report characteristic descriptor written: notifications enabled");
>>> @@ -403,7 +413,7 @@ static void report_reference_cb(guint8 status, const guint8 *pdu,
>>>         report->id = pdu[1];
>>>         report->type = pdu[2];
>>>
>>> -       DBG("Report 0x%04x: id 0x%02x type %s", report->decl->value_handle,
>>> +       DBG("Report 0x%04x: id 0x%02x type %s", report->value_handle,
>>>                                 report->id, type_to_string(report->type));
>>>
>>>         /* Enable notifications only for Input Reports */
>>> @@ -516,7 +526,7 @@ static int report_chrc_cmp(const void *data, const void *user_data)
>>>         const struct report *report = data;
>>>         const struct gatt_char *decl = user_data;
>>>
>>> -       return report->decl->handle - decl->handle;
>>> +       return report->handle - decl->handle;
>>>  }
>>>
>>>  static struct report *report_new(struct bt_hog *hog, struct gatt_char *chr)
>>> @@ -531,7 +541,9 @@ static struct report *report_new(struct bt_hog *hog, struct gatt_char *chr)
>>>
>>>         report = g_new0(struct report, 1);
>>>         report->hog = hog;
>>> -       report->decl = g_memdup(chr, sizeof(*chr));
>>> +       report->handle = chr->handle;
>>> +       report->value_handle = chr->value_handle;
>>> +       report->properties = chr->properties;
>>>         hog->reports = g_slist_append(hog->reports, report);
>>>
>>>         read_char(hog, hog->attrib, chr->value_handle, report_read_cb, report);
>>> @@ -691,16 +703,16 @@ static void forward_report(struct uhid_event *ev, void *user_data)
>>>         }
>>>
>>>         DBG("Sending report type %d ID %d to handle 0x%X", report->type,
>>> -                               report->id, report->decl->value_handle);
>>> +                               report->id, report->value_handle);
>>>
>>>         if (hog->attrib == NULL)
>>>                 return;
>>>
>>> -       if (report->decl->properties & GATT_CHR_PROP_WRITE)
>>> -               write_char(hog, hog->attrib, report->decl->value_handle,
>>> +       if (report->properties & GATT_CHR_PROP_WRITE)
>>> +               write_char(hog, hog->attrib, report->value_handle,
>>>                                 data, size, output_written_cb, hog);
>>> -       else if (report->decl->properties & GATT_CHR_PROP_WRITE_WITHOUT_RESP)
>>> -               gatt_write_cmd(hog->attrib, report->decl->value_handle,
>>> +       else if (report->properties & GATT_CHR_PROP_WRITE_WITHOUT_RESP)
>>> +               gatt_write_cmd(hog->attrib, report->value_handle,
>>>                                                 data, size, NULL, NULL);
>>>  }
>>>
>>> @@ -789,13 +801,13 @@ static void set_report(struct uhid_event *ev, void *user_data)
>>>         }
>>>
>>>         DBG("Sending report type %d ID %d to handle 0x%X", report->type,
>>> -                               report->id, report->decl->value_handle);
>>> +                               report->id, report->value_handle);
>>>
>>>         if (hog->attrib == NULL)
>>>                 return;
>>>
>>>         hog->setrep_att = gatt_write_char(hog->attrib,
>>> -                                               report->decl->value_handle,
>>> +                                               report->value_handle,
>>>                                                 data, size, set_report_cb,
>>>                                                 hog);
>>>         if (!hog->setrep_att) {
>>> @@ -878,7 +890,7 @@ static void get_report(struct uhid_event *ev, void *user_data)
>>>         }
>>>
>>>         hog->getrep_att = gatt_read_char(hog->attrib,
>>> -                                               report->decl->value_handle,
>>> +                                               report->value_handle,
>>>                                                 get_report_cb, hog);
>>>         if (!hog->getrep_att) {
>>>                 err = ENOMEM;
>>> @@ -1180,7 +1192,6 @@ static void report_free(void *data)
>>>         struct report *report = data;
>>>
>>>         g_free(report->value);
>>> -       g_free(report->decl);
>>>         g_free(report);
>>>  }
>>>
>>> @@ -1211,14 +1222,132 @@ static void hog_free(void *data)
>>>
>>>  struct bt_hog *bt_hog_new_default(const char *name, uint16_t vendor,
>>>                                         uint16_t product, uint16_t version,
>>> -                                       void *primary)
>>> +                                       struct gatt_db *db)
>>>  {
>>> -       return bt_hog_new(-1, name, vendor, product, version, primary);
>>> +       return bt_hog_new(-1, name, vendor, product, version, db);
>>>  }
>>>
>>> -struct bt_hog *bt_hog_new(int fd, const char *name, uint16_t vendor,
>>> +static void foreach_hog_report(struct gatt_db_attribute *attr, void *user_data)
>>> +{
>>> +       struct report *report = user_data;
>>> +       struct bt_hog *hog = report->hog;
>>> +       const bt_uuid_t *uuid;
>>> +       bt_uuid_t ref_uuid, ccc_uuid;
>>> +       uint16_t handle;
>>> +
>>> +       handle = gatt_db_attribute_get_handle(attr);
>>> +       uuid = gatt_db_attribute_get_type(attr);
>>> +
>>> +       bt_uuid16_create(&ref_uuid, GATT_REPORT_REFERENCE);
>>> +       if (!bt_uuid_cmp(&ref_uuid, uuid)) {
>>> +               read_char(hog, hog->attrib, handle, report_reference_cb,
>>> +                                                               report);
>>> +               return;
>>> +       }
>>> +
>>> +       bt_uuid16_create(&ccc_uuid, GATT_CLIENT_CHARAC_CFG_UUID);
>>> +       if (!bt_uuid_cmp(&ccc_uuid, uuid))
>>> +               report->ccc_handle = handle;
>>> +}
>>> +
>>> +static int report_attr_cmp(const void *data, const void *user_data)
>>> +{
>>> +       const struct report *report = data;
>>> +       const struct gatt_db_attribute *attr = user_data;
>>> +
>>> +       return report->handle - gatt_db_attribute_get_handle(attr);
>>> +}
>>> +
>>> +static struct report *report_add(struct bt_hog *hog,
>>> +                                       struct gatt_db_attribute *attr)
>>> +{
>>> +       struct report *report;
>>> +       GSList *l;
>>> +
>>> +       /* Skip if report already exists */
>>> +       l = g_slist_find_custom(hog->reports, attr, report_attr_cmp);
>>> +       if (l)
>>> +               return l->data;
>>> +
>>> +       report = g_new0(struct report, 1);
>>> +       report->hog = hog;
>>> +
>>> +       gatt_db_attribute_get_char_data(attr, &report->handle,
>>> +                                       &report->value_handle,
>>> +                                       &report->properties,
>>> +                                       NULL, NULL);
>>> +
>>> +       hog->reports = g_slist_append(hog->reports, report);
>>> +
>>> +       read_char(hog, hog->attrib, report->value_handle, report_read_cb,
>>> +                                                               report);
>>> +
>>> +       return report;
>>> +}
>>> +
>>> +static void foreach_hog_external(struct gatt_db_attribute *attr,
>>> +                                                       void *user_data)
>>> +{
>>> +       struct bt_hog *hog = user_data;
>>> +       const bt_uuid_t *uuid;
>>> +       bt_uuid_t ext_uuid;
>>> +       uint16_t handle;
>>> +
>>> +       handle = gatt_db_attribute_get_handle(attr);
>>> +       uuid = gatt_db_attribute_get_type(attr);
>>> +
>>> +       bt_uuid16_create(&ext_uuid, GATT_EXTERNAL_REPORT_REFERENCE);
>>> +       if (!bt_uuid_cmp(&ext_uuid, uuid))
>>> +               read_char(hog, hog->attrib, handle,
>>> +                                       external_report_reference_cb, hog);
>>> +}
>>> +
>>> +static void foreach_hog_chrc(struct gatt_db_attribute *attr, void *user_data)
>>> +{
>>> +       struct bt_hog *hog = user_data;
>>> +       bt_uuid_t uuid, report_uuid, report_map_uuid, info_uuid;
>>> +       bt_uuid_t proto_mode_uuid, ctrlpt_uuid;
>>> +       uint16_t handle, value_handle;
>>> +
>>> +       gatt_db_attribute_get_char_data(attr, &handle, &value_handle, NULL,
>>> +                                       NULL, &uuid);
>>> +
>>> +       bt_uuid16_create(&report_uuid, HOG_REPORT_UUID);
>>> +       if (!bt_uuid_cmp(&report_uuid, &uuid)) {
>>> +               struct report *report = report_add(hog, attr);
>>> +               gatt_db_service_foreach_desc(attr, foreach_hog_report, report);
>>> +               return;
>>> +       }
>>> +
>>> +       bt_uuid16_create(&report_map_uuid, HOG_REPORT_MAP_UUID);
>>> +       if (!bt_uuid_cmp(&report_map_uuid, &uuid)) {
>>> +               read_char(hog, hog->attrib, value_handle, report_map_read_cb,
>>> +                                                                       hog);
>>> +               gatt_db_service_foreach_desc(attr, foreach_hog_external, hog);
>>> +               return;
>>> +       }
>>> +
>>> +       bt_uuid16_create(&info_uuid, HOG_INFO_UUID);
>>> +       if (!bt_uuid_cmp(&info_uuid, &uuid)) {
>>> +               read_char(hog, hog->attrib, value_handle, info_read_cb, hog);
>>> +               return;
>>> +       }
>>> +
>>> +       bt_uuid16_create(&proto_mode_uuid, HOG_PROTO_MODE_UUID);
>>> +       if (!bt_uuid_cmp(&proto_mode_uuid, &uuid)) {
>>> +               hog->proto_mode_handle = value_handle;
>>> +               read_char(hog, hog->attrib, value_handle, proto_mode_read_cb,
>>> +                                                                       hog);
>>> +       }
>>> +
>>> +       bt_uuid16_create(&ctrlpt_uuid, HOG_CONTROL_POINT_UUID);
>>> +       if (!bt_uuid_cmp(&ctrlpt_uuid, &uuid))
>>> +               hog->ctrlpt_handle = value_handle;
>>> +}
>>> +
>>> +static struct bt_hog *hog_new(int fd, const char *name, uint16_t vendor,
>>>                                         uint16_t product, uint16_t version,
>>> -                                       void *primary)
>>> +                                       struct gatt_db_attribute *attr)
>>>  {
>>>         struct bt_hog *hog;
>>>
>>> @@ -1245,9 +1374,58 @@ struct bt_hog *bt_hog_new(int fd, const char *name, uint16_t vendor,
>>>         hog->vendor = vendor;
>>>         hog->product = product;
>>>         hog->version = version;
>>> +       hog->attr = attr;
>>>
>>> -       if (primary)
>>> -               hog->primary = g_memdup(primary, sizeof(*hog->primary));
>>> +       return hog;
>>> +}
>>> +
>>> +static void hog_attach_instace(struct bt_hog *hog,
>>> +                               struct gatt_db_attribute *attr)
>>> +{
>>> +       struct bt_hog *instance;
>>> +
>>> +       if (!hog->attr) {
>>> +               hog->attr = attr;
>>> +               gatt_db_service_foreach_char(hog->attr, foreach_hog_chrc, hog);
>>> +               return;
>>> +       }
>>> +
>>> +       instance = hog_new(hog->uhid_fd, hog->name, hog->vendor,
>>> +                                       hog->product, hog->version, attr);
>>> +       if (!instance)
>>> +               return;
>>> +
>>> +       hog->instances = g_slist_append(hog->instances, instance);
>>> +}
>>> +
>>> +static void foreach_hog_service(struct gatt_db_attribute *attr, void *user_data)
>>> +{
>>> +       struct bt_hog *hog = user_data;
>>> +
>>> +       hog_attach_instace(hog, attr);
>>> +}
>>> +
>>> +struct bt_hog *bt_hog_new(int fd, const char *name, uint16_t vendor,
>>> +                                       uint16_t product, uint16_t version,
>>> +                                       struct gatt_db *db)
>>> +{
>>> +       struct bt_hog *hog;
>>> +
>>> +       hog = hog_new(fd, name, vendor, product, version, NULL);
>>> +       if (!hog)
>>> +               return NULL;
>>> +
>>> +       if (db) {
>>> +               bt_uuid_t uuid;
>>> +
>>> +               /* Handle the HID services */
>>> +               bt_uuid16_create(&uuid, HOG_UUID16);
>>> +               gatt_db_foreach_service(db, &uuid, foreach_hog_service, hog);
>>> +               if (!hog->attr) {
>>> +                       hog_free(hog);
>>> +                       return NULL;
>>> +               }
>>> +       }
>>>
>>>         return bt_hog_ref(hog);
>>>  }
>>> @@ -1357,10 +1535,11 @@ static void hog_attach_hog(struct bt_hog *hog, struct gatt_primary *primary)
>>>         }
>>>
>>>         instance = bt_hog_new(hog->uhid_fd, hog->name, hog->vendor,
>>> -                                       hog->product, hog->version, primary);
>>> +                                       hog->product, hog->version, NULL);
>>>         if (!instance)
>>>                 return;
>>>
>>> +       instance->primary = g_memdup(primary, sizeof(*primary));
>>>         find_included(instance, hog->attrib, primary->range.start,
>>>                         primary->range.end, find_included_cb, instance);
>>>
>>> @@ -1415,7 +1594,6 @@ static void primary_cb(uint8_t status, GSList *services, void *user_data)
>>>
>>>  bool bt_hog_attach(struct bt_hog *hog, void *gatt)
>>>  {
>>> -       struct gatt_primary *primary = hog->primary;
>>>         GSList *l;
>>>
>>>         if (hog->attrib)
>>> @@ -1423,7 +1601,7 @@ bool bt_hog_attach(struct bt_hog *hog, void *gatt)
>>>
>>>         hog->attrib = g_attrib_ref(gatt);
>>>
>>> -       if (!primary) {
>>> +       if (!hog->attr && !hog->primary) {
>>>                 discover_primary(hog, hog->attrib, NULL, primary_cb, hog);
>>>                 return true;
>>>         }
>>> @@ -1444,9 +1622,14 @@ bool bt_hog_attach(struct bt_hog *hog, void *gatt)
>>>
>>>         if (!hog->uhid_created) {
>>>                 DBG("HoG discovering characteristics");
>>> -               discover_char(hog, hog->attrib, primary->range.start,
>>> -                                               primary->range.end, NULL,
>>> -                                               char_discovered_cb, hog);
>>> +               if (hog->attr)
>>> +                       gatt_db_service_foreach_char(hog->attr,
>>> +                                                       foreach_hog_chrc, hog);
>>> +               else
>>> +                       discover_char(hog, hog->attrib,
>>> +                                       hog->primary->range.start,
>>> +                                       hog->primary->range.end, NULL,
>>> +                                       char_discovered_cb, hog);
>>>                 return true;
>>>         }
>>>
>>> @@ -1455,7 +1638,7 @@ bool bt_hog_attach(struct bt_hog *hog, void *gatt)
>>>
>>>                 r->notifyid = g_attrib_register(hog->attrib,
>>>                                         ATT_OP_HANDLE_NOTIFY,
>>> -                                       r->decl->value_handle,
>>> +                                       r->value_handle,
>>>                                         report_value_cb, r, NULL);
>>>         }
>>>
>>> @@ -1528,14 +1711,14 @@ int bt_hog_send_report(struct bt_hog *hog, void *data, size_t size, int type)
>>>         if (!report)
>>>                 return -ENOTSUP;
>>>
>>> -       DBG("hog: Write report, handle 0x%X", report->decl->value_handle);
>>> +       DBG("hog: Write report, handle 0x%X", report->value_handle);
>>>
>>> -       if (report->decl->properties & GATT_CHR_PROP_WRITE)
>>> -               write_char(hog, hog->attrib, report->decl->value_handle,
>>> +       if (report->properties & GATT_CHR_PROP_WRITE)
>>> +               write_char(hog, hog->attrib, report->value_handle,
>>>                                 data, size, output_written_cb, hog);
>>>
>>> -       if (report->decl->properties & GATT_CHR_PROP_WRITE_WITHOUT_RESP)
>>> -               gatt_write_cmd(hog->attrib, report->decl->value_handle,
>>> +       if (report->properties & GATT_CHR_PROP_WRITE_WITHOUT_RESP)
>>> +               gatt_write_cmd(hog->attrib, report->value_handle,
>>>                                                 data, size, NULL, NULL);
>>>
>>>         for (l = hog->instances; l; l = l->next) {
>>> diff --git a/profiles/input/hog-lib.h b/profiles/input/hog-lib.h
>>> index 2a9b899..415dc63 100644
>>> --- a/profiles/input/hog-lib.h
>>> +++ b/profiles/input/hog-lib.h
>>> @@ -25,11 +25,11 @@ struct bt_hog;
>>>
>>>  struct bt_hog *bt_hog_new_default(const char *name, uint16_t vendor,
>>>                                         uint16_t product, uint16_t version,
>>> -                                       void *primary);
>>> +                                       struct gatt_db *db);
>>>
>>>  struct bt_hog *bt_hog_new(int fd, const char *name, uint16_t vendor,
>>>                                         uint16_t product, uint16_t version,
>>> -                                       void *primary);
>>> +                                       struct gatt_db *db);
>>>
>>>  struct bt_hog *bt_hog_ref(struct bt_hog *hog);
>>>  void bt_hog_unref(struct bt_hog *hog);
>>> diff --git a/profiles/input/hog.c b/profiles/input/hog.c
>>> index 7d318cd..23c9c15 100644
>>> --- a/profiles/input/hog.c
>>> +++ b/profiles/input/hog.c
>>> @@ -67,32 +67,34 @@ struct hog_device {
>>>  static gboolean suspend_supported = FALSE;
>>>  static struct queue *devices = NULL;
>>>
>>> -static struct hog_device *hog_device_new(struct btd_device *device,
>>> -                                               struct gatt_primary *prim)
>>> +static void hog_device_accept(struct hog_device *dev, struct gatt_db *db)
>>>  {
>>> -       struct hog_device *dev;
>>>         char name[248];
>>>         uint16_t vendor, product, version;
>>>
>>> -       if (device_name_known(device))
>>> -               device_get_name(device, name, sizeof(name));
>>> +       if (dev->hog)
>>> +               return;
>>> +
>>> +       if (device_name_known(dev->device))
>>> +               device_get_name(dev->device, name, sizeof(name));
>>>         else
>>>                 strcpy(name, "bluez-hog-device");
>>>
>>> -       vendor = btd_device_get_vendor(device);
>>> -       product = btd_device_get_product(device);
>>> -       version = btd_device_get_version(device);
>>> +       vendor = btd_device_get_vendor(dev->device);
>>> +       product = btd_device_get_product(dev->device);
>>> +       version = btd_device_get_version(dev->device);
>>>
>>>         DBG("name=%s vendor=0x%X, product=0x%X, version=0x%X", name, vendor,
>>>                                                         product, version);
>>>
>>> -       dev = new0(struct hog_device, 1);
>>> -       dev->hog = bt_hog_new_default(name, vendor, product, version, prim);
>>> -       if (!dev->hog) {
>>> -               free(dev);
>>> -               return NULL;
>>> -       }
>>> +       dev->hog = bt_hog_new_default(name, vendor, product, version, db);
>>> +}
>>>
>>> +static struct hog_device *hog_device_new(struct btd_device *device)
>>> +{
>>> +       struct hog_device *dev;
>>> +
>>> +       dev = new0(struct hog_device, 1);
>>>         dev->device = btd_device_ref(device);
>>>
>>>         if (!devices)
>>> @@ -148,30 +150,16 @@ static int hog_probe(struct btd_service *service)
>>>  {
>>>         struct btd_device *device = btd_service_get_device(service);
>>>         const char *path = device_get_path(device);
>>> -       GSList *primaries, *l;
>>> +       struct hog_device *dev;
>>>
>>>         DBG("path %s", path);
>>>
>>> -       primaries = btd_device_get_primaries(device);
>>> -       if (primaries == NULL)
>>> +       dev = hog_device_new(device);
>>> +       if (!dev)
>>>                 return -EINVAL;
>>>
>>> -       for (l = primaries; l; l = g_slist_next(l)) {
>>> -               struct gatt_primary *prim = l->data;
>>> -               struct hog_device *dev;
>>> -
>>> -               if (strcmp(prim->uuid, HOG_UUID) != 0)
>>> -                       continue;
>>> -
>>> -               dev = hog_device_new(device, prim);
>>> -               if (!dev)
>>> -                       break;
>>> -
>>> -               btd_service_set_user_data(service, dev);
>>> -               return 0;
>>> -       }
>>> -
>>> -       return -EINVAL;
>>> +       btd_service_set_user_data(service, dev);
>>> +       return 0;
>>>  }
>>>
>>>  static void hog_remove(struct btd_service *service)
>>> @@ -189,8 +177,15 @@ static int hog_accept(struct btd_service *service)
>>>  {
>>>         struct hog_device *dev = btd_service_get_user_data(service);
>>>         struct btd_device *device = btd_service_get_device(service);
>>> +       struct gatt_db *db = btd_device_get_gatt_db(device);
>>>         GAttrib *attrib = btd_device_get_attrib(device);
>>>
>>> +       if (!dev->hog) {
>>> +               hog_device_accept(dev, db);
>>> +               if (!dev->hog)
>>> +                       return -EINVAL;
>>> +       }
>>> +
>>>         /* TODO: Replace GAttrib with bt_gatt_client */
>>>         bt_hog_attach(dev->hog, attrib);
>>>
>>> diff --git a/unit/test-hog.c b/unit/test-hog.c
>>> index 9f026e5..d117968 100644
>>> --- a/unit/test-hog.c
>>> +++ b/unit/test-hog.c
>>> @@ -32,8 +32,14 @@
>>>
>>>  #include <glib.h>
>>>
>>> +#include "lib/bluetooth.h"
>>> +#include "lib/uuid.h"
>>> +
>>>  #include "src/shared/util.h"
>>>  #include "src/shared/tester.h"
>>> +#include "src/shared/queue.h"
>>> +#include "src/shared/att.h"
>>> +#include "src/shared/gatt-db.h"
>>>
>>>  #include "attrib/gattrib.h"
>>>
>>> --
>>> 2.9.3
>>
>> Applied.
>>
>>
>> --
>> Luiz Augusto von Dentz
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Luiz Augusto von Dentz
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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