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) {
+ if (g_strcmp0(err->message, "Already Exists") == 0)
ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
- } else {
+ else
ret = BLUETOOTH_ERROR_INTERNAL;
- }
+
g_error_free(err);
}
} else {
- g_variant_get (result, "(hh)", &index1, &index2);
+ 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);
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);
+ _bt_convert_addr_string_to_type(conn_info.device_addr.addr, info->address);
if (result == BLUETOOTH_ERROR_NONE)
BT_INFO_C("Connected [HID Device]");
g_free(info);
}
+static gboolean __is_error_by_disconnect(GError *err)
+{
+ return !g_strcmp0(err->message, "Connection reset by peer") ||
+ !g_strcmp0(err->message, "Connection timed out") ||
+ !g_strcmp0(err->message, "Software caused connection abort");
+}
+
static gboolean __received_cb(GIOChannel *chan, GIOCondition cond,
gpointer data)
{
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;
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
BT_ERR_C("HID disconnected: %d", info->ctrl_fd);
- if (info->disconnect_idle_id > 0) {
- BT_INFO("Disconnect idle still not process remove source");
- g_source_remove(info->disconnect_idle_id);
- info->disconnect_idle_id = 0;
- }
+ if (info->disconnect_idle_id > 0) {
+ BT_INFO("Disconnect idle still not process remove source");
+ g_source_remove(info->disconnect_idle_id);
+ info->disconnect_idle_id = 0;
+ }
__hid_disconnect(info);
return FALSE;
}
+
status = g_io_channel_read_chars(chan, buffer, BT_RFCOMM_BUFFER_LEN,
&len, &err);
if (status == G_IO_STATUS_NORMAL) {
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);
- 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);
- break;
- case BT_HID_TRANS_DATA:
- BT_INFO("TRANS DATA");
- 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);
- } 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);
- }
- break;
- case BT_HID_TRANS_GET_REPORT: {
- BT_INFO("Get Report");
- data.type = HTYPE_TRANS_GET_REPORT;
- if (param & BT_HID_DATA_RTYPE_INPUT) {
- BT_INFO("Input Report");
- data.param = PTYPE_DATA_RTYPE_INPUT;
- } else {
- BT_INFO("Output Report");
- data.param = PTYPE_DATA_RTYPE_OUTPUT;
- }
+ 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);
+ 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);
+ break;
+
+ case BT_HID_TRANS_DATA:
+ BT_INFO("TRANS DATA");
+ 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);
- break;
- }
- case BT_HID_TRANS_SET_REPORT: {
- BT_INFO("Set Report");
- data.type = HTYPE_TRANS_SET_REPORT;
- if (param & BT_HID_DATA_RTYPE_INPUT) {
- BT_INFO("Input Report");
- data.param = PTYPE_DATA_RTYPE_INPUT;
- } else {
- BT_INFO("Output Report");
- data.param = PTYPE_DATA_RTYPE_OUTPUT;
- }
+ } 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);
- break;
}
- case BT_HID_TRANS_GET_PROTOCOL:{
- BT_INFO("Get_PROTOCOL");
- data.type = HTYPE_TRANS_GET_PROTOCOL;
+ break;
+
+ case BT_HID_TRANS_GET_REPORT: {
+ BT_INFO("Get Report");
+ data.type = HTYPE_TRANS_GET_REPORT;
+ 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);
- break;
+ } else {
+ BT_INFO("Output Report");
+ data.param = PTYPE_DATA_RTYPE_OUTPUT;
}
- case BT_HID_TRANS_SET_PROTOCOL:{
- BT_INFO("Set_PROTOCOL");
- data.type = HTYPE_TRANS_SET_PROTOCOL;
+ 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_REPORT: {
+ BT_INFO("Set Report");
+ data.type = HTYPE_TRANS_SET_REPORT;
+ 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);
- break;
- }
- default: {
- BT_INFO("unsupported HIDP control message");
- BT_ERR("Send Handshake Message");
- 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, &type, sizeof(type));
- BT_INFO("Bytes Written %d", bytes);
- break;
+ } else {
+ BT_INFO("Output 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);
+ break;
}
- _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DATA_RECEIVED,
+ 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);
+ 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);
+ 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 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, &type, sizeof(type));
+ BT_INFO("Bytes Written %d", bytes);
+ break;
+ }
+ }
+
+ _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DATA_RECEIVED,
BLUETOOTH_ERROR_NONE, &data,
event_info->cb, event_info->user_data);
- if (data.buffer)
- g_free(data.buffer);
- if (data.address)
- g_free((char *)data.address);
+ if (data.buffer)
+ g_free(data.buffer);
+
+ if (data.address)
+ g_free((char *)data.address);
} else {
- BT_INFO("Error while reading data");
+ BT_ERR("Error while reading data %d [%s]", status, info->address);
+ if (err) {
+ BT_ERR("IO Channel read error [%s]", err->message);
+ if (status == G_IO_STATUS_ERROR &&
+ __is_error_by_disconnect(err)) {
+ BT_DBG("cond : %d", cond);
+ g_error_free(err);
+ __hid_disconnect(info);
+ return FALSE;
+ }
+ g_error_free(err);
+ } else if (status == G_IO_STATUS_EOF) {
+ __hid_disconnect(info);
+ return FALSE;
+ }
}
return TRUE;
}
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;
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
__received_cb, dev_info);
}
- if (dev_info->ctrl_fd != -1 && dev_info->intr_fd != -1) {
+
+ if (dev_info->ctrl_fd != -1 && dev_info->intr_fd != -1)
__hid_connected_cb(dev_info, BLUETOOTH_ERROR_NONE);
- }
return 0;
}
path = g_strdup_printf("/org/socket/server/%d", getpid());
object_id = _bt_register_new_conn(path, new_hid_connection);
- if (object_id < 0) {
+ if (object_id < 0)
return NULL;
- }
+
info = g_new(hid_info_t, 1);
info->object_id = (guint)object_id;
info->path = path;
return info;
}
+void _bluetooth_hid_free_hid_info(void)
+{
+ if (hid_info == NULL) {
+ BT_DBG("hid_info is already NULL");
+ return;
+ }
+
+ __free_hid_info(hid_info);
+ hid_info = NULL;
+}
+
BT_EXPORT_API int bluetooth_hid_device_init(hid_cb_func_ptr callback_ptr, void *user_data)
{
int ret;
bt_register_profile_info_t profile_info;
int result = BLUETOOTH_ERROR_NONE;
+ BT_CHECK_ENABLED(return);
+
if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_ACTIVATE)
== BLUETOOTH_ERROR_PERMISSION_DEINED) {
BT_ERR("Don't have a privilege to use this API");
profile_info.uuid = hid_info->uuid;
BT_INFO("uuid %s", profile_info.uuid);
- result = _bt_register_profile_platform(&profile_info, FALSE);
+ result = _bt_register_profile(&profile_info, FALSE);
+
+ g_free(profile_info.role);
return result;
}
BT_EXPORT_API int bluetooth_hid_device_deactivate(void)
{
+ 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");
_bt_unregister_profile(hid_info->path);
- __free_hid_info(hid_info);
- hid_info = NULL;
+ _bluetooth_hid_free_hid_info();
+
return BLUETOOTH_ERROR_NONE;
}
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_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");
int written = 0;
hid_connected_device_info_t *info = NULL;
+ BT_CHECK_PARAMETER(remote_addr, return);
+
switch (privilege_token_send_mouse) {
case 0:
result = _bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_SEND_MOUSE_EVENT);
int written = 0;
hid_connected_device_info_t *info = NULL;
+ BT_CHECK_PARAMETER(remote_addr, return);
+
switch (privilege_token_send_key) {
case 0:
result = _bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_SEND_KEY_EVENT);
return written;
}
-BT_EXPORT_API int bluetooth_hid_device_send_rc_key_event(const char *remote_addr,
- hid_send_rc_key_event_t send_event)
+BT_EXPORT_API int bluetooth_hid_device_send_custom_event(const char *remote_addr,
+ unsigned char btcode, unsigned char report_id,
+ const char *data, unsigned int data_len)
{
int result;
int written = 0;
int socket_fd;
hid_connected_device_info_t *info = NULL;
+ char *send_event = NULL;
+
+ BT_CHECK_PARAMETER(remote_addr, return);
+ BT_CHECK_PARAMETER(data, return);
switch (privilege_token_send_key) {
case 0:
- result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_HID_DEVICE_SEND_KEY_EVENT);
+ result = _bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_SEND_CUSTOM_EVENT);
if (result == BLUETOOTH_ERROR_NONE) {
privilege_token_send_key = 1; /* Have a permission */
else
socket_fd = info->ctrl_fd;
- written = write(socket_fd, &send_event, sizeof(send_event));
+ 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);
+
+ written = write(socket_fd, send_event, data_len + 2);
+
+ g_free(send_event);
+
return written;
}
{
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) {
return BLUETOOTH_ERROR_INVALID_PARAM;
}
+ BT_CHECK_PARAMETER(remote_addr, return);
+
switch (privilege_token_reply) {
case 0:
result = _bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_SEND_REPLY_TO_REPORT);
}
BT_INFO("htype %d ptype %d", htype, ptype);
- switch(htype) {
- case HTYPE_TRANS_GET_REPORT: {
- switch(ptype) {
- case PTYPE_DATA_RTYPE_INPUT: {
- 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,
- sizeof(output_report));
- BT_DBG("Bytes Written %d", bytes);
- break;
- }
- default:
- BT_INFO("Not Supported");
- break;
- }
- 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);
- break;
- }
- case HTYPE_TRANS_SET_PROTOCOL: {
- BT_DBG("Reply to Set_Protocol");
- output_report.type = BT_HID_TRANS_DATA | BT_HID_DATA_RTYPE_INPUT;
+ switch (htype) {
+ case HTYPE_TRANS_GET_REPORT: {
+ switch (ptype) {
+ case PTYPE_DATA_RTYPE_INPUT: {
+ 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));
+ bytes = write(info->intr_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,
- sizeof(output_report.type));
- BT_DBG("Bytes Written %d", bytes);
+ default:
+ BT_INFO("Not Supported");
break;
- }
- default:
- break;
+ }
+ 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);
+ 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,
+ 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);
+ 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;
}
}
return bytes;