hidd_api.cc 20 KB

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