diff --git a/android/hog.c b/android/hog.c
index bfb9c17..d42400d 100644
--- a/android/hog.c
+++ b/android/hog.c
hog->vendor = vendor;
hog->product = product;
hog->version = version;
- hog->primary = g_memdup(primary, sizeof(*primary));
+
+ if (primary)
+ hog->primary = g_memdup(primary, sizeof(*hog->primary));
return bt_hog_ref(hog);
}
hog_free(hog);
}
+static void find_included_cb(uint8_t status, GSList *services, void *user_data)
+{
+ struct bt_hog *hog = user_data;
+ struct gatt_included *include;
+ GSList *l;
+
+ DBG("");
+
+ if (hog->primary)
+ return;
+
+ if (status) {
+ const char *str = att_ecode2str(status);
+ DBG("Find included failed: %s", str);
+ return;
+ }
+
+ if (!services) {
+ DBG("No included service found");
+ return;
+ }
+
+ for (l = services; l; l = l->next) {
+ include = l->data;
+
+ if (strcmp(include->uuid, HOG_UUID) == 0)
+ break;
+ }
+
+ if (!l) {
+ for (l = services; l; l = l->next) {
+ include = l->data;
+
+ gatt_find_included(hog->attrib, include->range.start,
+ include->range.end, find_included_cb, hog);
+ }
+ return;
+ }
+
+ hog->primary = g_new0(struct gatt_primary, 1);
+ memcpy(hog->primary->uuid, include->uuid, sizeof(include->uuid));
+ memcpy(&hog->primary->range, &include->range, sizeof(include->range));
+
+ gatt_discover_char(hog->attrib, hog->primary->range.start,
+ hog->primary->range.end, NULL,
+ char_discovered_cb, hog);
+}
+
+static void primary_cb(uint8_t status, GSList *services, void *user_data)
+{
+ struct bt_hog *hog = user_data;
+ struct gatt_primary *primary;
+ GSList *l;
+
+ DBG("");
+
+ if (status) {
+ const char *str = att_ecode2str(status);
+ DBG("Discover primary failed: %s", str);
+ return;
+ }
+
+ if (!services) {
+ DBG("No primary service found");
+ return;
+ }
+
+ for (l = services; l; l = l->next) {
+ primary = l->data;
+
+ if (strcmp(primary->uuid, HOG_UUID) == 0)
+ break;
+ }
+
+ if (!l) {
+ for (l = services; l; l = l->next) {
+ primary = l->data;
+
+ gatt_find_included(hog->attrib, primary->range.start,
+ primary->range.end, find_included_cb,
+ hog);
+ }
+ return;
+ }
+
+ hog->primary = g_memdup(primary, sizeof(*primary));
+
+ gatt_discover_char(hog->attrib, hog->primary->range.start,
+ hog->primary->range.end, NULL,
+ char_discovered_cb, hog);
+}
+
bool bt_hog_attach(struct bt_hog *hog, void *gatt)
{
struct gatt_primary *primary = hog->primary;
hog->attrib = g_attrib_ref(gatt);
+ if (!primary) {
+ gatt_discover_primary(hog->attrib, NULL, primary_cb, hog);
+ return true;
+ }
+
if (hog->reports == NULL) {
gatt_discover_char(hog->attrib, primary->range.start,
primary->range.end, NULL,
{
GSList *l;
+ if (!hog->attrib)
+ return;
+
for (l = hog->reports; l; l = l->next) {
struct report *r = l->data;