/* 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);
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)
{
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;
/* 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);
}
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;
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");
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("+");
/* 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;
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) {
__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;
+}
#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;
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)
{
}
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;
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("-");
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;
}
return;
_bt_hal_unregister_hid_dbus_handler_cb();
+ _bt_hal_unregister_hid_event_handler_cb();
bt_hal_hid_cbacks = NULL;
}