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