X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-api%2Fbt-hid-device.c;h=db0f6bb93304de9ce2fd118007f3264c873144bc;hb=d21d5daacc8684fd8bd3de0a023f6ab880c0c991;hp=d6b307f36e0fdcf70f1b924a9f44d43489c9a4e1;hpb=2db600c3809082a563d2688477f3a4f3a3f5bacf;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-api/bt-hid-device.c b/bt-api/bt-hid-device.c index d6b307f..db0f6bb 100755 --- 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 @@ -156,11 +152,36 @@ int _bt_hid_device_get_fd(const char *address, int *ctrl, int *intr) return ret; } +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; + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, NULL); + + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_HID_SERVICE_NAME, path, interface, NULL, err); + if (proxy == NULL) { + BT_ERR("Unable to allocate new proxy"); + return NULL; + } + + reply = g_dbus_proxy_call_sync(proxy, method, parameters, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, err); + + 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) return info; @@ -245,7 +266,7 @@ static gboolean __hid_disconnect(hid_connected_device_info_t *info) 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; @@ -290,29 +311,6 @@ static gboolean __hid_disconnect(hid_connected_device_info_t *info) 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); - } - - g_free(info->path); - g_free(info->uuid); - g_free(info); -} - static gboolean __is_error_by_disconnect(GError *err) { return !g_strcmp0(err->message, "Connection reset by peer") || @@ -321,9 +319,9 @@ static gboolean __is_error_by_disconnect(GError *err) } static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, - gpointer user_data) + gpointer data) { - hid_connected_device_info_t *info = user_data; + hid_connected_device_info_t *info = data; GIOStatus status = G_IO_STATUS_NORMAL; char buffer[BT_RFCOMM_BUFFER_LEN]; gsize len = 0; @@ -454,14 +452,36 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, 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); + 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); + break; + } + default: { BT_INFO("unsupported HIDP control message"); BT_ERR("Send Handshake Message"); - guint8 type1 = BT_HID_TRANS_HANDSHAKE | + guint8 type = BT_HID_TRANS_HANDSHAKE | BT_HID_HSHK_ERR_UNSUPPORTED_REQUEST; data.type = HTYPE_TRANS_UNKNOWN; int fd = g_io_channel_unix_get_fd(chan); - int bytes = write(fd, &type1, sizeof(type1)); + int bytes = write(fd, &type, sizeof(type)); BT_INFO("Bytes Written %d", bytes); break; } @@ -497,23 +517,15 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *addr) { - hid_info_t *info = NULL; hid_connected_device_info_t *dev_info = NULL; char address[18]; - info = hid_info; - 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)); - if (dev_info == NULL) { - BT_ERR("Fail to allocation memory"); - return -1; - } dev_info->intr_fd = -1; dev_info->ctrl_fd = -1; @@ -526,7 +538,7 @@ int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *add 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); + device_list = g_slist_append(device_list, dev_info); } else { dev_info->ctrl_fd = fd; dev_info->ctrl_data_io = g_io_channel_unix_new(dev_info->ctrl_fd); @@ -543,35 +555,26 @@ int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *add return 0; } -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; +static void __free_hid_info(void *data) +{ + BT_DBG(""); - info = g_new(hid_info_t, 1); - info->object_id = (guint)object_id; - info->path = path; - info->id = 0; - info->device_list = NULL; + hid_connected_device_info_t *dev_info = (hid_connected_device_info_t *)data; - return info; + 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); } void _bluetooth_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) @@ -611,8 +614,10 @@ 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); if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_ACTIVATE) == BLUETOOTH_ERROR_PERMISSION_DEINED) { @@ -620,40 +625,61 @@ 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; + 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; + } - BT_INFO("uuid %s", profile_info.uuid); - result = _bt_register_profile(&profile_info, FALSE); + 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) == BLUETOOTH_ERROR_PERMISSION_DEINED) { BT_ERR("Don't have a privilege to use this API"); 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); - _bt_unregister_profile(hid_info->path); + 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; + } + + g_variant_unref(reply); _bluetooth_hid_free_hid_info(); @@ -668,6 +694,8 @@ BT_EXPORT_API int bluetooth_hid_device_connect(const char *remote_addr) BT_DBG("+"); BT_CHECK_PARAMETER(remote_addr, return); + BT_CHECK_ENABLED(return); + info = __find_hid_info_with_address(remote_addr); if (info) { BT_ERR("Connection Already Exists"); @@ -679,7 +707,7 @@ BT_EXPORT_API int bluetooth_hid_device_connect(const char *remote_addr) return BLUETOOTH_ERROR_PERMISSION_DEINED; } - g_strlcpy(device_address, remote_addr, BT_ADDRESS_STRING_SIZE); + memcpy(device_address, remote_addr, BT_ADDRESS_STRING_SIZE); ret = _bt_connect_profile(device_address, HID_DEVICE_UUID, __hid_connect_response_cb, NULL); @@ -689,6 +717,8 @@ BT_EXPORT_API int bluetooth_hid_device_disconnect(const char *remote_addr) { BT_CHECK_PARAMETER(remote_addr, return); + BT_CHECK_ENABLED(return); + if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_DISCONNECT) == BLUETOOTH_ERROR_PERMISSION_DEINED) { BT_ERR("Don't have a privilege to use this API"); @@ -855,9 +885,7 @@ BT_EXPORT_API int bluetooth_hid_device_send_custom_event(const char *remote_addr else socket_fd = info->ctrl_fd; - send_event = (char*)g_malloc0(data_len + 2); - if (send_event == NULL) - return BLUETOOTH_ERROR_OUT_OF_MEMORY; + send_event = g_malloc0(data_len + 2); send_event[0] = (char)btcode; send_event[1] = (char)report_id; @@ -878,7 +906,7 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, { int result; struct reports output_report = { 0 }; - int bytes = 0; + int bytes = BLUETOOTH_ERROR_INTERNAL; hid_connected_device_info_t *info = NULL; info = __find_hid_info_with_address(remote_addr); if (info == NULL) { @@ -959,6 +987,26 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, 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); + 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; + } + default: break; }