2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <gio/gunixfdlist.h>
19 #include <sys/socket.h>
21 #include "bluetooth-api.h"
22 #include "bt-internal-types.h"
23 #include "bluetooth-hid-api.h"
24 #include "bt-common.h"
25 #include "bt-request-sender.h"
26 #include "bt-event-handler.h"
28 #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
29 #define REPORTID_MOUSE 1
30 #define BT_HID_BUFFER_LEN 100
32 /* The types of HIDP transaction */
33 #define BT_HIDP_TRANSACTION_SET_PROTOCOL 0x70
34 #define BT_HIDP_TRANSACTION_GET_IDLE 0x80
35 #define BT_HIDP_TRANSACTION_SET_IDLE 0x90
36 #define BT_HIDP_TRANSACTION_DATA 0xa0
37 #define BT_HIDP_TRANSACTION_DATC 0xb0
38 #define BT_HIDP_TRANSACTION_HANDSHAKE 0x00
39 #define BT_HIDP_TRANSACTION_HID_CONTROL 0x10
40 #define BT_HIDP_TRANSACTION_GET_REPORT 0x40
41 #define BT_HIDP_TRANSACTION_SET_REPORT 0x50
42 #define BT_HIDP_TRANSACTION_GET_PROTOCOL 0x60
44 #define BT_HIDP_DATA_OUT_RTYPE 0x02
45 #define BT_HIDP_DATA_IN_RTYPE 0x01
47 #define BT_HIDP_HSHK_ERROR_UNSUPPORTED_REQUEST 0x03
48 #define BT_HIDP_HSHK_ERROR_INVALID_PARAM 0x04
49 #define BT_HIDP_HSHK_ERROR_UNKNOWN 0x0E
50 #define BT_HIDP_HSHK_ERROR_FATAL 0x0F
51 #define BT_HIDP_HSHK_OK_SUCCESSFUL 0x00
52 #define BT_HIDP_HSHK_NOT_AVAILABLE 0x01
53 #define BT_HIDP_HSHK_ERROR_INVALID_REPORT_ID 0x02
55 /* The masks of BT_HIDP header */
56 #define BT_HIDP_HEADER_PARAMETER_MASK 0x0f
57 #define BT_HIDP_HEADER_TRANSACTION_MASK 0xf0
70 GIOChannel *ctrl_data_io;
71 GIOChannel *intr_data_io;
75 guint disconnect_idle_id;
76 } hid_connected_device_info_t;
81 }__attribute__((__packed__));
83 static hid_info_t *hid_info = NULL;
85 /* Variable for privilege, only for write API,
86 before we should reduce time to bt-service dbus calling
87 -1 : Don't have a permission to access API
88 0 : Initial value, not yet check
89 1 : Have a permission to access API
91 static int privilege_token_send_mouse = 0;
92 static int privilege_token_send_key = 0;
93 static int privilege_token_reply = 0;
95 static gboolean __hid_disconnect(hid_connected_device_info_t *info);
97 static hid_connected_device_info_t *__find_hid_info_with_address(const char *remote_addr)
101 for ( l = hid_info->device_list; l != NULL; l = l->next) {
102 hid_connected_device_info_t *info = l->data;
103 if (g_strcmp0((const char *)info->address, (const char *)remote_addr) == 0)
109 static void __hid_connected_cb(hid_connected_device_info_t *info,
110 bt_event_info_t *event_info)
112 bluetooth_hid_request_t conn_info;
114 memset(&conn_info, 0x00, sizeof(bluetooth_hid_request_t));
115 if (info->intr_fd != -1 && info->ctrl_fd == -1)
116 conn_info.socket_fd = info->intr_fd;
118 conn_info.socket_fd = info->ctrl_fd;
119 _bt_convert_addr_string_to_type (conn_info.device_addr.addr , info->address);
121 BT_INFO_C("Connected [HID Device]");
122 _bt_common_event_cb(BLUETOOTH_HID_DEVICE_CONNECTED,
123 BLUETOOTH_ERROR_NONE, &conn_info,
124 event_info->cb, event_info->user_data);
127 static gboolean __hid_disconnect(hid_connected_device_info_t *info)
129 bluetooth_hid_request_t disconn_info;
130 int fd = info->ctrl_fd;
131 bt_event_info_t *event_info;
133 BT_INFO_C("Disconnected [HID Device]");
134 hid_info->device_list = g_slist_remove(hid_info->device_list, info);
135 if (info->ctrl_data_id > 0) {
136 g_source_remove(info->ctrl_data_id);
137 info->ctrl_data_id = 0;
139 if (info->intr_data_id > 0) {
140 g_source_remove(info->intr_data_id);
141 info->intr_data_id = 0;
144 if (info->intr_fd >= 0) {
145 close(info->ctrl_fd);
146 close(info->intr_fd);
151 if (info->ctrl_data_io) {
152 g_io_channel_shutdown(info->ctrl_data_io, TRUE, NULL);
153 g_io_channel_unref(info->ctrl_data_io);
154 info->ctrl_data_io = NULL;
156 if (info->intr_data_io) {
157 g_io_channel_shutdown(info->intr_data_io, TRUE, NULL);
158 g_io_channel_unref(info->intr_data_io);
159 info->intr_data_io = NULL;
161 info->disconnect_idle_id = 0;
162 event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT);
163 if (event_info == NULL)
166 memset(&disconn_info, 0x00, sizeof(bluetooth_hid_request_t));
167 disconn_info.socket_fd = fd;
168 _bt_convert_addr_string_to_type (disconn_info.device_addr.addr , info->address);
169 _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DISCONNECTED,
170 BLUETOOTH_ERROR_NONE, &disconn_info,
171 event_info->cb, event_info->user_data);
173 g_free(info->address);
180 void __free_hid_info(hid_info_t *info)
184 _bt_unregister_gdbus(info->object_id);
186 while (info->device_list) {
187 hid_connected_device_info_t *dev_info = NULL;
188 dev_info = (hid_connected_device_info_t *)info->device_list->data;
190 if (dev_info->disconnect_idle_id > 0) {
191 BT_INFO("Disconnect idle still not process remove source");
192 g_source_remove(dev_info->disconnect_idle_id);
193 dev_info->disconnect_idle_id = 0;
195 __hid_disconnect(dev_info);
203 static gboolean __received_cb(GIOChannel *chan, GIOCondition cond,
206 hid_connected_device_info_t *info = data;
207 GIOStatus status = G_IO_STATUS_NORMAL;
211 guint8 header, type, param;
212 bt_event_info_t *event_info;
213 retv_if(info == NULL, FALSE);
215 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
216 BT_ERR_C("HID disconnected: %d", info->ctrl_fd);
217 if (info->disconnect_idle_id > 0) {
218 BT_INFO("Disconnect idle still not process remove source");
219 g_source_remove(info->disconnect_idle_id);
220 info->disconnect_idle_id = 0;
222 __hid_disconnect(info);
225 status = g_io_channel_read_chars(chan, buffer, BT_RFCOMM_BUFFER_LEN,
227 if (status == G_IO_STATUS_NORMAL) {
228 BT_INFO("Parsing Data");
229 bluetooth_hid_received_data_t data = {0};
231 type = header & BT_HIDP_HEADER_TRANSACTION_MASK;
232 param = header & BT_HIDP_HEADER_PARAMETER_MASK;
233 BT_INFO("type %d , param %d", type, param);
234 BT_INFO("Data Reveived from %s" , info->address);
235 data.address = g_strdup(info->address);
237 case BT_HIDP_TRANSACTION_HANDSHAKE:
238 BT_INFO("TRANS HANDSHAKE");
239 data.type = HTYPE_TRANS_HANDSHAKE;
240 data.buffer_size = len;
241 data.buffer = (char *) malloc(sizeof(char) * len);
243 memcpy(data.buffer, buffer, len);
245 case BT_HIDP_TRANSACTION_HID_CONTROL:
246 BT_INFO("HID CONTROL");
247 data.type = HTYPE_TRANS_HID_CONTROL;
248 data.buffer_size = len;
249 data.buffer = (char *) malloc(sizeof(char) * len);
251 memcpy(data.buffer, buffer, len);
253 case BT_HIDP_TRANSACTION_DATA:
254 BT_INFO("TRANS DATA");
255 data.type = HTYPE_TRANS_DATA;
256 if ( param & BT_HIDP_DATA_IN_RTYPE) {
257 BT_INFO("Input Report");
258 data.param = PTYPE_DATA_RTYPE_INPUT;
259 data.buffer_size = len;
260 data.buffer = (char *) malloc(sizeof(char) * len);
262 memcpy(data.buffer, buffer, len);
265 BT_INFO("Out Report");
266 data.param = PTYPE_DATA_RTYPE_OUTPUT;
267 data.buffer_size = len;
268 data.buffer = (char *) malloc(sizeof(char) * len);
270 memcpy(data.buffer, buffer, len);
273 case BT_HIDP_TRANSACTION_GET_REPORT: {
274 BT_INFO("Get Report");
275 data.type = HTYPE_TRANS_GET_REPORT;
276 if (param & BT_HIDP_DATA_IN_RTYPE) {
277 BT_INFO("Input Report");
278 data.param = PTYPE_DATA_RTYPE_INPUT;
280 BT_INFO("Output Report");
281 data.param = PTYPE_DATA_RTYPE_OUTPUT;
283 data.buffer_size = len;
284 data.buffer = (char *) malloc(sizeof(char) * len);
286 memcpy(data.buffer, buffer, len);
289 case BT_HIDP_TRANSACTION_SET_REPORT: {
290 BT_INFO("Set Report");
291 data.type = HTYPE_TRANS_SET_REPORT;
292 if (param & BT_HIDP_DATA_IN_RTYPE) {
293 BT_INFO("Input Report");
294 data.param = PTYPE_DATA_RTYPE_INPUT;
296 BT_INFO("Output Report");
297 data.param = PTYPE_DATA_RTYPE_OUTPUT;
299 data.buffer_size = len;
300 data.buffer = (char *) malloc(sizeof(char) * len);
302 memcpy(data.buffer, buffer, len);
305 case BT_HIDP_TRANSACTION_GET_PROTOCOL:{
306 BT_INFO("Get_PROTOCOL");
307 data.type = HTYPE_TRANS_GET_PROTOCOL;
308 data.param = PTYPE_DATA_RTYPE_INPUT;
309 data.buffer_size = len;
310 data.buffer = (char *) malloc(sizeof(char) * len);
312 memcpy(data.buffer, buffer, len);
315 case BT_HIDP_TRANSACTION_SET_PROTOCOL:{
316 BT_INFO("Set_PROTOCOL");
317 data.type = HTYPE_TRANS_SET_PROTOCOL;
318 data.param = PTYPE_DATA_RTYPE_INPUT;
319 data.buffer_size = len;
320 data.buffer = (char *) malloc(sizeof(char) * len);
322 memcpy(data.buffer, buffer, len);
326 BT_INFO("unsupported HIDP control message");
327 BT_ERR("Send Handshake Message");
328 guint8 type = BT_HIDP_TRANSACTION_HANDSHAKE |
329 BT_HIDP_HSHK_ERROR_UNSUPPORTED_REQUEST;
330 data.type = HTYPE_TRANS_UNKNOWN;
331 int fd = g_io_channel_unix_get_fd(chan);
332 int bytes = write(fd, &type, sizeof(type));
333 BT_INFO("Bytes Written %d", bytes);
337 event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT);
338 if (event_info == NULL) {
340 g_free((char *)data.address);
344 _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DATA_RECEIVED,
345 BLUETOOTH_ERROR_NONE, &data,
346 event_info->cb, event_info->user_data);
349 g_free((char *)data.address);
351 BT_INFO("Error while reading data");
356 int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *addr)
358 hid_info_t *info = NULL;
359 hid_connected_device_info_t *dev_info = NULL;
360 bt_event_info_t *event_info = NULL;
366 _bt_convert_addr_type_to_string((char *)address, addr->addr);
367 BT_INFO("Address [%s]", address);
368 dev_info = __find_hid_info_with_address(address);
369 if (dev_info == NULL) {
370 dev_info = (hid_connected_device_info_t *)
371 g_malloc0(sizeof(hid_connected_device_info_t));
372 if (dev_info == NULL) {
373 BT_ERR("Fail to allocation memory");
377 dev_info->intr_fd = -1;
378 dev_info->ctrl_fd = -1;
379 dev_info->intr_fd = fd;
380 dev_info->address = g_strdup(address);
381 dev_info->intr_data_io = g_io_channel_unix_new(dev_info->intr_fd);
382 g_io_channel_set_encoding(dev_info->intr_data_io, NULL, NULL);
383 g_io_channel_set_flags(dev_info->intr_data_io, G_IO_FLAG_NONBLOCK, NULL);
385 dev_info->intr_data_id = g_io_add_watch(dev_info->intr_data_io,
386 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
387 __received_cb, dev_info);
388 hid_info->device_list = g_slist_append(hid_info->device_list, dev_info);
390 dev_info->ctrl_fd = fd;
391 dev_info->ctrl_data_io = g_io_channel_unix_new(dev_info->ctrl_fd);
392 g_io_channel_set_encoding(dev_info->ctrl_data_io, NULL, NULL);
393 g_io_channel_set_flags(dev_info->ctrl_data_io, G_IO_FLAG_NONBLOCK, NULL);
395 dev_info->ctrl_data_id = g_io_add_watch(dev_info->ctrl_data_io,
396 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
397 __received_cb, dev_info);
399 if (dev_info->ctrl_fd != -1 && dev_info->intr_fd != -1) {
400 event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT);
402 __hid_connected_cb(dev_info, event_info);
407 static hid_info_t *__register_method()
410 hid_info_t *info = NULL;
412 path = g_strdup_printf("/org/socket/server/%d", getpid());
414 object_id = _bt_register_new_conn(path, new_hid_connection);
418 info = g_new(hid_info_t, 1);
419 info->object_id = (guint)object_id;
422 info->device_list = NULL;
427 BT_EXPORT_API int bluetooth_hid_device_init(hid_cb_func_ptr callback_ptr, void *user_data)
431 /* Register HID Device events */
432 BT_INFO("BT_HID_DEVICE_EVENT");
433 ret = _bt_register_event(BT_HID_DEVICE_EVENT , (void *)callback_ptr, user_data);
435 if (ret != BLUETOOTH_ERROR_NONE &&
436 ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
437 BT_ERR("Fail to init the event handler");
441 _bt_set_user_data(BT_HID, (void *)callback_ptr, user_data);
443 return BLUETOOTH_ERROR_NONE;
446 BT_EXPORT_API int bluetooth_hid_device_deinit(void)
450 ret = _bt_unregister_event(BT_HID_DEVICE_EVENT);
452 if (ret != BLUETOOTH_ERROR_NONE) {
453 BT_ERR("Fail to deinit the event handler");
457 _bt_set_user_data(BT_HID, NULL, NULL);
459 return BLUETOOTH_ERROR_NONE;
462 BT_EXPORT_API int bluetooth_hid_device_activate(void)
464 bt_register_profile_info_t profile_info;
465 int result = BLUETOOTH_ERROR_NONE;
467 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_ACTIVATE)
468 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
469 BT_ERR("Don't have a privilege to use this API");
470 return BLUETOOTH_ERROR_PERMISSION_DEINED;
473 if (hid_info != NULL)
474 return BLUETOOTH_ERROR_IN_PROGRESS;
476 hid_info = __register_method();
477 if (hid_info == NULL)
478 return BLUETOOTH_ERROR_INTERNAL;
480 hid_info->uuid = g_strdup(HID_UUID);
482 profile_info.authentication = TRUE;
483 profile_info.authorization = TRUE;
484 profile_info.obj_path = hid_info->path;
485 profile_info.role = g_strdup("Hid");
486 profile_info.service = hid_info->uuid;
487 profile_info.uuid = hid_info->uuid;
489 BT_INFO("uuid %s", profile_info.uuid);
490 result = _bt_register_profile_platform(&profile_info, FALSE);
495 BT_EXPORT_API int bluetooth_hid_device_deactivate(void)
497 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_DEACTIVATE)
498 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
499 BT_ERR("Don't have a privilege to use this API");
500 return BLUETOOTH_ERROR_PERMISSION_DEINED;
503 if (hid_info == NULL)
504 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
506 _bt_unregister_profile(hid_info->path);
508 __free_hid_info(hid_info);
510 return BLUETOOTH_ERROR_NONE;
513 BT_EXPORT_API int bluetooth_hid_device_connect(const char *remote_addr)
515 char device_address[BT_ADDRESS_STRING_SIZE] = {0};
516 hid_connected_device_info_t *info = NULL;
519 BT_CHECK_PARAMETER(remote_addr, return);
521 info = __find_hid_info_with_address(remote_addr);
523 BT_ERR("Connection Already Exists");
524 return BLUETOOTH_ERROR_ALREADY_CONNECT;
526 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_CONNECT)
527 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
528 BT_ERR("Don't have a privilege to use this API");
529 return BLUETOOTH_ERROR_PERMISSION_DEINED;
532 memcpy(device_address, remote_addr, BT_ADDRESS_STRING_SIZE);
533 ret = _bt_connect_profile(device_address, HID_UUID, NULL, NULL);
537 BT_EXPORT_API int bluetooth_hid_device_disconnect(const char *remote_addr)
539 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_DISCONNECT)
540 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
541 BT_ERR("Don't have a privilege to use this API");
542 return BLUETOOTH_ERROR_PERMISSION_DEINED;
544 hid_connected_device_info_t *info = NULL;
546 info = __find_hid_info_with_address(remote_addr);
548 return BLUETOOTH_ERROR_INVALID_PARAM;
550 _bt_disconnect_profile((char *)remote_addr, HID_UUID, NULL, NULL);
552 info->disconnect_idle_id = g_idle_add((GSourceFunc)__hid_disconnect, info);
555 return BLUETOOTH_ERROR_NONE;
557 BT_EXPORT_API int bluetooth_hid_device_send_mouse_event(const char *remote_addr,
558 hid_send_mouse_event_t send_event)
563 hid_connected_device_info_t *info = NULL;
565 switch (privilege_token_send_mouse) {
567 result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_HID_DEVICE_SEND_MOUSE_EVENT);
569 if (result == BLUETOOTH_ERROR_NONE) {
570 privilege_token_send_mouse = 1; /* Have a permission */
571 } else if (result == BLUETOOTH_ERROR_PERMISSION_DEINED) {
572 BT_ERR("Don't have a privilege to use this API");
573 privilege_token_send_mouse = -1; /* Don't have a permission */
574 return BLUETOOTH_ERROR_PERMISSION_DEINED;
576 /* Just break - It is not related with permission error */
580 /* Already have a privilege */
583 return BLUETOOTH_ERROR_PERMISSION_DEINED;
585 /* Invalid privilge token value */
586 return BLUETOOTH_ERROR_INTERNAL;
588 info = __find_hid_info_with_address(remote_addr);
590 BT_ERR("Connection Information not found");
591 return BLUETOOTH_ERROR_INVALID_PARAM;
594 if (info->intr_fd != -1 && info->ctrl_fd == -1)
595 socket_fd = info->intr_fd;
597 socket_fd = info->ctrl_fd;
599 written = write(socket_fd, &send_event, sizeof(send_event));
604 BT_EXPORT_API int bluetooth_hid_device_send_key_event(const char *remote_addr,
605 hid_send_key_event_t send_event)
610 hid_connected_device_info_t *info = NULL;
612 switch (privilege_token_send_key) {
614 result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_HID_DEVICE_SEND_KEY_EVENT);
616 if (result == BLUETOOTH_ERROR_NONE) {
617 privilege_token_send_key = 1; /* Have a permission */
618 } else if (result == BLUETOOTH_ERROR_PERMISSION_DEINED) {
619 BT_ERR("Don't have a privilege to use this API");
620 privilege_token_send_key = -1; /* Don't have a permission */
621 return BLUETOOTH_ERROR_PERMISSION_DEINED;
623 /* Just break - It is not related with permission error */
627 /* Already have a privilege */
630 return BLUETOOTH_ERROR_PERMISSION_DEINED;
632 /* Invalid privilge token value */
633 return BLUETOOTH_ERROR_INTERNAL;
636 info = __find_hid_info_with_address(remote_addr);
638 BT_ERR("Connection Information not found");
639 return BLUETOOTH_ERROR_INVALID_PARAM;
642 if (info->intr_fd != -1 && info->ctrl_fd == -1)
643 socket_fd = info->intr_fd;
645 socket_fd = info->ctrl_fd;
647 written = write(socket_fd, &send_event, sizeof(send_event));
651 BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr,
652 bt_hid_header_type_t htype,
653 bt_hid_param_type_t ptype,
655 unsigned int data_len)
658 struct reports output_report = { 0 };
660 hid_connected_device_info_t *info = NULL;
661 info = __find_hid_info_with_address(remote_addr);
663 BT_ERR("Connection Information not found");
664 return BLUETOOTH_ERROR_INVALID_PARAM;
667 switch (privilege_token_reply) {
669 result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_HID_DEVICE_SEND_REPLY_TO_REPORT);
671 if (result == BLUETOOTH_ERROR_NONE) {
672 privilege_token_reply = 1; /* Have a permission */
673 } else if (result == BLUETOOTH_ERROR_PERMISSION_DEINED) {
674 BT_ERR("Don't have a privilege to use this API");
675 privilege_token_reply = -1; /* Don't have a permission */
676 return BLUETOOTH_ERROR_PERMISSION_DEINED;
678 /* Just break - It is not related with permission error */
682 /* Already have a privilege */
685 return BLUETOOTH_ERROR_PERMISSION_DEINED;
687 /* Invalid privilge token value */
688 return BLUETOOTH_ERROR_INTERNAL;
691 BT_INFO("htype %d ptype %d", htype, ptype);
693 case HTYPE_TRANS_GET_REPORT: {
695 case PTYPE_DATA_RTYPE_INPUT: {
696 output_report.type = BT_HIDP_TRANSACTION_DATA |
697 BT_HIDP_DATA_IN_RTYPE;
698 memcpy(output_report.rep_data, data, data_len);
699 bytes = write(info->intr_fd, &output_report,
700 sizeof(output_report));
701 BT_DBG("Bytes Written %d", bytes);
705 BT_INFO("Not Supported");
709 case HTYPE_TRANS_GET_PROTOCOL: {
710 BT_DBG("Replying to Get_PROTOCOL");
711 output_report.type = BT_HIDP_TRANSACTION_DATA | BT_HIDP_DATA_OUT_RTYPE;
712 output_report.rep_data[0] = data[0];
713 bytes = write(info->intr_fd, &output_report, 2);
714 BT_DBG("Bytes Written %d", bytes);
717 case HTYPE_TRANS_SET_PROTOCOL: {
718 BT_DBG("Reply to Set_Protocol");
719 output_report.type = BT_HIDP_TRANSACTION_DATA | BT_HIDP_DATA_IN_RTYPE;
720 memcpy(output_report.rep_data, data, data_len);
721 bytes = write(info->ctrl_fd, &output_report,
722 sizeof(output_report));
723 BT_DBG("Bytes Written %d", bytes);
726 case HTYPE_TRANS_HANDSHAKE: {
727 BT_DBG("Replying Handshake");
728 output_report.type = BT_HIDP_TRANSACTION_HANDSHAKE | data[0];
729 memset(output_report.rep_data, 0, sizeof(output_report.rep_data));
730 bytes = write(info->intr_fd, &output_report.type,
731 sizeof(output_report.type));
732 BT_DBG("Bytes Written %d", bytes);