[Adapt:BluezHAL] Handle Input device events 89/79589/2
authorAtul Rai <a.rai@samsung.com>
Fri, 8 Jul 2016 06:23:35 +0000 (15:23 +0900)
committerPyun DoHyun <dh79.pyun@samsung.com>
Wed, 13 Jul 2016 02:50:45 +0000 (19:50 -0700)
This patch adds implementation to handle input device events
from bluez. In this patch we parse the incomming events and
invoke corresponding HAL event handler.

Change-Id: I8957bd457835959fd0e8b8882928b20e83fd4451
Signed-off-by: Atul Rai <a.rai@samsung.com>
bt-oal/bluez_hal/src/bt-hal-dbus-common-utils.h
bt-oal/bluez_hal/src/bt-hal-event-receiver.c
bt-oal/bluez_hal/src/bt-hal-event-receiver.h
bt-oal/bluez_hal/src/bt-hal-hidhost.c
bt-oal/bluez_hal/src/bt-hal-internal.h

index de22a50..3db7dc2 100644 (file)
@@ -110,8 +110,6 @@ extern "C" {
 #define BT_HAL_NAME_OWNER_CHANGED "NameOwnerChanged"
 #define BT_HAL_PROPERTIES_CHANGED "PropertiesChanged"
 
-#define HID_UUID                "00001124-0000-1000-8000-00805f9b34fb"
-
 /**
  * This is Bluetooth error code
  */
index f4cbd6e..3c451be 100644 (file)
 /* Global variables and structures */
 static GDBusConnection *manager_conn;
 static handle_stack_msg event_cb = NULL;
+static handle_stack_msg hid_event_cb = NULL;
 static guint event_id;
 
 /* Forward declarations */
-int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
+static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
 static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe);
 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn, int subscribe);
+static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe);
+
 static int __bt_hal_parse_event(GVariant *msg);
 static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current);
+
+static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path);
 static void __bt_hal_adapter_property_changed_event(GVariant *msg);
-void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path);
 static  void __bt_hal_manager_event_filter(GDBusConnection *connection, const gchar *sender_name,
                        const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
                        GVariant *parameters, gpointer user_data);
-static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe);
-int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
 static int __bt_hal_initialize_manager_receiver(void);
 static gboolean __bt_hal_parse_interface(GVariant *msg);
 static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters);
@@ -74,6 +76,7 @@ static void __bt_hal_dbus_device_found_properties(const char *device_path);
 static void __bt_hal_device_properties_lookup(GVariant *result, char *address);
 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member,const char *path);
 static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address);
+static void __bt_hal_handle_input_event(GVariant *msg, const char *path);
 
 static gboolean __bt_hal_discovery_finished_cb(gpointer user_data)
 {
@@ -504,7 +507,7 @@ static gboolean __bt_hal_parse_device_properties(GVariant *item)
        return TRUE;
 }
 
-void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
+static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
 {
        char *interface_name = NULL;
        GVariant *val = NULL;
@@ -534,6 +537,7 @@ void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_pa
                /* TODO: Handle event */
        } else if (strcasecmp(interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
                DBG("Event: Property Changed: Interface: BT_HAL_INPUT_INTERFACE");
+               __bt_hal_handle_input_event(val, object_path);
        }
        g_variant_unref(val);
 }
@@ -551,6 +555,55 @@ static void __bt_hal_handle_device_event(GVariant *value, GVariant *parameters)
        DBG("-");
 }
 
+static void __bt_hal_send_hid_connection_state_event(
+               gboolean connected, char *address)
+{
+       struct hal_ev_hidhost_conn_state ev;
+
+       ev.state = (connected == TRUE) ?
+               HAL_HIDHOST_STATE_CONNECTED :
+               HAL_HIDHOST_STATE_DISCONNECTED;
+
+       _bt_convert_addr_string_to_type(ev.bdaddr, address);
+
+       if (!hid_event_cb)
+               ERR("HID event handler not registered");
+       else
+               hid_event_cb(HAL_EV_HIDHOST_CONN_STATE, &ev, sizeof(ev));
+}
+
+static void __bt_hal_handle_input_event(GVariant *msg, const char *path)
+{
+       gboolean property_flag = FALSE;
+       GVariantIter value_iter;
+       char *property = NULL;
+       GVariant *child = NULL, *val = NULL;
+
+       DBG("+");
+       g_variant_iter_init (&value_iter, msg);
+       while ((child = g_variant_iter_next_value (&value_iter))) {
+               g_variant_get(child, "{sv}", &property, &val);
+
+               if (property == NULL)
+                       return;
+
+               if (strcasecmp(property, "Connected") == 0) {
+                       char *address;
+
+                       g_variant_get(val, "b", &property_flag);
+                       address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
+                       _bt_convert_device_path_to_address(path, address);
+                       __bt_hal_send_hid_connection_state_event(property_flag, address);
+                       g_free(address);
+               }
+               g_free(property);
+               g_variant_unref(val);
+               g_variant_unref(child);
+       }
+
+       DBG("-");
+}
+
 static gboolean __bt_hal_parse_interface(GVariant *msg)
 {
        char *path = NULL;
@@ -661,6 +714,7 @@ static  void __bt_hal_manager_event_filter(GDBusConnection *connection,
                DBG("Manager Event: Interface Name: BT_HAL_ADAPTER_INTERFACE");
        } else if (g_strcmp0(interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
                DBG("Manager Event: Interface Name: BT_HAL_INPUT_INTERFACE");
+               __bt_hal_handle_input_event(parameters, object_path);
        } else if (g_strcmp0(interface_name, BT_HAL_NETWORK_SERVER_INTERFACE) == 0) {
                /* TODO: Handle Network Server events from stack */
                DBG("Manager Event: Interface Name: BT_HAL_NETWORK_SERVER_INTERFACE");
@@ -790,7 +844,37 @@ static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn,
        return 0;
 }
 
-int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
+static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int subscribe)
+{
+       static int subs_input_id = -1;
+
+       DBG("+");
+
+       if (conn == NULL)
+               return -1;
+
+       if (subscribe) {
+               if (subs_input_id == -1) {
+                       subs_input_id = g_dbus_connection_signal_subscribe(conn,
+                                       NULL, BT_HAL_INPUT_INTERFACE,
+                                       NULL, NULL, NULL, 0,
+                                       __bt_hal_manager_event_filter,
+                                       NULL, NULL);
+               }
+       } else {
+               if (subs_input_id != -1) {
+                       g_dbus_connection_signal_unsubscribe(conn,
+                                       subs_input_id);
+                       subs_input_id = -1;
+               }
+       }
+
+       DBG("-");
+
+       return 0;
+}
+
+static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
 {
        DBG("+");
 
@@ -799,15 +883,18 @@ int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
 
        /* TODO: Add more events in subsequent patches */
        switch (event_type) {
-               case BT_HAL_MANAGER_EVENT:
-                       __bt_hal_register_manager_subscribe_signal(g_conn, TRUE);
-                       break;
-               case BT_HAL_DEVICE_EVENT:
-                       __bt_hal_register_device_subscribe_signal(g_conn, TRUE);
-                       break;
-               default:
-                       INFO_C("Register Event: event_type [%d]", event_type);
-                       return BT_HAL_ERROR_NOT_SUPPORT;
+       case BT_HAL_MANAGER_EVENT:
+               __bt_hal_register_manager_subscribe_signal(g_conn, TRUE);
+               break;
+       case BT_HAL_DEVICE_EVENT:
+               __bt_hal_register_device_subscribe_signal(g_conn, TRUE);
+               break;
+       case BT_HAL_HID_EVENT:
+               __bt_hal_register_input_subscribe_signal(g_conn, TRUE);
+               break;
+       default:
+               INFO_C("Register Event: event_type [%d]", event_type);
+               return BT_HAL_ERROR_NOT_SUPPORT;
        }
 
        return BT_HAL_ERROR_NONE;
@@ -835,6 +922,9 @@ static int __bt_hal_initialize_manager_receiver(void)
        if (__bt_hal_register_service_event(manager_conn,
                                BT_HAL_DEVICE_EVENT) != BT_HAL_ERROR_NONE)
                goto fail;
+       if (__bt_hal_register_service_event(manager_conn,
+                               BT_HAL_HID_EVENT) != BT_HAL_ERROR_NONE)
+               goto fail;
        return BT_HAL_ERROR_NONE;
 fail:
        if (manager_conn) {
@@ -1213,9 +1303,39 @@ static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *me
                __bt_hal_send_device_acl_connection_state_event(FALSE, address);
                g_free(address);
        } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
-               /* TODO */
+               int state = 0;
+               char *profile_uuid = NULL;
+
+               g_variant_get(msg, "(si)", &profile_uuid, &state);
+               address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
+               _bt_convert_device_path_to_address(path, address);
+
+               DBG("Address: %s", address);
+               DBG("Profile UUID: %s", profile_uuid);
+               DBG("State: %d", state);
+               if (strncmp(profile_uuid, HID_UUID, strlen(HID_UUID)) == 0) {
+                       if (state == BT_HAL_PROFILE_STATE_CONNECTED)
+                               __bt_hal_send_hid_connection_state_event(TRUE, address);
+                       else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED)
+                               __bt_hal_send_hid_connection_state_event(FALSE, address);
+                       else
+                               DBG("Profile state: %d", state);
+
+               }
+               g_free(address);
+               g_free(profile_uuid);
        } else if (strcasecmp(member, "AdvReport") == 0) {
                /* TODO */
                DBG("Member: [%s]", member);
        }
 }
+
+void _bt_hal_register_hid_event_handler_cb(handle_stack_msg cb)
+{
+               hid_event_cb = cb;
+}
+
+void _bt_hal_unregister_hid_event_handler_cb()
+{
+               hid_event_cb = NULL;
+}
index f89a58c..dea34a2 100644 (file)
@@ -40,6 +40,10 @@ typedef void (*handle_stack_msg) (int message, void *buf, uint16_t len);
 
 int _bt_hal_initialize_event_receiver(handle_stack_msg cb);
 
+void _bt_hal_register_hid_event_handler_cb(handle_stack_msg cb);
+
+void _bt_hal_unregister_hid_event_handler_cb();
+
 handle_stack_msg _bt_hal_get_stack_message_handler(void);
 
 int __bt_insert_hal_properties(void *buf, uint8_t type, uint16_t len, const void *val);
index e249a7d..3bba559 100644 (file)
@@ -31,6 +31,7 @@
 #include "bt-hal-utils.h"
 
 #include "bt-hal-hid-dbus-handler.h"
+#include "bt-hal-event-receiver.h"
 
 static const bthh_callbacks_t *bt_hal_hid_cbacks;
 
@@ -45,9 +46,76 @@ static void __bt_hal_handle_conn_state(void *buf, uint16_t len)
 
        if (bt_hal_hid_cbacks->connection_state_cb)
                bt_hal_hid_cbacks->connection_state_cb((bt_bdaddr_t *) ev->bdaddr,
-                                                               ev->state);
+                               ev->state);
 }
 
+static void __bt_hal_handle_hidhost_info(void *buf, uint16_t len)
+{
+       struct hal_ev_hidhost_info *ev = buf;
+       bthh_hid_info_t info;
+
+       info.attr_mask = ev->attr;
+       info.sub_class = ev->subclass;
+       info.app_id = ev->app_id;
+       info.vendor_id = ev->vendor;
+       info.product_id = ev->product;
+       info.version = ev->version;
+       info.ctry_code = ev->country;
+       info.dl_len = ev->descr_len;
+       memcpy(info.dsc_list, ev->descr, info.dl_len);
+
+       if (bt_hal_hid_cbacks->hid_info_cb)
+               bt_hal_hid_cbacks->hid_info_cb((bt_bdaddr_t *) ev->bdaddr, info);
+}
+
+static void __bt_hal_handle_proto_mode(void *buf, uint16_t len)
+{
+       struct hal_ev_hidhost_proto_mode *ev = buf;
+
+       if (bt_hal_hid_cbacks->protocol_mode_cb)
+               bt_hal_hid_cbacks->protocol_mode_cb((bt_bdaddr_t *) ev->bdaddr,
+                               ev->status, ev->mode);
+}
+
+static void __bt_hal_handle_idle_time(void *buf, uint16_t len)
+{
+       struct hal_ev_hidhost_idle_time *ev = buf;
+
+       if (bt_hal_hid_cbacks->idle_time_cb)
+               bt_hal_hid_cbacks->idle_time_cb((bt_bdaddr_t *) ev->bdaddr, ev->status,
+                               ev->idle_rate);
+}
+
+static void __bt_hal_handle_get_report(void *buf, uint16_t len)
+{
+       struct hal_ev_hidhost_get_report *ev = buf;
+
+       if (len != sizeof(*ev) + ev->len) {
+               ERR("invalid get report event");
+               return;
+       }
+
+       if (bt_hal_hid_cbacks->get_report_cb)
+               bt_hal_hid_cbacks->get_report_cb((bt_bdaddr_t *) ev->bdaddr, ev->status,
+                               ev->data, ev->len);
+}
+
+static void __bt_hal_handle_virtual_unplug(void *buf, uint16_t len)
+{
+       struct hal_ev_hidhost_virtual_unplug *ev = buf;
+
+       if (bt_hal_hid_cbacks->virtual_unplug_cb)
+               bt_hal_hid_cbacks->virtual_unplug_cb((bt_bdaddr_t *) ev->bdaddr,
+                               ev->status);
+}
+
+static void __bt_hal_handle_handshake(void *buf, uint16_t len)
+{
+       struct hal_ev_hidhost_handshake *ev = buf;
+
+       if (bt_hal_hid_cbacks->handshake_cb)
+               bt_hal_hid_cbacks->handshake_cb((bt_bdaddr_t *) ev->bdaddr, ev->status);
+}
 
 static bt_status_t hidhost_connect(bt_bdaddr_t *bd_addr)
 {
@@ -74,31 +142,31 @@ static bt_status_t hidhost_set_info(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_in
 }
 
 static bt_status_t get_protocol(bt_bdaddr_t *bd_addr,
-                                       bthh_protocol_mode_t protocol_mode)
+               bthh_protocol_mode_t protocol_mode)
 {
        DBG("");
        return BT_STATUS_UNSUPPORTED;
 }
 
 static bt_status_t set_protocol(bt_bdaddr_t *bd_addr,
-                                       bthh_protocol_mode_t protocol_mode)
+               bthh_protocol_mode_t protocol_mode)
 {
        DBG("");
        return BT_STATUS_UNSUPPORTED;
 }
 
 static bt_status_t get_report(bt_bdaddr_t *bd_addr,
-                                               bthh_report_type_t report_type,
-                                               uint8_t report_id,
-                                               int buffer_size)
+               bthh_report_type_t report_type,
+               uint8_t report_id,
+               int buffer_size)
 {
        DBG("");
        return BT_STATUS_UNSUPPORTED;
 }
 
 static bt_status_t set_report(bt_bdaddr_t *bd_addr,
-                                               bthh_report_type_t report_type,
-                                               char *report)
+               bthh_report_type_t report_type,
+               char *report)
 {
        DBG("");
        return BT_STATUS_UNSUPPORTED;
@@ -118,13 +186,37 @@ static void __bt_hal_handle_hid_events(int message, void *buf, uint16_t len)
                return;
 
        switch(message) {
-               case HAL_EV_HIDHOST_CONN_STATE:
-                       DBG("Event: HAL_EV_HIDHOST_CONN_STATE");
-                       __bt_hal_handle_conn_state(buf, len);
-                       break;
-               default:
-                       DBG("Event Currently not handled!!");
-                       break;
+       case HAL_EV_HIDHOST_CONN_STATE:
+               DBG("Event: HAL_EV_HIDHOST_CONN_STATE");
+               __bt_hal_handle_conn_state(buf, len);
+               break;
+       case HAL_EV_HIDHOST_INFO:
+               DBG("Event: HAL_EV_HIDHOST_INFO");
+               __bt_hal_handle_hidhost_info(buf, len);
+               break;
+       case HAL_EV_HIDHOST_PROTO_MODE:
+               DBG("Event: HAL_EV_HIDHOST_PROTO_MODE");
+               __bt_hal_handle_proto_mode(buf, len);
+               break;
+       case HAL_EV_HIDHOST_IDLE_TIME:
+               DBG("Event: HAL_EV_HIDHOST_IDLE_TIME");
+               __bt_hal_handle_idle_time(buf, len);
+               break;
+       case HAL_EV_HIDHOST_GET_REPORT:
+               DBG("Event: HAL_EV_HIDHOST_GET_REPORT");
+               __bt_hal_handle_get_report(buf, len);
+               break;
+       case HAL_EV_HIDHOST_VIRTUAL_UNPLUG:
+               DBG("Event: HAL_EV_HIDHOST_VIRTUAL_UNPLUG");
+               __bt_hal_handle_virtual_unplug(buf, len);
+               break;
+       case HAL_EV_HIDHOST_HANDSHAKE:
+               DBG("Event: HAL_EV_HIDHOST_HANDSHAKE");
+               __bt_hal_handle_handshake(buf, len);
+               break;
+       default:
+               DBG("Event Currently not handled!!");
+               break;
        }
 
        DBG("-");
@@ -140,6 +232,7 @@ static bt_status_t init(bthh_callbacks_t *callbacks)
        bt_hal_hid_cbacks = callbacks;
        DBG("Register HID events callback function");
        _bt_hal_register_hid_dbus_handler_cb(__bt_hal_handle_hid_events);
+       _bt_hal_register_hid_event_handler_cb(__bt_hal_handle_hid_events);
 
        return BT_STATUS_SUCCESS;
 }
@@ -152,6 +245,7 @@ static void cleanup(void)
                return;
 
        _bt_hal_unregister_hid_dbus_handler_cb();
+       _bt_hal_unregister_hid_event_handler_cb();
 
        bt_hal_hid_cbacks = NULL;
 }
index cf3a391..476427a 100644 (file)
@@ -53,6 +53,18 @@ typedef enum {
         /* Will be added */
 } bt_hal_event_type_t;
 
+/* Profile states matched to btd_service_state_t of bluez service.h */
+typedef enum {
+       BT_HAL_PROFILE_STATE_UNAVAILABLE,
+       BT_HAL_PROFILE_STATE_DISCONNECTED,
+       BT_HAL_PROFILE_STATE_CONNECTING,
+       BT_HAL_PROFILE_STATE_CONNECTED,
+       BT_HAL_PROFILE_STATE_DISCONNECTING,
+} bt_hal_profile_state_t;
+
+/* UUIDs */
+#define HID_UUID                "00001124-0000-1000-8000-00805f9b34fb"
+
 /* TODO  More declarations to be added in subsequent patches */
 #ifdef __cplusplus
 }