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