X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-api%2Fbt-hid-device.c;h=e0e8a53623bad77a8343ce2e20255e10289099eb;hb=684f5da84d22874810deb97ea6d72b81f63fbb70;hp=23942fabda0245e45a80855c2460d257c26f7e0c;hpb=5a7a8022285f9381eb8c7c7fba3a9977651c0e1b;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-api/bt-hid-device.c b/bt-api/bt-hid-device.c index 23942fa..e0e8a53 100644 --- a/bt-api/bt-hid-device.c +++ b/bt-api/bt-hid-device.c @@ -57,13 +57,9 @@ #define BT_HID_HSHK_ERR_UNKNOWN 0x0E #define BT_HID_HSHK_ERR_FATAL 0x0F -typedef struct { - guint object_id; - gchar *path; - int id; - char *uuid; - GSList *device_list; -} hid_info_t; +#define BT_HID_SERVICE_NAME "org.bluez.hid_agent" +#define BT_HID_AGENT_OBJECT_PATH "/org/bluez/hid_agent" +#define BT_HID_SERVICE_INTERFACE "org.tizen.HidApp" typedef struct { int ctrl_fd; @@ -81,7 +77,7 @@ struct reports { guint8 rep_data[20]; } __attribute__((__packed__)); -static hid_info_t *hid_info = NULL; +static GSList *device_list; /* Variable for privilege, only for write API, before we should reduce time to bt-service dbus calling @@ -93,76 +89,38 @@ static int privilege_token_send_mouse = 0; static int privilege_token_send_key = 0; static int privilege_token_reply = 0; -static gboolean __hid_disconnect(hid_connected_device_info_t *info); - -int _bt_hid_device_get_fd(const char *address, int *ctrl, int *intr) +static GVariant* __bt_hid_agent_dbus_send(const char *path, + const char *interface, const char *method, + GError **err, GVariant *parameters) { + GVariant *reply = NULL; + GDBusProxy *proxy = NULL; + GDBusConnection *conn = NULL; - int ret = BLUETOOTH_ERROR_NONE; - char *adapter_path; - GVariant *result = NULL; - GError *err = NULL; - GDBusConnection *conn; - GDBusProxy *server_proxy; - int index1 = 0; - int index2 = 0; - GUnixFDList *out_fd_list = NULL; - conn = _bt_gdbus_get_system_gconn(); - retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); - - adapter_path = _bt_get_device_object_path((char *)address); - retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL); - BT_INFO_C("Device : %s", adapter_path); - server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, - NULL, BT_BLUEZ_NAME, - adapter_path, "org.bluez.Input1", NULL, NULL); - g_free(adapter_path); + conn = _bt_get_system_private_conn(); + retv_if(conn == NULL, NULL); - if (server_proxy == NULL) { - BT_ERR("Failed to get the network server proxy\n"); - return BLUETOOTH_ERROR_INTERNAL; + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, BT_HID_SERVICE_NAME, path, interface, NULL, err); + if (proxy == NULL) { + BT_ERR("Unable to allocate new proxy"); + return NULL; } - result = g_dbus_proxy_call_with_unix_fd_list_sync(server_proxy, "GetFD", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &out_fd_list, - NULL, - &err); - if (result == NULL) { - if (err != NULL) { - g_dbus_error_strip_remote_error(err); - BT_ERR("INPUT server register Error: %s\n", err->message); - if (g_strcmp0(err->message, "Already Exists") == 0) - ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED; - else - ret = BLUETOOTH_ERROR_INTERNAL; - - g_error_free(err); - } - } else { - g_variant_get(result, "(hh)", &index1, &index2); - int fd1 = g_unix_fd_list_get(out_fd_list, index1, NULL); - int fd2 = g_unix_fd_list_get(out_fd_list, index2, NULL); + reply = g_dbus_proxy_call_sync(proxy, method, parameters, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, err); - *ctrl = fd1; - *intr = fd2; - g_object_unref(out_fd_list); - g_variant_unref(result); - } - g_object_unref(server_proxy); - return ret; + g_object_unref(proxy); + return reply; } static hid_connected_device_info_t *__find_hid_info_with_address(const char *remote_addr) { GSList *l; - for (l = hid_info->device_list; l != NULL; l = l->next) { + for (l = device_list; l != NULL; l = l->next) { hid_connected_device_info_t *info = l->data; - if (g_strcmp0((const char *)info->address, (const char *)remote_addr) == 0) + if (strcasecmp((const char *)info->address, (const char *)remote_addr) == 0) return info; } return NULL; @@ -171,25 +129,21 @@ static hid_connected_device_info_t *__find_hid_info_with_address(const char *rem static void __hid_connected_cb(hid_connected_device_info_t *info, int result) { - bluetooth_hid_request_t conn_info; + bluetooth_device_address_t bd_addr; bt_event_info_t *event_info = NULL; event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT); if (event_info == NULL) return; - memset(&conn_info, 0x00, sizeof(bluetooth_hid_request_t)); - if (info->intr_fd != -1 && info->ctrl_fd == -1) - conn_info.socket_fd = info->intr_fd; - else - conn_info.socket_fd = info->ctrl_fd; - _bt_convert_addr_string_to_type(conn_info.device_addr.addr, info->address); + memset(&bd_addr, 0x00, sizeof(bluetooth_device_address_t)); + _bt_convert_addr_string_to_type(bd_addr.addr, info->address); if (result == BLUETOOTH_ERROR_NONE) BT_INFO_C("Connected [HID Device]"); _bt_common_event_cb(BLUETOOTH_HID_DEVICE_CONNECTED, - result, &conn_info, + result, &bd_addr, event_info->cb, event_info->user_data); } @@ -210,11 +164,6 @@ static void __hid_connect_response_cb(GDBusProxy *proxy, GAsyncResult *res, g_dbus_error_strip_remote_error(error); BT_ERR("Error : %s \n", error->message); - if (g_strcmp0(error->message, "In Progress") == 0) - result = BLUETOOTH_ERROR_DEVICE_BUSY; - else - result = BLUETOOTH_ERROR_INTERNAL; - info.ctrl_fd = -1; info.intr_fd = -1; @@ -223,10 +172,27 @@ static void __hid_connect_response_cb(GDBusProxy *proxy, GAsyncResult *res, path = g_dbus_proxy_get_object_path(proxy); _bt_convert_device_path_to_address(path, info.address); - __hid_connected_cb(&info, result); + if (g_strcmp0(error->message, "Already Connected") == 0) { + bluetooth_device_address_t dev_address = { {0} }; + int ctrl = -1, intr = -1; - g_free(info.address); + _bt_convert_addr_string_to_type(dev_address.addr, + info.address); + _bt_hid_device_get_fd(info.address, &ctrl, &intr); + if (ctrl != -1 && intr != -1) + _bt_hid_new_connection(&dev_address, ctrl, intr); + else + BT_ERR("fd is invalid.(ctrl=%d, intr=%d)", ctrl, intr); + } else { + if (g_strcmp0(error->message, "In Progress") == 0) + result = BLUETOOTH_ERROR_IN_PROGRESS; + else + result = BLUETOOTH_ERROR_INTERNAL; + + __hid_connected_cb(&info, result); + } + g_free(info.address); g_error_free(error); } else { g_variant_unref(ret); @@ -240,12 +206,11 @@ static void __hid_connect_response_cb(GDBusProxy *proxy, GAsyncResult *res, static gboolean __hid_disconnect(hid_connected_device_info_t *info) { - bluetooth_hid_request_t disconn_info; - int fd = info->ctrl_fd; + bluetooth_device_address_t bd_addr; bt_event_info_t *event_info; BT_INFO_C("Disconnected [HID Device]"); - hid_info->device_list = g_slist_remove(hid_info->device_list, info); + device_list = g_slist_remove(device_list, info); if (info->ctrl_data_id > 0) { g_source_remove(info->ctrl_data_id); info->ctrl_data_id = 0; @@ -273,44 +238,18 @@ static gboolean __hid_disconnect(hid_connected_device_info_t *info) } info->disconnect_idle_id = 0; event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT); - if (event_info == NULL) - return FALSE; - - memset(&disconn_info, 0x00, sizeof(bluetooth_hid_request_t)); - disconn_info.socket_fd = fd; - _bt_convert_addr_string_to_type(disconn_info.device_addr.addr , info->address); - _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DISCONNECTED, - BLUETOOTH_ERROR_NONE, &disconn_info, - event_info->cb, event_info->user_data); - if (info->address) - g_free(info->address); - g_free(info); - info = NULL; - BT_DBG("-"); - return FALSE; -} - -void __free_hid_info(hid_info_t *info) -{ - BT_DBG(""); - - _bt_unregister_gdbus(info->object_id); - - while (info->device_list) { - hid_connected_device_info_t *dev_info = NULL; - dev_info = (hid_connected_device_info_t *)info->device_list->data; - - if (dev_info->disconnect_idle_id > 0) { - BT_INFO("Disconnect idle still not process remove source"); - g_source_remove(dev_info->disconnect_idle_id); - dev_info->disconnect_idle_id = 0; - } - __hid_disconnect(dev_info); + if (event_info != NULL) { + memset(&bd_addr, 0x00, sizeof(bluetooth_device_address_t)); + _bt_convert_addr_string_to_type(bd_addr.addr , info->address); + _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DISCONNECTED, + BLUETOOTH_ERROR_NONE, &bd_addr, + event_info->cb, event_info->user_data); } - g_free(info->path); - g_free(info->uuid); + g_free(info->address); g_free(info); + + return FALSE; } static gboolean __is_error_by_disconnect(GError *err) @@ -347,7 +286,7 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, &len, &err); if (status == G_IO_STATUS_NORMAL) { BT_INFO("Parsing Data"); - bluetooth_hid_received_data_t data = {0}; + bluetooth_hid_received_data_t recv_data = {0}; header = buffer[0]; type = header & BT_HID_HEADER_TRANS_MASK; param = header & BT_HID_HEADER_PARAM_MASK; @@ -358,121 +297,111 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, if (event_info == NULL) return FALSE; - data.address = g_strdup(info->address); + recv_data.address = g_strdup(info->address); switch (type) { case BT_HID_TRANS_HANDSHAKE: BT_INFO("TRANS HANDSHAKE"); - data.type = HTYPE_TRANS_HANDSHAKE; - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.type = HTYPE_TRANS_HANDSHAKE; + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); break; case BT_HID_TRANS_HID_CONTROL: BT_INFO("HID CONTROL"); - data.type = HTYPE_TRANS_HID_CONTROL; - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.type = HTYPE_TRANS_HID_CONTROL; + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); break; case BT_HID_TRANS_DATA: BT_INFO("TRANS DATA"); - data.type = HTYPE_TRANS_DATA; + recv_data.type = HTYPE_TRANS_DATA; if (param & BT_HID_DATA_RTYPE_INPUT) { BT_INFO("Input Report"); - data.param = PTYPE_DATA_RTYPE_INPUT; - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.param = PTYPE_DATA_RTYPE_INPUT; + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); } else { BT_INFO("Out Report"); - data.param = PTYPE_DATA_RTYPE_OUTPUT; - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.param = PTYPE_DATA_RTYPE_OUTPUT; + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); } break; case BT_HID_TRANS_GET_REPORT: { BT_INFO("Get Report"); - data.type = HTYPE_TRANS_GET_REPORT; + recv_data.type = HTYPE_TRANS_GET_REPORT; if (param & BT_HID_DATA_RTYPE_INPUT) { BT_INFO("Input Report"); - data.param = PTYPE_DATA_RTYPE_INPUT; + recv_data.param = PTYPE_DATA_RTYPE_INPUT; } else { BT_INFO("Output Report"); - data.param = PTYPE_DATA_RTYPE_OUTPUT; + recv_data.param = PTYPE_DATA_RTYPE_OUTPUT; } - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); break; } case BT_HID_TRANS_SET_REPORT: { BT_INFO("Set Report"); - data.type = HTYPE_TRANS_SET_REPORT; + recv_data.type = HTYPE_TRANS_SET_REPORT; if (param & BT_HID_DATA_RTYPE_INPUT) { BT_INFO("Input Report"); - data.param = PTYPE_DATA_RTYPE_INPUT; + recv_data.param = PTYPE_DATA_RTYPE_INPUT; } else { BT_INFO("Output Report"); - data.param = PTYPE_DATA_RTYPE_OUTPUT; + recv_data.param = PTYPE_DATA_RTYPE_OUTPUT; } - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); break; } case BT_HID_TRANS_GET_PROTOCOL:{ BT_INFO("Get_PROTOCOL"); - data.type = HTYPE_TRANS_GET_PROTOCOL; - data.param = PTYPE_DATA_RTYPE_INPUT; - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.type = HTYPE_TRANS_GET_PROTOCOL; + recv_data.param = PTYPE_DATA_RTYPE_INPUT; + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); break; } case BT_HID_TRANS_SET_PROTOCOL:{ BT_INFO("Set_PROTOCOL"); - data.type = HTYPE_TRANS_SET_PROTOCOL; - data.param = PTYPE_DATA_RTYPE_INPUT; - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.type = HTYPE_TRANS_SET_PROTOCOL; + recv_data.param = PTYPE_DATA_RTYPE_INPUT; + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); break; } case BT_HID_TRANS_GET_IDLE:{ BT_INFO("Get_IDLE"); - data.type = HTYPE_TRANS_GET_IDLE; - data.param = PTYPE_DATA_RTYPE_INPUT; - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.type = HTYPE_TRANS_GET_IDLE; + recv_data.param = PTYPE_DATA_RTYPE_INPUT; + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); break; } case BT_HID_TRANS_SET_IDLE:{ BT_INFO("Set_IDLE"); - data.type = HTYPE_TRANS_SET_IDLE; - data.param = PTYPE_DATA_RTYPE_INPUT; - data.buffer_size = len; - data.buffer = (char *) malloc(sizeof(char) * len); - if (data.buffer) - memcpy(data.buffer, buffer, len); + recv_data.type = HTYPE_TRANS_SET_IDLE; + recv_data.param = PTYPE_DATA_RTYPE_INPUT; + recv_data.buffer_size = len; + recv_data.buffer = (char *)g_malloc0(sizeof(char) * len); + memcpy(recv_data.buffer, buffer, len); break; } @@ -481,7 +410,7 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, BT_ERR("Send Handshake Message"); guint8 type = BT_HID_TRANS_HANDSHAKE | BT_HID_HSHK_ERR_UNSUPPORTED_REQUEST; - data.type = HTYPE_TRANS_UNKNOWN; + recv_data.type = HTYPE_TRANS_UNKNOWN; int fd = g_io_channel_unix_get_fd(chan); int bytes = write(fd, &type, sizeof(type)); BT_INFO("Bytes Written %d", bytes); @@ -490,13 +419,13 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, } _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DATA_RECEIVED, - BLUETOOTH_ERROR_NONE, &data, + BLUETOOTH_ERROR_NONE, &recv_data, event_info->cb, event_info->user_data); - if (data.buffer) - g_free(data.buffer); + if (recv_data.buffer) + g_free(recv_data.buffer); - if (data.address) - g_free((char *)data.address); + if (recv_data.address) + g_free((char *)recv_data.address); } else { BT_ERR("Error while reading data %d [%s]", status, info->address); if (err) { @@ -517,79 +446,127 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, return TRUE; } -int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *addr) +static void __free_hid_info(void *data) { - hid_info_t *info = NULL; - hid_connected_device_info_t *dev_info = NULL; - char address[18]; - info = hid_info; + BT_DBG(""); - if (info == NULL) - return -1; - _bt_convert_addr_type_to_string((char *)address, addr->addr); - BT_INFO("Address [%s]", address); - dev_info = __find_hid_info_with_address(address); - if (dev_info == NULL) { - dev_info = (hid_connected_device_info_t *) - g_malloc0(sizeof(hid_connected_device_info_t)); - - dev_info->intr_fd = -1; - dev_info->ctrl_fd = -1; - dev_info->intr_fd = fd; - dev_info->address = g_strdup(address); - dev_info->intr_data_io = g_io_channel_unix_new(dev_info->intr_fd); - g_io_channel_set_encoding(dev_info->intr_data_io, NULL, NULL); - g_io_channel_set_flags(dev_info->intr_data_io, G_IO_FLAG_NONBLOCK, NULL); - g_io_channel_set_close_on_unref(dev_info->intr_data_io, TRUE); - dev_info->intr_data_id = g_io_add_watch(dev_info->intr_data_io, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - __received_cb, dev_info); - hid_info->device_list = g_slist_append(hid_info->device_list, dev_info); - } else { - dev_info->ctrl_fd = fd; - dev_info->ctrl_data_io = g_io_channel_unix_new(dev_info->ctrl_fd); - g_io_channel_set_encoding(dev_info->ctrl_data_io, NULL, NULL); - g_io_channel_set_flags(dev_info->ctrl_data_io, G_IO_FLAG_NONBLOCK, NULL); - g_io_channel_set_close_on_unref(dev_info->ctrl_data_io, TRUE); - dev_info->ctrl_data_id = g_io_add_watch(dev_info->ctrl_data_io, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - __received_cb, dev_info); + hid_connected_device_info_t *dev_info = (hid_connected_device_info_t *)data; + + if (dev_info->disconnect_idle_id > 0) { + BT_INFO("Disconnect idle still not process remove source"); + g_source_remove(dev_info->disconnect_idle_id); + dev_info->disconnect_idle_id = 0; } + __hid_disconnect(dev_info); +} - if (dev_info->ctrl_fd != -1 && dev_info->intr_fd != -1) - __hid_connected_cb(dev_info, BLUETOOTH_ERROR_NONE); +int _bt_hid_device_get_fd(const char *address, int *ctrl, int *intr) +{ - return 0; + int ret = BLUETOOTH_ERROR_NONE; + char *adapter_path; + GVariant *result = NULL; + GError *err = NULL; + GDBusConnection *conn; + GDBusProxy *server_proxy; + int index1 = 0; + int index2 = 0; + GUnixFDList *out_fd_list = NULL; + conn = _bt_get_system_private_conn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + adapter_path = _bt_get_device_object_path((char *)address); + retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL); + BT_INFO_C("Device : %s", adapter_path); + server_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, BT_BLUEZ_NAME, + adapter_path, "org.bluez.Input1", NULL, NULL); + g_free(adapter_path); + + if (server_proxy == NULL) { + BT_ERR("Failed to get the network server proxy\n"); + return BLUETOOTH_ERROR_INTERNAL; + } + + result = g_dbus_proxy_call_with_unix_fd_list_sync(server_proxy, "GetFD", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &out_fd_list, + NULL, + &err); + if (result == NULL) { + if (err != NULL) { + g_dbus_error_strip_remote_error(err); + BT_ERR("INPUT server register Error: %s\n", err->message); + if (g_strcmp0(err->message, "Already Exists") == 0) + ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED; + else + ret = BLUETOOTH_ERROR_INTERNAL; + + g_error_free(err); + } + } else { + g_variant_get(result, "(hh)", &index1, &index2); + int fd1 = g_unix_fd_list_get(out_fd_list, index1, NULL); + int fd2 = g_unix_fd_list_get(out_fd_list, index2, NULL); + + *ctrl = fd1; + *intr = fd2; + g_object_unref(out_fd_list); + g_variant_unref(result); + } + g_object_unref(server_proxy); + return ret; } -static hid_info_t *__register_method() -{ - int object_id; - hid_info_t *info = NULL; - char *path = NULL; - path = g_strdup_printf("/org/socket/server/%d", getpid()); - object_id = _bt_register_new_conn(path, new_hid_connection); - if (object_id < 0) - return NULL; +int _bt_hid_new_connection(bluetooth_device_address_t *addr, + int ctrl_fd, int intr_fd) +{ + hid_connected_device_info_t *dev_info = NULL; + char address[18]; + char secure_addr[BT_ADDRESS_STRING_SIZE] = { 0 }; - info = g_new(hid_info_t, 1); - info->object_id = (guint)object_id; - info->path = path; - info->id = 0; - info->device_list = NULL; + _bt_convert_addr_type_to_string((char *)address, addr->addr); + _bt_convert_addr_string_to_secure_string(secure_addr, address); + BT_INFO("Address [%s]", secure_addr); + dev_info = __find_hid_info_with_address(address); + if (dev_info != NULL) + __free_hid_info(dev_info); + + dev_info = (hid_connected_device_info_t *) + g_malloc0(sizeof(hid_connected_device_info_t)); + + dev_info->ctrl_fd = ctrl_fd; + dev_info->intr_fd = intr_fd; + dev_info->address = g_strdup(address); + dev_info->ctrl_data_io = g_io_channel_unix_new(dev_info->ctrl_fd); + dev_info->intr_data_io = g_io_channel_unix_new(dev_info->intr_fd); + g_io_channel_set_encoding(dev_info->ctrl_data_io, NULL, NULL); + g_io_channel_set_flags(dev_info->ctrl_data_io, G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_close_on_unref(dev_info->ctrl_data_io, TRUE); + g_io_channel_set_encoding(dev_info->intr_data_io, NULL, NULL); + g_io_channel_set_flags(dev_info->intr_data_io, G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_close_on_unref(dev_info->intr_data_io, TRUE); + dev_info->ctrl_data_id = g_io_add_watch(dev_info->ctrl_data_io, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + __received_cb, dev_info); + dev_info->intr_data_id = g_io_add_watch(dev_info->intr_data_io, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + __received_cb, dev_info); + device_list = g_slist_append(device_list, dev_info); + + __hid_connected_cb(dev_info, BLUETOOTH_ERROR_NONE); - return info; + return 0; } -void _bluetooth_hid_free_hid_info(void) +void _bt_hid_free_hid_info(void) { - if (hid_info == NULL) { - BT_DBG("hid_info is already NULL"); - return; - } + g_slist_free_full(device_list, __free_hid_info); - __free_hid_info(hid_info); - hid_info = NULL; + device_list = NULL; } BT_EXPORT_API int bluetooth_hid_device_init(hid_cb_func_ptr callback_ptr, void *user_data) @@ -629,8 +606,8 @@ BT_EXPORT_API int bluetooth_hid_device_deinit(void) BT_EXPORT_API int bluetooth_hid_device_activate(void) { - bt_register_profile_info_t profile_info; - int result = BLUETOOTH_ERROR_NONE; + GVariant *reply; + GError *err = NULL; BT_CHECK_ENABLED(return); @@ -640,32 +617,34 @@ BT_EXPORT_API int bluetooth_hid_device_activate(void) return BLUETOOTH_ERROR_PERMISSION_DEINED; } - if (hid_info != NULL) - return BLUETOOTH_ERROR_IN_PROGRESS; + reply = __bt_hid_agent_dbus_send(BT_HID_AGENT_OBJECT_PATH, + BT_HID_SERVICE_INTERFACE, + "RegisterApplication", &err, NULL); - hid_info = __register_method(); - if (hid_info == NULL) - return BLUETOOTH_ERROR_INTERNAL; - - hid_info->uuid = g_strdup(HID_DEVICE_UUID); - - profile_info.authentication = TRUE; - profile_info.authorization = TRUE; - profile_info.obj_path = hid_info->path; - profile_info.role = g_strdup("Hid"); - profile_info.service = hid_info->uuid; - profile_info.uuid = hid_info->uuid; - - BT_INFO("uuid %s", profile_info.uuid); - result = _bt_register_profile(&profile_info, FALSE); + if (!reply) { + int ret = BLUETOOTH_ERROR_INTERNAL; + BT_ERR("Error returned in method call"); + if (err) { + BT_ERR("Error = %s", err->message); + if (strcmp(err->message, BT_ERROR_ALREADY_EXIST) == 0) + ret = BLUETOOTH_ERROR_IN_PROGRESS; + else + ret = BLUETOOTH_ERROR_INTERNAL; + g_clear_error(&err); + } + return ret; + } - g_free(profile_info.role); + g_variant_unref(reply); - return result; + return BLUETOOTH_ERROR_NONE; } BT_EXPORT_API int bluetooth_hid_device_deactivate(void) { + GVariant *reply; + GError *err = NULL; + BT_CHECK_ENABLED(return); if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_DEACTIVATE) @@ -674,12 +653,27 @@ BT_EXPORT_API int bluetooth_hid_device_deactivate(void) return BLUETOOTH_ERROR_PERMISSION_DEINED; } - if (hid_info == NULL) - return BLUETOOTH_ERROR_NOT_IN_OPERATION; + reply = __bt_hid_agent_dbus_send(BT_HID_AGENT_OBJECT_PATH, + BT_HID_SERVICE_INTERFACE, + "UnregisterApplication", &err, NULL); + + if (!reply) { + int ret = BLUETOOTH_ERROR_INTERNAL; + BT_ERR("Error returned in method call"); + if (err) { + BT_ERR("Error = %s", err->message); + if (strcmp(err->message, BT_ERROR_NOT_AVAILABLE) == 0) + ret = BLUETOOTH_ERROR_NOT_IN_OPERATION; + else + ret = BLUETOOTH_ERROR_INTERNAL; + g_clear_error(&err); + } + return ret; + } - _bt_unregister_profile(hid_info->path); + g_variant_unref(reply); - _bluetooth_hid_free_hid_info(); + _bt_hid_free_hid_info(); return BLUETOOTH_ERROR_NONE; } @@ -773,14 +767,14 @@ BT_EXPORT_API int bluetooth_hid_device_send_mouse_event(const char *remote_addr, BT_ERR("Connection Information not found"); return BLUETOOTH_ERROR_INVALID_PARAM; } - int socket_fd; - - if (info->intr_fd != -1 && info->ctrl_fd == -1) - socket_fd = info->intr_fd; - else - socket_fd = info->ctrl_fd; - written = write(socket_fd, &send_event, sizeof(send_event)); + if (info->intr_fd >= 0) { + written = write(info->intr_fd, &send_event, sizeof(send_event)); + } else { + BT_ERR("intr_fd(%d) is invalid.", info->intr_fd); + __free_hid_info(info); + return BLUETOOTH_ERROR_INTERNAL; + } return written; } @@ -824,14 +818,14 @@ BT_EXPORT_API int bluetooth_hid_device_send_key_event(const char *remote_addr, return BLUETOOTH_ERROR_INVALID_PARAM; } - int socket_fd; - - if (info->intr_fd != -1 && info->ctrl_fd == -1) - socket_fd = info->intr_fd; - else - socket_fd = info->ctrl_fd; + if (info->intr_fd >= 0) { + written = write(info->intr_fd, &send_event, sizeof(send_event)); + } else { + BT_ERR("intr_fd(%d) is invalid.", info->intr_fd); + __free_hid_info(info); + return BLUETOOTH_ERROR_INTERNAL; + } - written = write(socket_fd, &send_event, sizeof(send_event)); return written; } @@ -841,7 +835,6 @@ BT_EXPORT_API int bluetooth_hid_device_send_custom_event(const char *remote_addr { int result; int written = 0; - int socket_fd; hid_connected_device_info_t *info = NULL; char *send_event = NULL; @@ -878,20 +871,20 @@ BT_EXPORT_API int bluetooth_hid_device_send_custom_event(const char *remote_addr return BLUETOOTH_ERROR_INVALID_PARAM; } - if (info->intr_fd != -1 && info->ctrl_fd == -1) - socket_fd = info->intr_fd; - else - socket_fd = info->ctrl_fd; - - send_event = g_malloc0(data_len + 2); - - send_event[0] = (char)btcode; - send_event[1] = (char)report_id; - memcpy(send_event + 2, data, data_len); + if (info->intr_fd >= 0) { + send_event = g_malloc0(data_len + 2); - written = write(socket_fd, send_event, data_len + 2); + send_event[0] = (char)btcode; + send_event[1] = (char)report_id; + memcpy(send_event + 2, data, data_len); - g_free(send_event); + written = write(info->intr_fd, send_event, data_len + 2); + g_free(send_event); + } else { + BT_ERR("intr_fd(%d) is invalid.", info->intr_fd); + __free_hid_info(info); + return BLUETOOTH_ERROR_INTERNAL; + } return written; } @@ -904,15 +897,22 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, { int result; struct reports output_report = { 0 }; - int bytes = BLUETOOTH_ERROR_INTERNAL; + int bytes = -1; hid_connected_device_info_t *info = NULL; + + BT_CHECK_PARAMETER(remote_addr, return); + info = __find_hid_info_with_address(remote_addr); if (info == NULL) { BT_ERR("Connection Information not found"); return BLUETOOTH_ERROR_INVALID_PARAM; } - BT_CHECK_PARAMETER(remote_addr, return); + if (info->ctrl_fd < 0) { + BT_ERR("ctrl_fd(%d) is invalid.", info->ctrl_fd); + __free_hid_info(info); + return BLUETOOTH_ERROR_INTERNAL; + } switch (privilege_token_reply) { case 0: @@ -946,7 +946,7 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, output_report.type = BT_HID_TRANS_DATA | BT_HID_DATA_RTYPE_INPUT; memcpy(output_report.rep_data, data, data_len); - bytes = write(info->intr_fd, &output_report, + bytes = write(info->ctrl_fd, &output_report, sizeof(output_report)); BT_DBG("Bytes Written %d", bytes); break; @@ -958,50 +958,40 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, break; case HTYPE_TRANS_GET_PROTOCOL: { - BT_DBG("Replying to Get_PROTOCOL"); output_report.type = BT_HID_TRANS_DATA | BT_HID_DATA_RTYPE_OUTPUT; output_report.rep_data[0] = data[0]; - bytes = write(info->intr_fd, &output_report, 2); - BT_DBG("Bytes Written %d", bytes); + bytes = write(info->ctrl_fd, &output_report, 2); break; } case HTYPE_TRANS_SET_PROTOCOL: { - BT_DBG("Reply to Set_Protocol"); output_report.type = BT_HID_TRANS_DATA | BT_HID_DATA_RTYPE_INPUT; memcpy(output_report.rep_data, data, data_len); bytes = write(info->ctrl_fd, &output_report, sizeof(output_report)); - BT_DBG("Bytes Written %d", bytes); break; } case HTYPE_TRANS_HANDSHAKE: { - BT_DBG("Replying Handshake"); output_report.type = BT_HID_TRANS_HANDSHAKE | data[0]; memset(output_report.rep_data, 0, sizeof(output_report.rep_data)); - bytes = write(info->intr_fd, &output_report.type, + bytes = write(info->ctrl_fd, &output_report.type, sizeof(output_report.type)); - BT_DBG("Bytes Written %d", bytes); break; } case HTYPE_TRANS_GET_IDLE: { - BT_DBG("Replying to Get_IDLE"); output_report.type = BT_HID_TRANS_DATA | BT_HID_DATA_RTYPE_OUTPUT; output_report.rep_data[0] = data[0]; - bytes = write(info->intr_fd, &output_report, 2); - BT_DBG("Bytes Written %d", bytes); + bytes = write(info->ctrl_fd, &output_report, 2); break; } case HTYPE_TRANS_SET_IDLE: { - BT_DBG("Reply to Set_IDLE"); output_report.type = BT_HID_TRANS_DATA | BT_HID_DATA_RTYPE_INPUT; memcpy(output_report.rep_data, data, data_len); bytes = write(info->ctrl_fd, &output_report, sizeof(output_report)); - BT_DBG("Bytes Written %d", bytes); break; } @@ -1009,5 +999,8 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, break; } } + + BT_DBG("Bytes Written %d", bytes); + return bytes; }