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