summaryrefslogtreecommitdiff
path: root/profiles
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2012-09-25 12:34:20 -0300
committerJohan Hedberg <johan.hedberg@intel.com>2012-09-28 14:13:20 +0300
commitfa51cea73092a3d82c1ea005a449cd85c23fb7b5 (patch)
tree4f4c31424cca60b35ec3b57987a9390cbca920e1 /profiles
parentdbb37fa21fa2bdf33272b03df3d26cd15954b862 (diff)
hog: Add writting Control Point
This patch adds GATT write without response operation when suspending or resuming.
Diffstat (limited to 'profiles')
-rw-r--r--profiles/input/hog_device.c27
-rw-r--r--profiles/input/hog_device.h1
-rw-r--r--profiles/input/hog_manager.c16
3 files changed, 43 insertions, 1 deletions
diff --git a/profiles/input/hog_device.c b/profiles/input/hog_device.c
index 4b43d671..a5581106 100644
--- a/profiles/input/hog_device.c
+++ b/profiles/input/hog_device.c
@@ -57,6 +57,7 @@
#define HOG_REPORT_MAP_UUID 0x2A4B
#define HOG_REPORT_UUID 0x2A4D
#define HOG_PROTO_MODE_UUID 0x2A4E
+#define HOG_CONTROL_POINT_UUID 0x2A4C
#define HOG_REPORT_TYPE_INPUT 1
#define HOG_REPORT_TYPE_OUTPUT 2
@@ -84,6 +85,7 @@ struct hog_device {
uint16_t bcdhid;
uint8_t bcountrycode;
uint16_t proto_mode_handle;
+ uint16_t ctrlpt_handle;
uint8_t flags;
};
@@ -439,7 +441,8 @@ static void proto_mode_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
static void char_discovered_cb(GSList *chars, guint8 status, gpointer user_data)
{
struct hog_device *hogdev = user_data;
- bt_uuid_t report_uuid, report_map_uuid, info_uuid, proto_mode_uuid;
+ bt_uuid_t report_uuid, report_map_uuid, info_uuid, proto_mode_uuid,
+ ctrlpt_uuid;
struct report *report;
GSList *l;
uint16_t info_handle = 0, proto_mode_handle = 0;
@@ -454,6 +457,7 @@ static void char_discovered_cb(GSList *chars, guint8 status, gpointer user_data)
bt_uuid16_create(&report_map_uuid, HOG_REPORT_MAP_UUID);
bt_uuid16_create(&info_uuid, HOG_INFO_UUID);
bt_uuid16_create(&proto_mode_uuid, HOG_PROTO_MODE_UUID);
+ bt_uuid16_create(&ctrlpt_uuid, HOG_CONTROL_POINT_UUID);
for (l = chars; l; l = g_slist_next(l)) {
struct gatt_char *chr, *next;
@@ -482,6 +486,8 @@ static void char_discovered_cb(GSList *chars, guint8 status, gpointer user_data)
info_handle = chr->value_handle;
else if (bt_uuid_cmp(&uuid, &proto_mode_uuid) == 0)
proto_mode_handle = chr->value_handle;
+ else if (bt_uuid_cmp(&uuid, &ctrlpt_uuid) == 0)
+ hogdev->ctrlpt_handle = chr->value_handle;
}
if (proto_mode_handle) {
@@ -765,3 +771,22 @@ int hog_device_unregister(struct hog_device *hogdev)
return 0;
}
+
+int hog_device_set_control_point(struct hog_device *hogdev, gboolean suspend)
+{
+ uint8_t value = suspend ? 0x00 : 0x01;
+
+ if (hogdev->attrib == NULL)
+ return -ENOTCONN;
+
+ DBG("%s HID Control Point: %s", hogdev->path, suspend ?
+ "Suspend" : "Exit Suspend");
+
+ if (hogdev->ctrlpt_handle == 0)
+ return -ENOTSUP;
+
+ gatt_write_char(hogdev->attrib, hogdev->ctrlpt_handle, &value,
+ sizeof(value), NULL, NULL);
+
+ return 0;
+}
diff --git a/profiles/input/hog_device.h b/profiles/input/hog_device.h
index efb7b4f9..03f1c905 100644
--- a/profiles/input/hog_device.h
+++ b/profiles/input/hog_device.h
@@ -31,3 +31,4 @@ struct hog_device *hog_device_register(struct btd_device *device,
const char *path, int *perr);
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 3888c2b8..2d724448 100644
--- a/profiles/input/hog_manager.c
+++ b/profiles/input/hog_manager.c
@@ -43,14 +43,30 @@
static gboolean suspend_supported = FALSE;
static GSList *devices = NULL;
+static void set_suspend(gpointer data, gpointer user_data)
+{
+ struct hog_device *hogdev = data;
+ gboolean suspend = GPOINTER_TO_INT(user_data);
+
+ hog_device_set_control_point(hogdev, suspend);
+}
+
static void suspend_callback(void)
{
+ gboolean suspend = TRUE;
+
DBG("Suspending ...");
+
+ g_slist_foreach(devices, set_suspend, GINT_TO_POINTER(suspend));
}
static void resume_callback(void)
{
+ gboolean suspend = FALSE;
+
DBG("Resuming ...");
+
+ g_slist_foreach(devices, set_suspend, GINT_TO_POINTER(suspend));
}
static int hog_device_probe(struct btd_profile *p, struct btd_device *device,