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 struct context *create_context(gconstpointer data) { struct context *context; GIOChannel *channel, *att_io; int err, sv[2], fd; char name[] = "bluez-hog"; uint16_t vendor = 0x0002; uint16_t product = 0x0001; uint16_t version = 0x0001; context = g_new0(struct context, 1); err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv); g_assert(err == 0); att_io = g_io_channel_unix_new(sv[0]); g_io_channel_set_close_on_unref(att_io, TRUE); context->attrib = g_attrib_new(att_io, 23, false); g_assert(context->attrib); g_io_channel_unref(att_io); fd = open("/dev/null", O_WRONLY | O_CLOEXEC); g_assert(fd > 0); context->hog = bt_hog_new(fd, name, vendor, product, version, NULL); g_assert(context->hog); channel = g_io_channel_unix_new(sv[1]); g_io_channel_set_close_on_unref(channel, TRUE); g_io_channel_set_encoding(channel, NULL, NULL); g_io_channel_set_buffered(channel, FALSE); context->source = g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, test_handler, context); g_assert(context->source > 0); g_io_channel_unref(channel); context->fd = sv[1]; context->data = data; return context; }
static void hog_attach_hog(struct bt_hog *hog, struct gatt_primary *primary) { struct bt_hog *instance; if (!hog->primary) { hog->primary = g_memdup(primary, sizeof(*primary)); gatt_discover_char(hog->attrib, primary->range.start, primary->range.end, NULL, char_discovered_cb, hog); return; } instance = bt_hog_new(hog->name, hog->vendor, hog->product, hog->version, primary); if (!instance) return; bt_hog_attach(instance, hog->attrib); hog->instances = g_slist_append(hog->instances, instance); }