#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;
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
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;
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;
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") ||
{
hid_connected_device_info_t *info = data;
GIOStatus status = G_IO_STATUS_NORMAL;
- char buffer[20];
+ char buffer[BT_RFCOMM_BUFFER_LEN];
gsize len = 0;
GError *err = NULL;
guint8 header, type, param;
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");
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);
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);
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)
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) {
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();
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");
{
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");
{
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) {
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;
}