From: Atul Rai Date: Fri, 8 Jul 2016 06:23:35 +0000 (+0900) Subject: [Adapt:BluezHAL] Handle Input device events X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b0f5e1f977fb2164d5274258740982bd5f03cf02;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git [Adapt:BluezHAL] Handle Input device events 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 --- diff --git a/bt-oal/bluez_hal/src/bt-hal-dbus-common-utils.h b/bt-oal/bluez_hal/src/bt-hal-dbus-common-utils.h index de22a50..3db7dc2 100644 --- a/bt-oal/bluez_hal/src/bt-hal-dbus-common-utils.h +++ b/bt-oal/bluez_hal/src/bt-hal-dbus-common-utils.h @@ -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 */ diff --git a/bt-oal/bluez_hal/src/bt-hal-event-receiver.c b/bt-oal/bluez_hal/src/bt-hal-event-receiver.c index f4cbd6e..3c451be 100644 --- a/bt-oal/bluez_hal/src/bt-hal-event-receiver.c +++ b/bt-oal/bluez_hal/src/bt-hal-event-receiver.c @@ -49,21 +49,23 @@ /* 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; +} diff --git a/bt-oal/bluez_hal/src/bt-hal-event-receiver.h b/bt-oal/bluez_hal/src/bt-hal-event-receiver.h index f89a58c..dea34a2 100644 --- a/bt-oal/bluez_hal/src/bt-hal-event-receiver.h +++ b/bt-oal/bluez_hal/src/bt-hal-event-receiver.h @@ -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); diff --git a/bt-oal/bluez_hal/src/bt-hal-hidhost.c b/bt-oal/bluez_hal/src/bt-hal-hidhost.c index e249a7d..3bba559 100644 --- a/bt-oal/bluez_hal/src/bt-hal-hidhost.c +++ b/bt-oal/bluez_hal/src/bt-hal-hidhost.c @@ -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; } diff --git a/bt-oal/bluez_hal/src/bt-hal-internal.h b/bt-oal/bluez_hal/src/bt-hal-internal.h index cf3a391..476427a 100644 --- a/bt-oal/bluez_hal/src/bt-hal-internal.h +++ b/bt-oal/bluez_hal/src/bt-hal-internal.h @@ -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 }