diff --git a/profiles/input/hog_device.c b/profiles/input/hog_device.c
index a558110..d0912f5 100644
--- a/profiles/input/hog_device.c
+++ b/profiles/input/hog_device.c
#include "../src/adapter.h"
#include "../src/device.h"
-#include "hog_device.h"
-
#include "att.h"
#include "gattrib.h"
#include "attio.h"
#include "gatt.h"
+#include "hog_device.h"
+
#define HOG_INFO_UUID 0x2A4A
#define HOG_REPORT_MAP_UUID 0x2A4B
#define HOG_REPORT_UUID 0x2A4D
#define HID_INFO_SIZE 4
struct hog_device {
- char *path;
+ uint16_t id;
struct btd_device *device;
GAttrib *attrib;
guint attioid;
if (write(hogdev->uhid_fd, &ev, sizeof(ev)) < 0)
error("uHID write failed: %s", strerror(errno));
else
- DBG("Report from HoG device %s written to uHID fd %d",
- hogdev->path, hogdev->uhid_fd);
+ DBG("Report from HoG device 0x%04X written to uHID fd %d",
+ hogdev->id, hogdev->uhid_fd);
}
static void report_ccc_written_cb(guint8 status, const guint8 *pdu,
if (value == HOG_PROTO_MODE_BOOT) {
uint8_t nval = HOG_PROTO_MODE_REPORT;
- DBG("HoG device %s is operating in Boot Procotol Mode",
- hogdev->path);
+ DBG("HoG device 0x%04X is operating in Boot Procotol Mode",
+ hogdev->id);
gatt_write_char(hogdev->attrib, hogdev->proto_mode_handle, &nval,
sizeof(nval), NULL, NULL);
} else if (value == HOG_PROTO_MODE_REPORT)
- DBG("HoG device %s is operating in Report Protocol Mode",
- hogdev->path);
+ DBG("HoG device 0x%04X is operating in Report Protocol Mode",
+ hogdev->id);
}
static void char_discovered_cb(GSList *chars, guint8 status, gpointer user_data)
report = l->data;
- DBG("Sending report type %d to device %s handle 0x%X", type,
- hogdev->path, report->decl->value_handle);
+ DBG("Sending report type %d to device 0x%04X handle 0x%X", type,
+ hogdev->id, report->decl->value_handle);
if (report->decl->properties & ATT_CHAR_PROPER_WRITE)
gatt_write_char(hogdev->attrib, report->decl->value_handle,
hogdev->attrib = NULL;
}
-struct hog_device *hog_device_find(GSList *list, const char *path)
-{
- for (; list; list = list->next) {
- struct hog_device *hogdev = list->data;
-
- if (!strcmp(hogdev->path, path))
- return hogdev;
- }
-
- return NULL;
-}
-
static struct hog_device *hog_device_new(struct btd_device *device,
- const char *path)
+ uint16_t id)
{
struct hog_device *hogdev;
if (!hogdev)
return NULL;
- hogdev->path = g_strdup(path);
+ hogdev->id = id;
hogdev->device = btd_device_ref(device);
return hogdev;
}
-static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
-{
- const struct gatt_primary *prim = a;
- const char *uuid = b;
-
- return g_strcmp0(prim->uuid, uuid);
-}
-
-static struct gatt_primary *load_hog_primary(struct btd_device *device)
-{
- GSList *primaries, *l;
-
- primaries = btd_device_get_primaries(device);
-
- l = g_slist_find_custom(primaries, HOG_UUID, primary_uuid_cmp);
-
- return (l ? l->data : NULL);
-}
-
static void report_free(void *data)
{
struct report *report = data;
{
btd_device_unref(hogdev->device);
g_slist_free_full(hogdev->reports, report_free);
- g_free(hogdev->path);
g_free(hogdev->hog_primary);
g_free(hogdev);
}
struct hog_device *hog_device_register(struct btd_device *device,
- const char *path, int *perr)
+ struct gatt_primary *prim)
{
- struct gatt_primary *prim;
struct hog_device *hogdev;
GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
GIOChannel *io;
- int err;
- prim = load_hog_primary(device);
- if (!prim) {
- err = -EINVAL;
- goto failed;
- }
-
- hogdev = hog_device_new(device, path);
- if (!hogdev) {
- err = -ENOMEM;
- goto failed;
- }
+ hogdev = hog_device_new(device, prim->range.start);
+ if (!hogdev)
+ return NULL;
hogdev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC);
if (hogdev->uhid_fd < 0) {
- err = -errno;
- error("Failed to open uHID device: %s", strerror(-err));
+ error("Failed to open uHID device: %s(%d)", strerror(errno),
+ errno);
hog_device_free(hogdev);
- goto failed;
+ return NULL;
}
io = g_io_channel_unix_new(hogdev->uhid_fd);
device_set_auto_connect(device, TRUE);
return hogdev;
-
-failed:
- if (perr)
- *perr = err;
-
- return NULL;
}
int hog_device_unregister(struct hog_device *hogdev)
if (hogdev->attrib == NULL)
return -ENOTCONN;
- DBG("%s HID Control Point: %s", hogdev->path, suspend ?
+ DBG("0x%4X HID Control Point: %s", hogdev->id, suspend ?
"Suspend" : "Exit Suspend");
if (hogdev->ctrlpt_handle == 0)
diff --git a/profiles/input/hog_device.h b/profiles/input/hog_device.h
index 03f1c90..d1bfc08 100644
--- a/profiles/input/hog_device.h
+++ b/profiles/input/hog_device.h
struct hog_device;
struct hog_device *hog_device_register(struct btd_device *device,
- const char *path, int *perr);
+ struct gatt_primary *prim);
int hog_device_unregister(struct hog_device *hogdev);
-struct hog_device *hog_device_find(GSList *list, const char *path);
int hog_device_set_control_point(struct hog_device *hogdev, gboolean suspend);
diff --git a/profiles/input/hog_manager.c b/profiles/input/hog_manager.c
index 2d72444..362c38a 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
#include <errno.h>
#include <stdbool.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/uuid.h>
+
#include "log.h"
#include "../src/adapter.h"
#include "../src/device.h"
#include "hcid.h"
#include "device.h"
#include "suspend.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
#include "hog_device.h"
static gboolean suspend_supported = FALSE;
GSList *uuids)
{
const char *path = device_get_path(device);
- struct hog_device *hogdev;
- int err;
+ GSList *primaries, *l;
DBG("path %s", path);
- hogdev = hog_device_find(devices, path);
- if (hogdev)
- return -EALREADY;
+ primaries = btd_device_get_primaries(device);
+ if (primaries == NULL)
+ return -EINVAL;
- hogdev = hog_device_register(device, path, &err);
- if (hogdev == NULL)
- return err;
+ for (l = primaries; l; l = g_slist_next(l)) {
+ struct gatt_primary *prim = l->data;
+ struct hog_device *hogdev;
- devices = g_slist_append(devices, hogdev);
+ hogdev = hog_device_register(device, prim);
+ if (hogdev == NULL)
+ continue;
+
+ devices = g_slist_append(devices, hogdev);
+ }
return 0;
}
+static void remove_device(gpointer hogdev, gpointer b)
+{
+ devices = g_slist_remove(devices, hogdev);
+ hog_device_unregister(hogdev);
+}
+
static void hog_device_remove(struct btd_profile *p, struct btd_device *device)
{
const gchar *path = device_get_path(device);
- struct hog_device *hogdev;
DBG("path %s", path);
- hogdev = hog_device_find(devices, path);
- if (hogdev) {
- devices = g_slist_remove(devices, hogdev);
- hog_device_unregister(hogdev);
- }
+ g_slist_foreach(devices, remove_device, NULL);
}
static struct btd_profile hog_profile = {