4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
24 #include <gio/gunixfdlist.h>
25 #include <sys/socket.h>
27 #include "bluetooth-api.h"
28 #include "bt-internal-types.h"
29 #include "bluetooth-hid-api.h"
30 #include "bt-common.h"
31 #include "bt-request-sender.h"
32 #include "bt-event-handler.h"
34 #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
35 #define REPORTID_MOUSE 1
36 #define BT_HID_BUFFER_LEN 100
38 /* HIDP header masks */
39 #define HIDP_HEADER_TRANS_MASK 0xf0
40 #define HIDP_HEADER_PARAM_MASK 0x0f
42 /* HIDP transaction types */
43 #define HIDP_TRANS_HANDSHAKE 0x00
44 #define HIDP_TRANS_HID_CONTROL 0x10
45 #define HIDP_TRANS_GET_REPORT 0x40
46 #define HIDP_TRANS_SET_REPORT 0x50
47 #define HIDP_TRANS_GET_PROTOCOL 0x60
48 #define HIDP_TRANS_SET_PROTOCOL 0x70
49 #define HIDP_TRANS_GET_IDLE 0x80
50 #define HIDP_TRANS_SET_IDLE 0x90
51 #define HIDP_TRANS_DATA 0xa0
52 #define HIDP_TRANS_DATC 0xb0
54 #define HIDP_DATA_RTYPE_INPUT 0x01
55 #define HIDP_DATA_RTYPE_OUTPUT 0x02
57 #define HIDP_HSHK_SUCCESSFUL 0x00
58 #define HIDP_HSHK_NOT_READY 0x01
59 #define HIDP_HSHK_ERR_INVALID_REPORT_ID 0x02
60 #define HIDP_HSHK_ERR_UNSUPPORTED_REQUEST 0x03
61 #define HIDP_HSHK_ERR_INVALID_PARAMETER 0x04
62 #define HIDP_HSHK_ERR_UNKNOWN 0x0E
63 #define HIDP_HSHK_ERR_FATAL 0x0F
76 GIOChannel *ctrl_data_io;
77 GIOChannel *intr_data_io;
81 guint disconnect_idle_id;
82 } hid_connected_device_info_t;
87 }__attribute__((__packed__));
89 static hid_info_t *hid_info = NULL;
91 /* Variable for privilege, only for write API,
92 before we should reduce time to bt-service dbus calling
93 -1 : Don't have a permission to access API
94 0 : Initial value, not yet check
95 1 : Have a permission to access API
97 static int privilege_token_send_mouse = 0;
98 static int privilege_token_send_key = 0;
99 static int privilege_token_reply = 0;
101 static gboolean __hid_disconnect(hid_connected_device_info_t *info);
103 static hid_connected_device_info_t *__find_hid_info_with_address(const char *remote_addr)
107 for ( l = hid_info->device_list; l != NULL; l = l->next) {
108 hid_connected_device_info_t *info = l->data;
109 if (g_strcmp0((const char *)info->address, (const char *)remote_addr) == 0)
115 static void __hid_connected_cb(hid_connected_device_info_t *info,
116 bt_event_info_t *event_info)
118 bluetooth_hid_request_t conn_info;
120 memset(&conn_info, 0x00, sizeof(bluetooth_hid_request_t));
121 if (info->intr_fd != -1 && info->ctrl_fd == -1)
122 conn_info.socket_fd = info->intr_fd;
124 conn_info.socket_fd = info->ctrl_fd;
125 _bt_convert_addr_string_to_type (conn_info.device_addr.addr , info->address);
127 BT_INFO_C("Connected [HID Device]");
128 _bt_common_event_cb(BLUETOOTH_HID_DEVICE_CONNECTED,
129 BLUETOOTH_ERROR_NONE, &conn_info,
130 event_info->cb, event_info->user_data);
133 static gboolean __hid_disconnect(hid_connected_device_info_t *info)
135 bluetooth_hid_request_t disconn_info;
136 int fd = info->ctrl_fd;
137 bt_event_info_t *event_info;
139 BT_INFO_C("Disconnected [HID Device]");
140 hid_info->device_list = g_slist_remove(hid_info->device_list, info);
141 if (info->ctrl_data_id > 0) {
142 g_source_remove(info->ctrl_data_id);
143 info->ctrl_data_id = 0;
145 if (info->intr_data_id > 0) {
146 g_source_remove(info->intr_data_id);
147 info->intr_data_id = 0;
150 if (info->intr_fd >= 0) {
151 close(info->ctrl_fd);
152 close(info->intr_fd);
157 if (info->ctrl_data_io) {
158 g_io_channel_shutdown(info->ctrl_data_io, TRUE, NULL);
159 g_io_channel_unref(info->ctrl_data_io);
160 info->ctrl_data_io = NULL;
162 if (info->intr_data_io) {
163 g_io_channel_shutdown(info->intr_data_io, TRUE, NULL);
164 g_io_channel_unref(info->intr_data_io);
165 info->intr_data_io = NULL;
167 info->disconnect_idle_id = 0;
168 event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT);
169 if (event_info == NULL)
172 memset(&disconn_info, 0x00, sizeof(bluetooth_hid_request_t));
173 disconn_info.socket_fd = fd;
174 _bt_convert_addr_string_to_type (disconn_info.device_addr.addr , info->address);
175 _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DISCONNECTED,
176 BLUETOOTH_ERROR_NONE, &disconn_info,
177 event_info->cb, event_info->user_data);
179 g_free(info->address);
186 void __free_hid_info(hid_info_t *info)
190 _bt_unregister_gdbus(info->object_id);
192 while (info->device_list) {
193 hid_connected_device_info_t *dev_info = NULL;
194 dev_info = (hid_connected_device_info_t *)info->device_list->data;
196 if (dev_info->disconnect_idle_id > 0) {
197 BT_INFO("Disconnect idle still not process remove source");
198 g_source_remove(dev_info->disconnect_idle_id);
199 dev_info->disconnect_idle_id = 0;
201 __hid_disconnect(dev_info);
209 static gboolean __received_cb(GIOChannel *chan, GIOCondition cond,
212 hid_connected_device_info_t *info = data;
213 GIOStatus status = G_IO_STATUS_NORMAL;
217 guint8 header, type, param;
218 bt_event_info_t *event_info;
219 retv_if(info == NULL, FALSE);
221 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
222 BT_ERR_C("HID disconnected: %d", info->ctrl_fd);
223 if (info->disconnect_idle_id > 0) {
224 BT_INFO("Disconnect idle still not process remove source");
225 g_source_remove(info->disconnect_idle_id);
226 info->disconnect_idle_id = 0;
228 __hid_disconnect(info);
231 status = g_io_channel_read_chars(chan, buffer, BT_RFCOMM_BUFFER_LEN,
233 if (status == G_IO_STATUS_NORMAL) {
234 BT_INFO("Parsing Data");
235 bluetooth_hid_received_data_t data = {0};
237 type = header & HIDP_HEADER_TRANS_MASK;
238 param = header & HIDP_HEADER_PARAM_MASK;
239 BT_INFO("type %d , param %d", type, param);
240 BT_INFO("Data Reveived from %s" , info->address);
241 data.address = g_strdup(info->address);
243 case HIDP_TRANS_HANDSHAKE:
244 BT_INFO("TRANS HANDSHAKE");
245 data.type = HTYPE_TRANS_HANDSHAKE;
246 data.buffer_size = len;
247 data.buffer = (char *) malloc(sizeof(char) * len);
248 /* Fix : NULL_RETURNS */
249 if (NULL == data.buffer) {
250 BT_ERR("Failed to allocate memory");
251 data.buffer_size = 0;
253 memcpy(data.buffer, buffer, len);
256 case HIDP_TRANS_HID_CONTROL:
257 BT_INFO("HID CONTROL");
258 data.type = HTYPE_TRANS_HID_CONTROL;
259 data.buffer_size = len;
260 data.buffer = (char *) malloc(sizeof(char) * len);
261 /* Fix : NULL_RETURNS */
262 if (NULL == data.buffer) {
263 BT_ERR("Failed to allocate memory");
264 data.buffer_size = 0;
266 memcpy(data.buffer, buffer, len);
269 case HIDP_TRANS_DATA:
270 BT_INFO("TRANS DATA");
271 data.type = HTYPE_TRANS_DATA;
272 if ( param & HIDP_DATA_RTYPE_INPUT) {
273 BT_INFO("Input Report");
274 data.param = PTYPE_DATA_RTYPE_INPUT;
275 data.buffer_size = len;
276 data.buffer = (char *) malloc(sizeof(char) * len);
277 /* Fix : NULL_RETURNS */
278 if (NULL == data.buffer) {
279 BT_ERR("Failed to allocate memory");
280 data.buffer_size = 0;
282 memcpy(data.buffer, buffer, len);
286 BT_INFO("Out Report");
287 data.param = PTYPE_DATA_RTYPE_OUTPUT;
288 data.buffer_size = len;
289 data.buffer = (char *) malloc(sizeof(char) * len);
290 /* Fix : NULL_RETURNS */
291 if (NULL == data.buffer) {
292 BT_ERR("Failed to allocate memory");
293 data.buffer_size = 0;
295 memcpy(data.buffer, buffer, len);
299 case HIDP_TRANS_GET_REPORT: {
300 BT_INFO("Get Report");
301 data.type = HTYPE_TRANS_GET_REPORT;
302 if (param & HIDP_DATA_RTYPE_INPUT) {
303 BT_INFO("Input Report");
304 data.param = PTYPE_DATA_RTYPE_INPUT;
306 BT_INFO("Output Report");
307 data.param = PTYPE_DATA_RTYPE_OUTPUT;
309 data.buffer_size = len;
310 data.buffer = (char *) malloc(sizeof(char) * len);
311 /* Fix : NULL_RETURNS */
312 if (NULL == data.buffer) {
313 BT_ERR("Failed to allocate memory");
314 data.buffer_size = 0;
316 memcpy(data.buffer, buffer, len);
320 case HIDP_TRANS_SET_REPORT: {
321 BT_INFO("Set Report");
322 data.type = HTYPE_TRANS_SET_REPORT;
323 if (param & HIDP_DATA_RTYPE_INPUT) {
324 BT_INFO("Input Report");
325 data.param = PTYPE_DATA_RTYPE_INPUT;
327 BT_INFO("Output Report");
328 data.param = PTYPE_DATA_RTYPE_OUTPUT;
330 data.buffer_size = len;
331 data.buffer = (char *) malloc(sizeof(char) * len);
332 /* Fix : NULL_RETURNS */
333 if (NULL == data.buffer) {
334 BT_ERR("Failed to allocate memory");
335 data.buffer_size = 0;
337 memcpy(data.buffer, buffer, len);
341 case HIDP_TRANS_GET_PROTOCOL:{
342 BT_INFO("Get_PROTOCOL");
343 data.type = HTYPE_TRANS_GET_PROTOCOL;
344 data.param = PTYPE_DATA_RTYPE_INPUT;
345 data.buffer_size = len;
346 data.buffer = (char *) malloc(sizeof(char) * len);
347 /* Fix : NULL_RETURNS */
348 if (NULL == data.buffer) {
349 BT_ERR("Failed to allocate memory");
350 data.buffer_size = 0;
352 memcpy(data.buffer, buffer, len);
356 case HIDP_TRANS_SET_PROTOCOL:{
357 BT_INFO("Set_PROTOCOL");
358 data.type = HTYPE_TRANS_SET_PROTOCOL;
359 data.param = PTYPE_DATA_RTYPE_INPUT;
360 data.buffer_size = len;
361 data.buffer = (char *) malloc(sizeof(char) * len);
362 /* Fix : NULL_RETURNS */
363 if (NULL == data.buffer) {
364 BT_ERR("Failed to allocate memory");
365 data.buffer_size = 0;
367 memcpy(data.buffer, buffer, len);
372 BT_INFO("unsupported HIDP control message");
373 BT_ERR("Send Handshake Message");
374 guint8 type = HIDP_TRANS_HANDSHAKE |
375 HIDP_HSHK_ERR_UNSUPPORTED_REQUEST;
376 data.type = HTYPE_TRANS_UNKNOWN;
377 int fd = g_io_channel_unix_get_fd(chan);
378 int bytes = write(fd, &type, sizeof(type));
379 BT_INFO("Bytes Written %d", bytes);
383 event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT);
384 if (event_info == NULL)
387 _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DATA_RECEIVED,
388 BLUETOOTH_ERROR_NONE, &data,
389 event_info->cb, event_info->user_data);
393 g_free((char *)data.address);
395 BT_INFO("Error while reading data");
400 int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *addr)
402 hid_info_t *info = NULL;
403 hid_connected_device_info_t *dev_info = NULL;
404 bt_event_info_t *event_info = NULL;
410 _bt_convert_addr_type_to_string((char *)address, addr->addr);
411 BT_INFO("Address [%s]", address);
412 dev_info = __find_hid_info_with_address(address);
413 if (dev_info == NULL) {
414 dev_info = (hid_connected_device_info_t *)
415 g_malloc0(sizeof(hid_connected_device_info_t));
416 dev_info->intr_fd = -1;
417 dev_info->ctrl_fd = -1;
418 dev_info->intr_fd = fd;
419 dev_info->address = g_strdup(address);
420 dev_info->intr_data_io = g_io_channel_unix_new(dev_info->intr_fd);
421 g_io_channel_set_encoding(dev_info->intr_data_io, NULL, NULL);
422 g_io_channel_set_flags(dev_info->intr_data_io, G_IO_FLAG_NONBLOCK, NULL);
424 dev_info->intr_data_id = g_io_add_watch(dev_info->intr_data_io,
425 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
426 __received_cb, dev_info);
427 hid_info->device_list = g_slist_append(hid_info->device_list, dev_info);
429 dev_info->ctrl_fd = fd;
430 dev_info->ctrl_data_io = g_io_channel_unix_new(dev_info->ctrl_fd);
431 g_io_channel_set_encoding(dev_info->ctrl_data_io, NULL, NULL);
432 g_io_channel_set_flags(dev_info->ctrl_data_io, G_IO_FLAG_NONBLOCK, NULL);
434 dev_info->ctrl_data_id = g_io_add_watch(dev_info->ctrl_data_io,
435 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
436 __received_cb, dev_info);
438 if (dev_info->ctrl_fd != -1 && dev_info->intr_fd != -1) {
439 event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT);
441 __hid_connected_cb(dev_info, event_info);
446 static hid_info_t *__register_method()
449 hid_info_t *info = NULL;
451 path = g_strdup_printf("/org/socket/server/%d", getpid());
453 object_id = _bt_register_new_conn(path, new_hid_connection);
457 info = g_new(hid_info_t, 1);
458 info->object_id = (guint)object_id;
461 info->device_list = NULL;
466 BT_EXPORT_API int bluetooth_hid_device_init(hid_cb_func_ptr callback_ptr, void *user_data)
470 /* Register HID Device events */
471 BT_INFO("BT_HID_DEVICE_EVENT");
472 ret = _bt_register_event(BT_HID_DEVICE_EVENT , (void *)callback_ptr, user_data);
474 if (ret != BLUETOOTH_ERROR_NONE &&
475 ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
476 BT_ERR("Fail to init the event handler");
480 _bt_set_user_data(BT_HID, (void *)callback_ptr, user_data);
482 return BLUETOOTH_ERROR_NONE;
485 BT_EXPORT_API int bluetooth_hid_device_deinit(void)
489 ret = _bt_unregister_event(BT_HID_DEVICE_EVENT);
491 if (ret != BLUETOOTH_ERROR_NONE) {
492 BT_ERR("Fail to deinit the event handler");
496 _bt_set_user_data(BT_HID, NULL, NULL);
498 return BLUETOOTH_ERROR_NONE;
501 BT_EXPORT_API int bluetooth_hid_device_activate(void)
503 bt_register_profile_info_t profile_info;
504 int result = BLUETOOTH_ERROR_NONE;
506 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_ACTIVATE)
507 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
508 BT_ERR("Don't have a privilege to use this API");
509 return BLUETOOTH_ERROR_PERMISSION_DEINED;
512 if (hid_info != NULL)
513 return BLUETOOTH_ERROR_IN_PROGRESS;
515 hid_info = __register_method();
516 if (hid_info == NULL)
517 return BLUETOOTH_ERROR_INTERNAL;
519 hid_info->uuid = g_strdup(HID_UUID);
521 profile_info.authentication = TRUE;
522 profile_info.authorization = TRUE;
523 profile_info.obj_path = hid_info->path;
524 profile_info.role = g_strdup("Hid");
525 profile_info.service = hid_info->uuid;
526 profile_info.uuid = hid_info->uuid;
528 BT_INFO("uuid %s", profile_info.uuid);
529 result = _bt_register_profile_platform(&profile_info, FALSE);
534 BT_EXPORT_API int bluetooth_hid_device_deactivate(void)
536 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_DEACTIVATE)
537 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
538 BT_ERR("Don't have a privilege to use this API");
539 return BLUETOOTH_ERROR_PERMISSION_DEINED;
542 if (hid_info == NULL)
543 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
545 _bt_unregister_profile(hid_info->path);
547 __free_hid_info(hid_info);
549 return BLUETOOTH_ERROR_NONE;
552 BT_EXPORT_API int bluetooth_hid_device_connect(const char *remote_addr)
554 char device_address[BT_ADDRESS_STRING_SIZE] = {0};
555 hid_connected_device_info_t *info = NULL;
557 BT_CHECK_PARAMETER(remote_addr, return);
559 info = __find_hid_info_with_address(remote_addr);
561 BT_ERR("Connection Already Exists");
562 return BLUETOOTH_ERROR_ALREADY_CONNECT;
564 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_CONNECT)
565 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
566 BT_ERR("Don't have a privilege to use this API");
567 return BLUETOOTH_ERROR_PERMISSION_DEINED;
570 memcpy(device_address, remote_addr, BT_ADDRESS_STRING_SIZE);
571 _bt_connect_profile(device_address, HID_UUID, NULL, NULL);
573 return BLUETOOTH_ERROR_NONE;
575 BT_EXPORT_API int bluetooth_hid_device_disconnect(const char *remote_addr)
577 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HID_DEVICE_DISCONNECT)
578 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
579 BT_ERR("Don't have a privilege to use this API");
580 return BLUETOOTH_ERROR_PERMISSION_DEINED;
582 hid_connected_device_info_t *info = NULL;
584 info = __find_hid_info_with_address(remote_addr);
586 return BLUETOOTH_ERROR_INVALID_PARAM;
588 _bt_disconnect_profile((char *)remote_addr, HID_UUID, NULL, NULL);
590 info->disconnect_idle_id = g_idle_add((GSourceFunc)__hid_disconnect, info);
593 return BLUETOOTH_ERROR_NONE;
595 BT_EXPORT_API int bluetooth_hid_device_send_mouse_event(const char *remote_addr,
596 hid_send_mouse_event_t send_event)
600 hid_connected_device_info_t *info = NULL;
602 switch (privilege_token_send_mouse) {
604 result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_HID_DEVICE_SEND_MOUSE_EVENT);
606 if (result == BLUETOOTH_ERROR_NONE) {
607 privilege_token_send_mouse = 1; /* Have a permission */
608 } else if (result == BLUETOOTH_ERROR_PERMISSION_DEINED) {
609 BT_ERR("Don't have a privilege to use this API");
610 privilege_token_send_mouse = -1; /* Don't have a permission */
611 return BLUETOOTH_ERROR_PERMISSION_DEINED;
613 /* Just break - It is not related with permission error */
617 /* Already have a privilege */
620 return BLUETOOTH_ERROR_PERMISSION_DEINED;
622 /* Invalid privilge token value */
623 return BLUETOOTH_ERROR_INTERNAL;
625 info = __find_hid_info_with_address(remote_addr);
627 BT_ERR("Connection Information not found");
628 return BLUETOOTH_ERROR_INVALID_PARAM;
635 if (info->intr_fd != -1 && info->ctrl_fd == -1)
636 socket_fd = info->intr_fd;
638 socket_fd = info->ctrl_fd;
640 written = write(socket_fd, &send_event, sizeof(send_event));
645 BT_EXPORT_API int bluetooth_hid_device_send_key_event(const char *remote_addr,
646 hid_send_key_event_t send_event)
650 hid_connected_device_info_t *info = NULL;
652 switch (privilege_token_send_key) {
654 result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_HID_DEVICE_SEND_KEY_EVENT);
656 if (result == BLUETOOTH_ERROR_NONE) {
657 privilege_token_send_key = 1; /* Have a permission */
658 } else if (result == BLUETOOTH_ERROR_PERMISSION_DEINED) {
659 BT_ERR("Don't have a privilege to use this API");
660 privilege_token_send_key = -1; /* Don't have a permission */
661 return BLUETOOTH_ERROR_PERMISSION_DEINED;
663 /* Just break - It is not related with permission error */
667 /* Already have a privilege */
670 return BLUETOOTH_ERROR_PERMISSION_DEINED;
672 /* Invalid privilge token value */
673 return BLUETOOTH_ERROR_INTERNAL;
676 info = __find_hid_info_with_address(remote_addr);
678 BT_ERR("Connection Information not found");
679 return BLUETOOTH_ERROR_INVALID_PARAM;
687 if (info->intr_fd != -1 && info->ctrl_fd == -1)
688 socket_fd = info->intr_fd;
690 socket_fd = info->ctrl_fd;
692 written = write(socket_fd, &send_event, sizeof(send_event));
696 BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr,
697 bt_hid_header_type_t htype,
698 bt_hid_param_type_t ptype,
700 unsigned int data_len)
703 struct reports output_report = { 0 };
705 hid_connected_device_info_t *info = NULL;
706 info = __find_hid_info_with_address(remote_addr);
708 BT_ERR("Connection Information not found");
709 return BLUETOOTH_ERROR_INVALID_PARAM;
712 switch (privilege_token_reply) {
714 result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_HID_DEVICE_SEND_REPLY_TO_REPORT);
716 if (result == BLUETOOTH_ERROR_NONE) {
717 privilege_token_reply = 1; /* Have a permission */
718 } else if (result == BLUETOOTH_ERROR_PERMISSION_DEINED) {
719 BT_ERR("Don't have a privilege to use this API");
720 privilege_token_reply = -1; /* Don't have a permission */
721 return BLUETOOTH_ERROR_PERMISSION_DEINED;
723 /* Just break - It is not related with permission error */
727 /* Already have a privilege */
730 return BLUETOOTH_ERROR_PERMISSION_DEINED;
732 /* Invalid privilge token value */
733 return BLUETOOTH_ERROR_INTERNAL;
736 BT_INFO("htype %d ptype %d", htype, ptype);
738 case HTYPE_TRANS_GET_REPORT: {
740 case PTYPE_DATA_RTYPE_INPUT: {
741 output_report.type = HIDP_TRANS_DATA |
742 HIDP_DATA_RTYPE_INPUT;
743 memcpy(output_report.rep_data, data, data_len);
744 bytes = write(info->intr_fd, &output_report,
745 sizeof(output_report));
746 BT_DBG("Bytes Written %d", bytes);
750 BT_INFO("Not Supported");
754 case HTYPE_TRANS_GET_PROTOCOL: {
755 BT_DBG("Replying to Get_PROTOCOL");
756 output_report.type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUTPUT;
757 output_report.rep_data[0] = data[0];
758 bytes = write(info->intr_fd, &output_report, 2);
759 BT_DBG("Bytes Written %d", bytes);
762 case HTYPE_TRANS_SET_PROTOCOL: {
763 BT_DBG("Reply to Set_Protocol");
764 output_report.type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT;
765 memcpy(output_report.rep_data, data, data_len);
766 bytes = write(info->ctrl_fd, &output_report,
767 sizeof(output_report));
768 BT_DBG("Bytes Written %d", bytes);
771 case HTYPE_TRANS_HANDSHAKE: {
772 BT_DBG("Replying Handshake");
773 output_report.type = HIDP_TRANS_HANDSHAKE | data[0];
774 memset(output_report.rep_data, 0, sizeof(output_report.rep_data));
775 bytes = write(info->intr_fd, &output_report.type,
776 sizeof(output_report.type));
777 BT_DBG("Bytes Written %d", bytes);