void bt_hog_detach(struct bt_hog *hog) { GSList *l; if (!hog->attrib) return; for (l = hog->instances; l; l = l->next) { struct bt_hog *instance = l->data; bt_hog_detach(instance); } for (l = hog->reports; l; l = l->next) { struct report *r = l->data; if (r->notifyid > 0) { g_attrib_unregister(hog->attrib, r->notifyid); r->notifyid = 0; } } if (hog->scpp) bt_scpp_detach(hog->scpp); if (hog->dis) bt_dis_detach(hog->dis); if (hog->bas) bt_bas_detach(hog->bas); g_attrib_unref(hog->attrib); hog->attrib = NULL; }
static void attio_disconnected_cb(gpointer user_data) { struct hog_device *dev = user_data; DBG("HoG disconnected"); bt_hog_detach(dev->hog); }
static void hog_conn_cb(const bdaddr_t *addr, int err, void *attrib) { GSList *l; struct hid_device *dev; l = g_slist_find_custom(devices, addr, device_cmp); dev = l ? l->data : NULL; if (err < 0) { if (!dev) return; if (dev->hog && !dev->reconnect_id) { bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); bt_hog_detach(dev->hog); dev->reconnect_id = g_idle_add(hog_reconnect, dev); return; } goto fail; } if (!dev) { dev = hid_device_new(addr); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); } if (!dev->hog) { /* TODO: Get device details and primary */ dev->hog = bt_hog_new("bluez-input-device", dev->vendor, dev->product, dev->version, NULL); if (!dev->hog) { error("HoG: unable to create session"); goto fail; } } if (!bt_hog_attach(dev->hog, attrib)) { error("HoG: unable to attach"); goto fail; } DBG(""); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED); return; fail: bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); hid_device_remove(dev); }
static void hog_free(void *data) { struct bt_hog *hog = data; bt_hog_detach(hog); g_slist_free_full(hog->instances, hog_free); bt_scpp_unref(hog->scpp); bt_dis_unref(hog->dis); bt_bas_unref(hog->bas); bt_uhid_unref(hog->uhid); g_slist_free_full(hog->reports, report_free); g_free(hog->name); g_free(hog->primary); g_free(hog); }