hidh_api.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2002-2012 Broadcom Corporation
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. /******************************************************************************
  19. *
  20. * This file contains the HID HOST API entry points
  21. *
  22. ******************************************************************************/
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include "common/bt_target.h"
  27. #include "osi/allocator.h"
  28. #include "stack/bt_types.h"
  29. #include "stack/hiddefs.h"
  30. #include "stack/hidh_api.h"
  31. #include "hid_int.h"
  32. #include "stack/btm_api.h"
  33. #include "stack/btu.h"
  34. #include "btm_int.h"
  35. #if (HID_HOST_INCLUDED == TRUE)
  36. #if HID_DYNAMIC_MEMORY == FALSE
  37. tHID_HOST_CTB hh_cb;
  38. #else
  39. tHID_HOST_CTB *hidh_cb_ptr = NULL;
  40. #endif
  41. static void hidh_search_callback (UINT16 sdp_result);
  42. /*******************************************************************************
  43. **
  44. ** Function HID_HostGetSDPRecord
  45. **
  46. ** Description This function reads the device SDP record
  47. **
  48. ** Returns tHID_STATUS
  49. **
  50. *******************************************************************************/
  51. tHID_STATUS HID_HostGetSDPRecord ( BD_ADDR addr, tSDP_DISCOVERY_DB *p_db, UINT32 db_len,
  52. tHID_HOST_SDP_CALLBACK *sdp_cback )
  53. {
  54. tSDP_UUID uuid_list;
  55. if ( hh_cb.sdp_busy ) {
  56. return HID_ERR_SDP_BUSY;
  57. }
  58. uuid_list.len = 2;
  59. uuid_list.uu.uuid16 = UUID_SERVCLASS_HUMAN_INTERFACE;
  60. hh_cb.p_sdp_db = p_db;
  61. SDP_InitDiscoveryDb (p_db, db_len, 1, &uuid_list, 0, NULL);
  62. if (SDP_ServiceSearchRequest (addr, p_db, hidh_search_callback)) {
  63. hh_cb.sdp_cback = sdp_cback ;
  64. hh_cb.sdp_busy = TRUE;
  65. return HID_SUCCESS;
  66. } else {
  67. return HID_ERR_NO_RESOURCES;
  68. }
  69. }
  70. void hidh_get_str_attr( tSDP_DISC_REC *p_rec, UINT16 attr_id, UINT16 max_len, char *str )
  71. {
  72. tSDP_DISC_ATTR *p_attr;
  73. UINT16 name_len;
  74. if ((p_attr = SDP_FindAttributeInRec(p_rec, attr_id)) != NULL) {
  75. if ((name_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type)) < max_len ) {
  76. memcpy( str, (char *) p_attr->attr_value.v.array, name_len );
  77. str[name_len] = '\0';
  78. } else {
  79. memcpy( str, (char *) p_attr->attr_value.v.array, max_len - 1 );
  80. str[max_len - 1] = '\0';
  81. }
  82. } else {
  83. str[0] = '\0';
  84. }
  85. }
  86. static void hidh_search_callback (UINT16 sdp_result)
  87. {
  88. tSDP_DISCOVERY_DB *p_db = hh_cb.p_sdp_db;
  89. tSDP_DISC_REC *p_rec;
  90. tSDP_DISC_ATTR *p_attr, *p_subattr1, *p_subattr2, *p_repdesc;
  91. tBT_UUID hid_uuid;
  92. tHID_DEV_SDP_INFO *p_nvi = &hh_cb.sdp_rec;
  93. UINT16 attr_mask = 0;
  94. hid_uuid.len = LEN_UUID_16;
  95. hid_uuid.uu.uuid16 = UUID_SERVCLASS_HUMAN_INTERFACE;
  96. hh_cb.sdp_busy = FALSE;
  97. if (sdp_result != SDP_SUCCESS) {
  98. hh_cb.sdp_cback(sdp_result, 0, NULL);
  99. return;
  100. }
  101. if ((p_rec = SDP_FindServiceUUIDInDb (p_db, &hid_uuid, NULL)) == NULL) {
  102. hh_cb.sdp_cback(HID_SDP_NO_SERV_UUID, 0, NULL);
  103. return;
  104. }
  105. memset (&hh_cb.sdp_rec, 0, sizeof( tHID_DEV_SDP_INFO ));
  106. /* First, verify the mandatory fields we care about */
  107. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DESCRIPTOR_LIST)) == NULL)
  108. || (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE)
  109. || ((p_subattr1 = p_attr->attr_value.v.p_sub_attr) == NULL)
  110. || (SDP_DISC_ATTR_TYPE(p_subattr1->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE)
  111. || ((p_subattr2 = p_subattr1->attr_value.v.p_sub_attr) == NULL)
  112. || ((p_repdesc = p_subattr2->p_next_attr) == NULL)
  113. || (SDP_DISC_ATTR_TYPE(p_repdesc->attr_len_type) != TEXT_STR_DESC_TYPE)) {
  114. hh_cb.sdp_cback(HID_SDP_MANDATORY_MISSING, 0, NULL);
  115. return;
  116. }
  117. if ((p_nvi->dscp_info.dl_len = SDP_DISC_ATTR_LEN(p_repdesc->attr_len_type)) != 0) {
  118. p_nvi->dscp_info.dsc_list = (UINT8 *) &p_repdesc->attr_value;
  119. }
  120. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_VIRTUAL_CABLE)) != NULL) &&
  121. (p_attr->attr_value.v.u8) ) {
  122. attr_mask |= HID_VIRTUAL_CABLE;
  123. }
  124. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_RECONNECT_INITIATE)) != NULL) &&
  125. (p_attr->attr_value.v.u8) ) {
  126. attr_mask |= HID_RECONN_INIT;
  127. }
  128. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_NORMALLY_CONNECTABLE)) != NULL) &&
  129. (p_attr->attr_value.v.u8) ) {
  130. attr_mask |= HID_NORMALLY_CONNECTABLE;
  131. }
  132. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SDP_DISABLE)) != NULL) &&
  133. (p_attr->attr_value.v.u8) ) {
  134. attr_mask |= HID_SDP_DISABLE;
  135. }
  136. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_BATTERY_POWER)) != NULL) &&
  137. (p_attr->attr_value.v.u8) ) {
  138. attr_mask |= HID_BATTERY_POWER;
  139. }
  140. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_REMOTE_WAKE)) != NULL) &&
  141. (p_attr->attr_value.v.u8) ) {
  142. attr_mask |= HID_REMOTE_WAKE;
  143. }
  144. hidh_get_str_attr( p_rec, ATTR_ID_SERVICE_NAME, HID_MAX_SVC_NAME_LEN, p_nvi->svc_name );
  145. hidh_get_str_attr( p_rec, ATTR_ID_SERVICE_DESCRIPTION, HID_MAX_SVC_DESCR_LEN, p_nvi->svc_descr );
  146. hidh_get_str_attr( p_rec, ATTR_ID_PROVIDER_NAME, HID_MAX_PROV_NAME_LEN, p_nvi->prov_name );
  147. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DEVICE_RELNUM)) != NULL)) {
  148. p_nvi->rel_num = p_attr->attr_value.v.u16;
  149. }
  150. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_COUNTRY_CODE)) != NULL)) {
  151. p_nvi->ctry_code = p_attr->attr_value.v.u8;
  152. }
  153. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DEVICE_SUBCLASS)) != NULL)) {
  154. p_nvi->sub_class = p_attr->attr_value.v.u8;
  155. }
  156. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_PARSER_VERSION)) != NULL)) {
  157. p_nvi->hpars_ver = p_attr->attr_value.v.u16;
  158. }
  159. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_LINK_SUPERVISION_TO)) != NULL)) {
  160. attr_mask |= HID_SUP_TOUT_AVLBL;
  161. p_nvi->sup_timeout = p_attr->attr_value.v.u16;
  162. }
  163. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SSR_HOST_MAX_LAT)) != NULL)) {
  164. attr_mask |= HID_SSR_MAX_LATENCY;
  165. p_nvi->ssr_max_latency = p_attr->attr_value.v.u16;
  166. } else {
  167. p_nvi->ssr_max_latency = HID_SSR_PARAM_INVALID;
  168. }
  169. if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SSR_HOST_MIN_TOUT)) != NULL)) {
  170. attr_mask |= HID_SSR_MIN_TOUT;
  171. p_nvi->ssr_min_tout = p_attr->attr_value.v.u16;
  172. } else {
  173. p_nvi->ssr_min_tout = HID_SSR_PARAM_INVALID;
  174. }
  175. hh_cb.sdp_rec.p_sdp_layer_rec = p_rec;
  176. hh_cb.sdp_cback(SDP_SUCCESS, attr_mask, &hh_cb.sdp_rec);
  177. }
  178. /*******************************************************************************
  179. **
  180. ** Function HID_HostInit
  181. **
  182. ** Description This function initializes the control block and trace variable
  183. **
  184. ** Returns tHID_STATUS
  185. **
  186. *******************************************************************************/
  187. tHID_STATUS HID_HostInit (void)
  188. {
  189. #if (HID_DYNAMIC_MEMORY)
  190. if (!hidh_cb_ptr) {
  191. hidh_cb_ptr = (tHID_HOST_CTB *)osi_malloc(sizeof(tHID_HOST_CTB));
  192. if (!hidh_cb_ptr) {
  193. return HID_ERR_NO_RESOURCES;
  194. }
  195. }
  196. #endif /* #if (HID_DYNAMIC_MEMORY) */
  197. memset(&hh_cb, 0, sizeof(tHID_HOST_CTB));
  198. #if defined(HIDH_INITIAL_TRACE_LEVEL)
  199. hh_cb.trace_level = HIDH_INITIAL_TRACE_LEVEL;
  200. #else
  201. hh_cb.trace_level = BT_TRACE_LEVEL_NONE;
  202. #endif
  203. return HID_SUCCESS;
  204. }
  205. /*******************************************************************************
  206. **
  207. ** Function HID_HostInit
  208. **
  209. ** Description This function deinitializes the control block
  210. **
  211. ** Returns void
  212. **
  213. *******************************************************************************/
  214. void HID_HostDeinit (void)
  215. {
  216. #if (HID_DYNAMIC_MEMORY)
  217. if (hidh_cb_ptr) {
  218. osi_free(hidh_cb_ptr);
  219. hidh_cb_ptr = NULL;
  220. }
  221. #endif /* #if (HID_DYNAMIC_MEMORY) */
  222. }
  223. /*******************************************************************************
  224. **
  225. ** Function HID_HostSetTraceLevel
  226. **
  227. ** Description This function sets the trace level for HID Host. If called with
  228. ** a value of 0xFF, it simply reads the current trace level.
  229. **
  230. ** Returns the new (current) trace level
  231. **
  232. *******************************************************************************/
  233. UINT8 HID_HostSetTraceLevel (UINT8 new_level)
  234. {
  235. if (new_level != 0xFF) {
  236. hh_cb.trace_level = new_level;
  237. }
  238. return (hh_cb.trace_level);
  239. }
  240. /*******************************************************************************
  241. **
  242. ** Function HID_HostRegister
  243. **
  244. ** Description This function registers HID-Host with lower layers
  245. **
  246. ** Returns tHID_STATUS
  247. **
  248. *******************************************************************************/
  249. tHID_STATUS HID_HostRegister (tHID_HOST_DEV_CALLBACK *dev_cback)
  250. {
  251. tHID_STATUS st;
  252. if ( hh_cb.reg_flag ) {
  253. return HID_ERR_ALREADY_REGISTERED;
  254. }
  255. if ( dev_cback == NULL ) {
  256. return HID_ERR_INVALID_PARAM;
  257. }
  258. /* Register with L2CAP */
  259. if ( (st = hidh_conn_reg()) != HID_SUCCESS ) {
  260. return st;
  261. }
  262. hh_cb.callback = dev_cback ;
  263. hh_cb.reg_flag = TRUE;
  264. return (HID_SUCCESS);
  265. }
  266. /*******************************************************************************
  267. **
  268. ** Function HID_HostDeregister
  269. **
  270. ** Description This function is called when the host is about power down.
  271. **
  272. ** Returns tHID_STATUS
  273. **
  274. *******************************************************************************/
  275. tHID_STATUS HID_HostDeregister(void)
  276. {
  277. UINT8 i;
  278. if ( !hh_cb.reg_flag ) {
  279. return (HID_ERR_NOT_REGISTERED);
  280. }
  281. for ( i = 0; i < HID_HOST_MAX_DEVICES; i++ ) {
  282. HID_HostRemoveDev( i ) ;
  283. }
  284. hidh_conn_dereg();
  285. hh_cb.reg_flag = FALSE;
  286. return (HID_SUCCESS) ;
  287. }
  288. /*******************************************************************************
  289. **
  290. ** Function HID_HostAddDev
  291. **
  292. ** Description This is called so HID-host may manage this device.
  293. **
  294. ** Returns tHID_STATUS
  295. **
  296. *******************************************************************************/
  297. tHID_STATUS HID_HostAddDev ( BD_ADDR addr, UINT16 attr_mask, UINT8 *handle )
  298. {
  299. int i;
  300. /* Find an entry for this device in hh_cb.devices array */
  301. if ( !hh_cb.reg_flag ) {
  302. return (HID_ERR_NOT_REGISTERED);
  303. }
  304. for ( i = 0; i < HID_HOST_MAX_DEVICES; i++) {
  305. if ((hh_cb.devices[i].in_use) &&
  306. (!memcmp(addr, hh_cb.devices[i].addr, BD_ADDR_LEN))) {
  307. break;
  308. }
  309. }
  310. if (i == HID_HOST_MAX_DEVICES ) {
  311. for ( i = 0; i < HID_HOST_MAX_DEVICES; i++) {
  312. if ( !hh_cb.devices[i].in_use) {
  313. break;
  314. }
  315. }
  316. }
  317. if ( i == HID_HOST_MAX_DEVICES ) {
  318. return HID_ERR_NO_RESOURCES;
  319. }
  320. if (!hh_cb.devices[i].in_use) {
  321. hh_cb.devices[i].in_use = TRUE;
  322. memcpy( hh_cb.devices[i].addr, addr, sizeof( BD_ADDR ) ) ;
  323. hh_cb.devices[i].state = HID_DEV_NO_CONN;
  324. hh_cb.devices[i].conn_tries = 0 ;
  325. }
  326. if (attr_mask != HID_ATTR_MASK_IGNORE) {
  327. hh_cb.devices[i].attr_mask = attr_mask;
  328. }
  329. *handle = i;
  330. return (HID_SUCCESS);
  331. }
  332. /*******************************************************************************
  333. **
  334. ** Function HID_HostGetDev
  335. **
  336. ** Description This is called so HID-host can find this device.
  337. **
  338. ** Returns tHID_STATUS
  339. **
  340. *******************************************************************************/
  341. tHID_STATUS HID_HostGetDev(BD_ADDR addr, UINT8 *handle)
  342. {
  343. int i;
  344. /* Find an entry for this device in hh_cb.devices array */
  345. if (!hh_cb.reg_flag) {
  346. return (HID_ERR_NOT_REGISTERED);
  347. }
  348. for (i = 0; i < HID_HOST_MAX_DEVICES; i++) {
  349. if ((hh_cb.devices[i].in_use) && (!memcmp(addr, hh_cb.devices[i].addr, BD_ADDR_LEN))) {
  350. break;
  351. }
  352. }
  353. if (i == HID_HOST_MAX_DEVICES) {
  354. *handle = 0xff;
  355. } else {
  356. *handle = i;
  357. }
  358. return (HID_SUCCESS);
  359. }
  360. /*******************************************************************************
  361. **
  362. ** Function HID_HostRemoveDev
  363. **
  364. ** Description This removes the device from list devices that host has to manage.
  365. **
  366. ** Returns tHID_STATUS
  367. **
  368. *******************************************************************************/
  369. tHID_STATUS HID_HostRemoveDev ( UINT8 dev_handle )
  370. {
  371. if ( !hh_cb.reg_flag ) {
  372. return (HID_ERR_NOT_REGISTERED);
  373. }
  374. if ( (dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) ) {
  375. return HID_ERR_INVALID_PARAM;
  376. }
  377. HID_HostCloseDev( dev_handle ) ;
  378. hh_cb.devices[dev_handle].in_use = FALSE;
  379. hh_cb.devices[dev_handle].conn.conn_state = HID_CONN_STATE_UNUSED;
  380. hh_cb.devices[dev_handle].conn.ctrl_cid = hh_cb.devices[dev_handle].conn.intr_cid = 0;
  381. hh_cb.devices[dev_handle].attr_mask = 0;
  382. return HID_SUCCESS;
  383. }
  384. /*******************************************************************************
  385. **
  386. ** Function HID_HostOpenDev
  387. **
  388. ** Description This function is called when the user wants to initiate a
  389. ** connection attempt to a device.
  390. **
  391. ** Returns void
  392. **
  393. *******************************************************************************/
  394. tHID_STATUS HID_HostOpenDev ( UINT8 dev_handle )
  395. {
  396. if ( !hh_cb.reg_flag ) {
  397. return (HID_ERR_NOT_REGISTERED);
  398. }
  399. if ( (dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) ) {
  400. return HID_ERR_INVALID_PARAM;
  401. }
  402. if ( hh_cb.devices[dev_handle].state != HID_DEV_NO_CONN ) {
  403. return HID_ERR_ALREADY_CONN;
  404. }
  405. hh_cb.devices[dev_handle].conn_tries = 1;
  406. return hidh_conn_initiate( dev_handle );
  407. }
  408. /*******************************************************************************
  409. **
  410. ** Function HID_HostWriteDev
  411. **
  412. ** Description This function is called when the host has a report to send.
  413. **
  414. ** report_id: is only used on GET_REPORT transaction if is specified.
  415. ** only valid when it's a non-zero value.
  416. **
  417. ** Returns void
  418. **
  419. *******************************************************************************/
  420. tHID_STATUS HID_HostWriteDev( UINT8 dev_handle, UINT8 t_type,
  421. UINT8 param, UINT16 data, UINT8 report_id, BT_HDR *pbuf )
  422. {
  423. tHID_STATUS status = HID_SUCCESS;
  424. if ( !hh_cb.reg_flag ) {
  425. HIDH_TRACE_ERROR("HID_ERR_NOT_REGISTERED");
  426. status = HID_ERR_NOT_REGISTERED;
  427. }
  428. if ( (dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) ) {
  429. HIDH_TRACE_ERROR("HID_ERR_INVALID_PARAM");
  430. status = HID_ERR_INVALID_PARAM;
  431. }
  432. else if ( hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED ) {
  433. HIDH_TRACE_ERROR("HID_ERR_NO_CONNECTION dev_handle %d", dev_handle);
  434. status = HID_ERR_NO_CONNECTION;
  435. }
  436. if (status != HID_SUCCESS) {
  437. if (pbuf) {
  438. osi_free ((void *)pbuf);
  439. }
  440. } else {
  441. status = hidh_conn_snd_data( dev_handle, t_type, param, data, report_id, pbuf ) ;
  442. }
  443. return status;
  444. }
  445. /*******************************************************************************
  446. **
  447. ** Function HID_HostCloseDev
  448. **
  449. ** Description This function disconnects the device.
  450. **
  451. ** Returns void
  452. **
  453. *******************************************************************************/
  454. tHID_STATUS HID_HostCloseDev( UINT8 dev_handle )
  455. {
  456. if ( !hh_cb.reg_flag ) {
  457. return (HID_ERR_NOT_REGISTERED);
  458. }
  459. if ( (dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) ) {
  460. return HID_ERR_INVALID_PARAM;
  461. }
  462. hh_cb.devices[dev_handle].conn_tries = HID_HOST_MAX_CONN_RETRY + 1;
  463. btu_stop_timer( &(hh_cb.devices[dev_handle].conn.timer_entry) ) ;
  464. if ( hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED ) {
  465. return HID_ERR_NO_CONNECTION;
  466. }
  467. hh_cb.devices[dev_handle].conn_tries = HID_HOST_MAX_CONN_RETRY + 1;
  468. return hidh_conn_disconnect( dev_handle );
  469. }
  470. tHID_STATUS HID_HostSetSecurityLevel( char serv_name[], UINT8 sec_lvl )
  471. {
  472. if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HIDH_SEC_CTRL,
  473. sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_SEC_CHN)) {
  474. HIDH_TRACE_ERROR ("Security Registration 1 failed");
  475. return (HID_ERR_NO_RESOURCES);
  476. }
  477. if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HIDH_SEC_CTRL,
  478. sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_SEC_CHN)) {
  479. HIDH_TRACE_ERROR ("Security Registration 2 failed");
  480. return (HID_ERR_NO_RESOURCES);
  481. }
  482. if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HIDH_NOSEC_CTRL,
  483. BTM_SEC_NONE, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_NOSEC_CHN)) {
  484. HIDH_TRACE_ERROR ("Security Registration 3 failed");
  485. return (HID_ERR_NO_RESOURCES);
  486. }
  487. if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HIDH_NOSEC_CTRL,
  488. BTM_SEC_NONE, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_NOSEC_CHN)) {
  489. HIDH_TRACE_ERROR ("Security Registration 4 failed");
  490. return (HID_ERR_NO_RESOURCES);
  491. }
  492. if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HIDH_INTR,
  493. BTM_SEC_NONE, HID_PSM_INTERRUPT, BTM_SEC_PROTO_HID, 0)) {
  494. HIDH_TRACE_ERROR ("Security Registration 5 failed");
  495. return (HID_ERR_NO_RESOURCES);
  496. }
  497. if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HIDH_INTR,
  498. BTM_SEC_NONE, HID_PSM_INTERRUPT, BTM_SEC_PROTO_HID, 0)) {
  499. HIDH_TRACE_ERROR ("Security Registration 6 failed");
  500. return (HID_ERR_NO_RESOURCES);
  501. }
  502. return ( HID_SUCCESS );
  503. }
  504. /******************************************************************************
  505. **
  506. ** Function hid_known_hid_device
  507. **
  508. ** Description check if this device is of type HID Device
  509. **
  510. ** Returns TRUE if device is HID Device else FALSE
  511. **
  512. *******************************************************************************/
  513. BOOLEAN hid_known_hid_device (BD_ADDR bd_addr)
  514. {
  515. UINT8 i;
  516. tBTM_INQ_INFO *p_inq_info = BTM_InqDbRead(bd_addr);
  517. if ( !hh_cb.reg_flag ) {
  518. return FALSE;
  519. }
  520. /* First check for class of device , if Inq DB has information about this device*/
  521. if (p_inq_info != NULL) {
  522. /* Check if remote major device class is of type BTM_COD_MAJOR_PERIPHERAL */
  523. if ((p_inq_info->results.dev_class[1] & BTM_COD_MAJOR_CLASS_MASK)
  524. == BTM_COD_MAJOR_PERIPHERAL ) {
  525. HIDH_TRACE_DEBUG("hid_known_hid_device:dev found in InqDB & COD matches HID dev");
  526. return TRUE;
  527. }
  528. } else {
  529. /* Look for this device in security device DB */
  530. tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
  531. if ((p_dev_rec != NULL) &&
  532. ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) == BTM_COD_MAJOR_PERIPHERAL )) {
  533. HIDH_TRACE_DEBUG("hid_known_hid_device:dev found in SecDevDB & COD matches HID dev");
  534. return TRUE;
  535. }
  536. }
  537. /* Find an entry for this device in hh_cb.devices array */
  538. for ( i = 0; i < HID_HOST_MAX_DEVICES; i++) {
  539. if ((hh_cb.devices[i].in_use) &&
  540. (memcmp(bd_addr, hh_cb.devices[i].addr, BD_ADDR_LEN) == 0)) {
  541. return TRUE;
  542. }
  543. }
  544. /* Check if this device is marked as HID Device in IOP Dev */
  545. HIDH_TRACE_DEBUG("hid_known_hid_device:remote is not HID device");
  546. return FALSE;
  547. }
  548. #endif //HID_HOST_INCLUDED