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