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