1 /******************************************************************************
2 *
3 * Copyright 2016 The Android Open Source Project
4 * Copyright 2002-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20 /******************************************************************************
21 *
22 * This file contains the HID Device API entry points
23 *
24 ******************************************************************************/
25
26 #define LOG_TAG "hid"
27
28 #include "hidd_api.h"
29
30 #include <bluetooth/log.h>
31 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "hidd_int.h"
36 #include "hiddefs.h"
37 #include "os/log.h"
38 #include "osi/include/allocator.h"
39 #include "stack/include/bt_psm_types.h"
40 #include "stack/include/bt_types.h"
41 #include "stack/include/bt_uuid16.h"
42 #include "stack/include/sdp_api.h"
43 #include "stack/include/sdpdefs.h"
44 #include "stack/include/stack_metrics_logging.h"
45 #include "types/raw_address.h"
46
47 using namespace bluetooth;
48 using namespace bluetooth::legacy::stack::sdp;
49
50 tHID_DEV_CTB hd_cb;
51
52 /*******************************************************************************
53 *
54 * Function HID_DevInit
55 *
56 * Description Initializes control block
57 *
58 * Returns void
59 *
60 ******************************************************************************/
HID_DevInit(void)61 void HID_DevInit(void) {
62 log::verbose("");
63
64 memset(&hd_cb, 0, sizeof(tHID_DEV_CTB));
65 }
66
67 /*******************************************************************************
68 *
69 * Function HID_DevRegister
70 *
71 * Description Registers HID device with lower layers
72 *
73 * Returns tHID_STATUS
74 *
75 ******************************************************************************/
HID_DevRegister(tHID_DEV_HOST_CALLBACK * host_cback)76 tHID_STATUS HID_DevRegister(tHID_DEV_HOST_CALLBACK* host_cback) {
77 tHID_STATUS st;
78
79 log::verbose("");
80
81 if (hd_cb.reg_flag) {
82 log_counter_metrics(
83 android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_ALREADY_REGISTERED,
84 1);
85 return HID_ERR_ALREADY_REGISTERED;
86 }
87
88 if (host_cback == NULL) {
89 log_counter_metrics(
90 android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_HOST_CALLBACK_NULL,
91 1);
92 return HID_ERR_INVALID_PARAM;
93 }
94
95 /* Register with L2CAP */
96 st = hidd_conn_reg();
97 if (st != HID_SUCCESS) return st;
98
99 hd_cb.callback = host_cback;
100 hd_cb.reg_flag = TRUE;
101
102 if (hd_cb.pending_data) {
103 osi_free(hd_cb.pending_data);
104 hd_cb.pending_data = NULL;
105 }
106
107 return (HID_SUCCESS);
108 }
109
110 /*******************************************************************************
111 *
112 * Function HID_DevDeregister
113 *
114 * Description Deregisters HID device with lower layers
115 *
116 * Returns tHID_STATUS
117 *
118 ******************************************************************************/
HID_DevDeregister(void)119 tHID_STATUS HID_DevDeregister(void) {
120 log::verbose("");
121
122 if (!hd_cb.reg_flag) {
123 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
124 HIDD_ERR_NOT_REGISTERED_AT_DEREGISTER,
125 1);
126 return (HID_ERR_NOT_REGISTERED);
127 }
128
129 hidd_conn_dereg();
130
131 hd_cb.reg_flag = FALSE;
132
133 return (HID_SUCCESS);
134 }
135
136 /*******************************************************************************
137 *
138 * Function HID_DevAddRecord
139 *
140 * Description Creates SDP record for HID device
141 *
142 * Returns tHID_STATUS
143 *
144 ******************************************************************************/
HID_DevAddRecord(uint32_t handle,char * p_name,char * p_description,char * p_provider,uint16_t subclass,uint16_t desc_len,uint8_t * p_desc_data)145 tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description,
146 char* p_provider, uint16_t subclass,
147 uint16_t desc_len, uint8_t* p_desc_data) {
148 bool result = TRUE;
149
150 log::verbose("");
151
152 // Service Class ID List
153 if (result) {
154 uint16_t uuid = UUID_SERVCLASS_HUMAN_INTERFACE;
155 result &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
156 handle, 1, &uuid);
157 }
158
159 // Protocol Descriptor List
160 if (result) {
161 tSDP_PROTOCOL_ELEM proto_list[2];
162
163 proto_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
164 proto_list[0].num_params = 1;
165 proto_list[0].params[0] = BT_PSM_HIDC;
166
167 proto_list[1].protocol_uuid = UUID_PROTOCOL_HIDP;
168 proto_list[1].num_params = 0;
169
170 result &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(
171 handle, 2, proto_list);
172 }
173
174 // Language Base Attribute ID List
175 if (result) {
176 result &= get_legacy_stack_sdp_api()->handle.SDP_AddLanguageBaseAttrIDList(
177 handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8,
178 LANGUAGE_BASE_ID);
179 }
180
181 // Additional Protocol Descriptor List
182 if (result) {
183 tSDP_PROTO_LIST_ELEM add_proto_list;
184
185 add_proto_list.num_elems = 2;
186 add_proto_list.list_elem[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
187 add_proto_list.list_elem[0].num_params = 1;
188 add_proto_list.list_elem[0].params[0] = BT_PSM_HIDI;
189 add_proto_list.list_elem[1].protocol_uuid = UUID_PROTOCOL_HIDP;
190 add_proto_list.list_elem[1].num_params = 0;
191
192 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAdditionProtoLists(
193 handle, 1, &add_proto_list);
194 }
195
196 // Service Name (O)
197 // Service Description (O)
198 // Provider Name (O)
199 if (result) {
200 const char* srv_name = p_name;
201 const char* srv_desc = p_description;
202 const char* provider_name = p_provider;
203
204 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
205 handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, strlen(srv_name) + 1,
206 (uint8_t*)srv_name);
207
208 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
209 handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE,
210 strlen(srv_desc) + 1, (uint8_t*)srv_desc);
211
212 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
213 handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE,
214 strlen(provider_name) + 1, (uint8_t*)provider_name);
215 }
216
217 // Bluetooth Profile Descriptor List
218 if (result) {
219 const uint16_t profile_uuid = UUID_SERVCLASS_HUMAN_INTERFACE;
220 const uint16_t version = 0x0100;
221
222 result &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
223 handle, profile_uuid, version);
224 }
225
226 // HID Parser Version
227 if (result) {
228 uint8_t* p;
229 const uint16_t rel_num = 0x0100;
230 const uint16_t parser_version = 0x0111;
231 const uint16_t prof_ver = 0x0100;
232 const uint8_t dev_subclass = subclass;
233 const uint8_t country_code = 0x21;
234 const uint8_t bool_false = 0x00;
235 const uint8_t bool_true = 0x01;
236 uint16_t temp;
237
238 p = (uint8_t*)&temp;
239 UINT16_TO_BE_STREAM(p, rel_num);
240 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
241 handle, ATTR_ID_HID_DEVICE_RELNUM, UINT_DESC_TYPE, 2, (uint8_t*)&temp);
242
243 p = (uint8_t*)&temp;
244 UINT16_TO_BE_STREAM(p, parser_version);
245 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
246 handle, ATTR_ID_HID_PARSER_VERSION, UINT_DESC_TYPE, 2, (uint8_t*)&temp);
247
248 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
249 handle, ATTR_ID_HID_DEVICE_SUBCLASS, UINT_DESC_TYPE, 1,
250 (uint8_t*)&dev_subclass);
251
252 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
253 handle, ATTR_ID_HID_COUNTRY_CODE, UINT_DESC_TYPE, 1,
254 (uint8_t*)&country_code);
255
256 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
257 handle, ATTR_ID_HID_VIRTUAL_CABLE, BOOLEAN_DESC_TYPE, 1,
258 (uint8_t*)&bool_true);
259
260 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
261 handle, ATTR_ID_HID_RECONNECT_INITIATE, BOOLEAN_DESC_TYPE, 1,
262 (uint8_t*)&bool_true);
263
264 {
265 static uint8_t cdt = 0x22;
266 uint8_t* p_buf;
267 uint8_t seq_len = 4 + desc_len;
268
269 if (desc_len > HIDD_APP_DESCRIPTOR_LEN) {
270 log::error("descriptor length = {}, larger than max {}", desc_len,
271 HIDD_APP_DESCRIPTOR_LEN);
272 log_counter_metrics(
273 android::bluetooth::CodePathCounterKeyEnum::
274 HIDD_ERR_NOT_REGISTERED_DUE_TO_DESCRIPTOR_LENGTH,
275 1);
276 return HID_ERR_NOT_REGISTERED;
277 };
278
279 p_buf = (uint8_t*)osi_malloc(HIDD_APP_DESCRIPTOR_LEN + 6);
280
281 if (p_buf == NULL) {
282 log::error("Buffer allocation failure for size = 2048");
283 log_counter_metrics(
284 android::bluetooth::CodePathCounterKeyEnum::
285 HIDD_ERR_NOT_REGISTERED_DUE_TO_BUFFER_ALLOCATION,
286 1);
287 return HID_ERR_NOT_REGISTERED;
288 }
289
290 p = p_buf;
291
292 UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
293
294 UINT8_TO_BE_STREAM(p, seq_len);
295
296 UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
297 UINT8_TO_BE_STREAM(p, cdt);
298
299 UINT8_TO_BE_STREAM(p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
300 UINT8_TO_BE_STREAM(p, desc_len);
301 ARRAY_TO_BE_STREAM(p, p_desc_data, (int)desc_len);
302
303 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
304 handle, ATTR_ID_HID_DESCRIPTOR_LIST, DATA_ELE_SEQ_DESC_TYPE,
305 p - p_buf, p_buf);
306
307 osi_free(p_buf);
308 }
309
310 {
311 uint8_t lang_buf[8];
312 p = lang_buf;
313 uint8_t seq_len = 6;
314 uint16_t lang_english = 0x0409;
315 UINT8_TO_BE_STREAM(p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
316 UINT8_TO_BE_STREAM(p, seq_len);
317 UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
318 UINT16_TO_BE_STREAM(p, lang_english);
319 UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
320 UINT16_TO_BE_STREAM(p, LANGUAGE_BASE_ID);
321 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
322 handle, ATTR_ID_HID_LANGUAGE_ID_BASE, DATA_ELE_SEQ_DESC_TYPE,
323 p - lang_buf, lang_buf);
324 }
325
326 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
327 handle, ATTR_ID_HID_BATTERY_POWER, BOOLEAN_DESC_TYPE, 1,
328 (uint8_t*)&bool_true);
329
330 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
331 handle, ATTR_ID_HID_REMOTE_WAKE, BOOLEAN_DESC_TYPE, 1,
332 (uint8_t*)&bool_false);
333
334 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
335 handle, ATTR_ID_HID_NORMALLY_CONNECTABLE, BOOLEAN_DESC_TYPE, 1,
336 (uint8_t*)&bool_true);
337
338 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
339 handle, ATTR_ID_HID_BOOT_DEVICE, BOOLEAN_DESC_TYPE, 1,
340 (uint8_t*)&bool_true);
341
342 p = (uint8_t*)&temp;
343 UINT16_TO_BE_STREAM(p, prof_ver);
344 result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
345 handle, ATTR_ID_HID_PROFILE_VERSION, UINT_DESC_TYPE, 2,
346 (uint8_t*)&temp);
347 }
348
349 if (result) {
350 uint16_t browse_group = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
351 result &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
352 handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_group);
353 }
354
355 if (!result) {
356 log::error("failed to complete SDP record");
357 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
358 HIDD_ERR_NOT_REGISTERED_AT_SDP,
359 1);
360 return HID_ERR_NOT_REGISTERED;
361 }
362
363 return HID_SUCCESS;
364 }
365
366 /*******************************************************************************
367 *
368 * Function HID_DevSendReport
369 *
370 * Description Sends report
371 *
372 * Returns tHID_STATUS
373 *
374 ******************************************************************************/
HID_DevSendReport(uint8_t channel,uint8_t type,uint8_t id,uint16_t len,uint8_t * p_data)375 tHID_STATUS HID_DevSendReport(uint8_t channel, uint8_t type, uint8_t id,
376 uint16_t len, uint8_t* p_data) {
377 log::verbose("channel={} type={} id={} len={}", channel, type, id, len);
378
379 if (channel == HID_CHANNEL_CTRL) {
380 return hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA, type, id, len,
381 p_data);
382 }
383
384 if (channel == HID_CHANNEL_INTR && type == HID_PAR_REP_TYPE_INPUT) {
385 // on INTR we can only send INPUT
386 return hidd_conn_send_data(HID_CHANNEL_INTR, HID_TRANS_DATA,
387 HID_PAR_REP_TYPE_INPUT, id, len, p_data);
388 }
389 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
390 HIDD_ERR_INVALID_PARAM_SEND_REPORT,
391 1);
392 return HID_ERR_INVALID_PARAM;
393 }
394
395 /*******************************************************************************
396 *
397 * Function HID_DevVirtualCableUnplug
398 *
399 * Description Sends Virtual Cable Unplug
400 *
401 * Returns tHID_STATUS
402 *
403 ******************************************************************************/
HID_DevVirtualCableUnplug(void)404 tHID_STATUS HID_DevVirtualCableUnplug(void) {
405 log::verbose("");
406
407 return hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_CONTROL,
408 HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG, 0, 0, NULL);
409 }
410
411 /*******************************************************************************
412 *
413 * Function HID_DevPlugDevice
414 *
415 * Description Establishes virtual cable to given host
416 *
417 * Returns tHID_STATUS
418 *
419 ******************************************************************************/
HID_DevPlugDevice(const RawAddress & addr)420 tHID_STATUS HID_DevPlugDevice(const RawAddress& addr) {
421 hd_cb.device.in_use = TRUE;
422 hd_cb.device.addr = addr;
423
424 return HID_SUCCESS;
425 }
426
427 /*******************************************************************************
428 *
429 * Function HID_DevUnplugDevice
430 *
431 * Description Unplugs virtual cable from given host
432 *
433 * Returns tHID_STATUS
434 *
435 ******************************************************************************/
HID_DevUnplugDevice(const RawAddress & addr)436 tHID_STATUS HID_DevUnplugDevice(const RawAddress& addr) {
437 if (hd_cb.device.addr == addr) {
438 hd_cb.device.in_use = FALSE;
439 hd_cb.device.conn.conn_state = HID_CONN_STATE_UNUSED;
440 hd_cb.device.conn.ctrl_cid = 0;
441 hd_cb.device.conn.intr_cid = 0;
442 }
443
444 return HID_SUCCESS;
445 }
446
447 /*******************************************************************************
448 *
449 * Function HID_DevConnect
450 *
451 * Description Connects to device
452 *
453 * Returns tHID_STATUS
454 *
455 ******************************************************************************/
HID_DevConnect(void)456 tHID_STATUS HID_DevConnect(void) {
457 if (!hd_cb.reg_flag) {
458 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
459 HIDD_ERR_NOT_REGISTERED_AT_CONNECT,
460 1);
461 return HID_ERR_NOT_REGISTERED;
462 }
463
464 if (!hd_cb.device.in_use) {
465 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
466 HIDD_ERR_DEVICE_NOT_IN_USE_AT_CONNECT,
467 1);
468 return HID_ERR_INVALID_PARAM;
469 }
470
471 if (hd_cb.device.state != HIDD_DEV_NO_CONN) {
472 log_counter_metrics(
473 android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_ALREADY_CONN, 1);
474 return HID_ERR_ALREADY_CONN;
475 }
476
477 return hidd_conn_initiate();
478 }
479
480 /*******************************************************************************
481 *
482 * Function HID_DevDisconnect
483 *
484 * Description Disconnects from device
485 *
486 * Returns tHID_STATUS
487 *
488 ******************************************************************************/
HID_DevDisconnect(void)489 tHID_STATUS HID_DevDisconnect(void) {
490 if (!hd_cb.reg_flag) {
491 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
492 HIDD_ERR_NOT_REGISTERED_AT_DISCONNECT,
493 1);
494 return HID_ERR_NOT_REGISTERED;
495 }
496
497 if (!hd_cb.device.in_use) {
498 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
499 HIDD_ERR_DEVICE_NOT_IN_USE_AT_DISCONNECT,
500 1);
501 return HID_ERR_INVALID_PARAM;
502 }
503
504 if (hd_cb.device.state == HIDD_DEV_NO_CONN) {
505 /* If we are still trying to connect, just close the connection. */
506 if (hd_cb.device.conn.conn_state != HID_CONN_STATE_UNUSED) {
507 tHID_STATUS ret = hidd_conn_disconnect();
508 hd_cb.device.conn.conn_state = HID_CONN_STATE_UNUSED;
509 hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE,
510 HID_ERR_DISCONNECTING, NULL);
511 log_counter_metrics(
512 android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_DISCONNECTING,
513 1);
514 return ret;
515 }
516 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
517 HIDD_ERR_NO_CONNECTION_AT_DISCONNECT,
518 1);
519 return HID_ERR_NO_CONNECTION;
520 }
521
522 return hidd_conn_disconnect();
523 }
524
525 /*******************************************************************************
526 *
527 * Function HID_DevSetIncomingPolicy
528 *
529 * Description Sets policy for incoming connections (allowed/disallowed)
530 *
531 * Returns tHID_STATUS
532 *
533 ******************************************************************************/
HID_DevSetIncomingPolicy(bool allow)534 tHID_STATUS HID_DevSetIncomingPolicy(bool allow) {
535 hd_cb.allow_incoming = allow;
536
537 return HID_SUCCESS;
538 }
539
540 /*******************************************************************************
541 *
542 * Function HID_DevReportError
543 *
544 * Description Reports error for Set Report via HANDSHAKE
545 *
546 * Returns tHID_STATUS
547 *
548 ******************************************************************************/
HID_DevReportError(uint8_t error)549 tHID_STATUS HID_DevReportError(uint8_t error) {
550 uint8_t handshake_param;
551
552 log::verbose("error = {}", error);
553
554 switch (error) {
555 case HID_PAR_HANDSHAKE_RSP_SUCCESS:
556 case HID_PAR_HANDSHAKE_RSP_NOT_READY:
557 case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_REP_ID:
558 case HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ:
559 case HID_PAR_HANDSHAKE_RSP_ERR_INVALID_PARAM:
560 case HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN:
561 case HID_PAR_HANDSHAKE_RSP_ERR_FATAL:
562 handshake_param = error;
563 break;
564 default:
565 handshake_param = HID_PAR_HANDSHAKE_RSP_ERR_UNKNOWN;
566 break;
567 }
568
569 return hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, handshake_param, 0, 0,
570 NULL);
571 }
572
573 /*******************************************************************************
574 *
575 * Function HID_DevGetDevice
576 *
577 * Description Returns the BD Address of virtually cabled device
578 *
579 * Returns tHID_STATUS
580 *
581 ******************************************************************************/
HID_DevGetDevice(RawAddress * addr)582 tHID_STATUS HID_DevGetDevice(RawAddress* addr) {
583 log::verbose("");
584
585 if (hd_cb.device.in_use) {
586 *addr = hd_cb.device.addr;
587 } else {
588 log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum::
589 HIDD_ERR_NOT_REGISTERED_AT_GET_DEVICE,
590 1);
591 return HID_ERR_NOT_REGISTERED;
592 }
593
594 return HID_SUCCESS;
595 }
596
597 /*******************************************************************************
598 *
599 * Function HID_DevSetIncomingQos
600 *
601 * Description Sets Incoming QoS values for Interrupt L2CAP Channel
602 *
603 * Returns tHID_STATUS
604 *
605 ******************************************************************************/
HID_DevSetIncomingQos(uint8_t service_type,uint32_t token_rate,uint32_t token_bucket_size,uint32_t peak_bandwidth,uint32_t latency,uint32_t delay_variation)606 tHID_STATUS HID_DevSetIncomingQos(uint8_t service_type, uint32_t token_rate,
607 uint32_t token_bucket_size,
608 uint32_t peak_bandwidth, uint32_t latency,
609 uint32_t delay_variation) {
610 log::verbose("");
611
612 hd_cb.use_in_qos = TRUE;
613
614 hd_cb.in_qos.service_type = service_type;
615 hd_cb.in_qos.token_rate = token_rate;
616 hd_cb.in_qos.token_bucket_size = token_bucket_size;
617 hd_cb.in_qos.peak_bandwidth = peak_bandwidth;
618 hd_cb.in_qos.latency = latency;
619 hd_cb.in_qos.delay_variation = delay_variation;
620
621 return HID_SUCCESS;
622 }
623
624 /*******************************************************************************
625 *
626 * Function HID_DevSetOutgoingQos
627 *
628 * Description Sets Outgoing QoS values for Interrupt L2CAP Channel
629 *
630 * Returns tHID_STATUS
631 *
632 ******************************************************************************/
HID_DevSetOutgoingQos(uint8_t service_type,uint32_t token_rate,uint32_t token_bucket_size,uint32_t peak_bandwidth,uint32_t latency,uint32_t delay_variation)633 tHID_STATUS HID_DevSetOutgoingQos(uint8_t service_type, uint32_t token_rate,
634 uint32_t token_bucket_size,
635 uint32_t peak_bandwidth, uint32_t latency,
636 uint32_t delay_variation) {
637 log::verbose("");
638
639 hd_cb.l2cap_intr_cfg.qos_present = TRUE;
640
641 hd_cb.l2cap_intr_cfg.qos.service_type = service_type;
642 hd_cb.l2cap_intr_cfg.qos.token_rate = token_rate;
643 hd_cb.l2cap_intr_cfg.qos.token_bucket_size = token_bucket_size;
644 hd_cb.l2cap_intr_cfg.qos.peak_bandwidth = peak_bandwidth;
645 hd_cb.l2cap_intr_cfg.qos.latency = latency;
646 hd_cb.l2cap_intr_cfg.qos.delay_variation = delay_variation;
647
648 return HID_SUCCESS;
649 }
650