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