diff options
author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2012-09-25 12:34:20 -0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-09-28 14:13:20 +0300 |
commit | fa51cea73092a3d82c1ea005a449cd85c23fb7b5 (patch) | |
tree | 4f4c31424cca60b35ec3b57987a9390cbca920e1 /profiles | |
parent | dbb37fa21fa2bdf33272b03df3d26cd15954b862 (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.c | 27 | ||||
-rw-r--r-- | profiles/input/hog_device.h | 1 | ||||
-rw-r--r-- | profiles/input/hog_manager.c | 16 |
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, |