Apply tizen 3.0 based product patchsets
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-hid-device.c
index a1c03aa..23942fa 100644 (file)
@@ -135,15 +135,15 @@ int _bt_hid_device_get_fd(const char *address, int *ctrl, int *intr)
                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);
 
@@ -183,7 +183,7 @@ static void __hid_connected_cb(hid_connected_device_info_t *info,
                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]");
@@ -313,12 +313,19 @@ void __free_hid_info(hid_info_t *info)
        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;
@@ -327,14 +334,15 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond,
 
        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) {
@@ -352,115 +360,159 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond,
 
                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;
 }
@@ -480,10 +532,6 @@ int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *add
        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;
@@ -507,9 +555,9 @@ int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *add
                                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;
 }
@@ -521,9 +569,9 @@ static hid_info_t *__register_method()
        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;
@@ -533,6 +581,17 @@ static hid_info_t *__register_method()
        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;
@@ -573,6 +632,8 @@ BT_EXPORT_API int bluetooth_hid_device_activate(void)
        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");
@@ -596,13 +657,17 @@ BT_EXPORT_API int bluetooth_hid_device_activate(void)
        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");
@@ -614,8 +679,8 @@ BT_EXPORT_API int bluetooth_hid_device_deactivate(void)
 
        _bt_unregister_profile(hid_info->path);
 
-       __free_hid_info(hid_info);
-       hid_info = NULL;
+       _bluetooth_hid_free_hid_info();
+
        return BLUETOOTH_ERROR_NONE;
 }
 
@@ -627,6 +692,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");
@@ -646,6 +713,10 @@ BT_EXPORT_API int bluetooth_hid_device_connect(const char *remote_addr)
 }
 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");
@@ -672,6 +743,8 @@ BT_EXPORT_API int bluetooth_hid_device_send_mouse_event(const char *remote_addr,
        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);
@@ -719,6 +792,8 @@ BT_EXPORT_API int bluetooth_hid_device_send_key_event(const char *remote_addr,
        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);
@@ -760,17 +835,22 @@ BT_EXPORT_API int bluetooth_hid_device_send_key_event(const char *remote_addr,
        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 */
@@ -803,7 +883,16 @@ BT_EXPORT_API int bluetooth_hid_device_send_rc_key_event(const char *remote_addr
        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;
 }
 
@@ -815,7 +904,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) {
@@ -823,6 +912,8 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr,
                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);
@@ -848,51 +939,74 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr,
        }
 
        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;