/******************************************************************************* ** ** Function btm_dev_support_switch ** ** Description This function is called by the L2CAP to check if remote ** device supports role switch ** ** Parameters: bd_addr - Address of the peer device ** ** Returns TRUE if device is known and role switch is supported ** *******************************************************************************/ BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr) { tBTM_SEC_DEV_REC *p_dev_rec; UINT8 xx; BOOLEAN feature_empty = TRUE; #if BTM_SCO_INCLUDED == TRUE /* Role switch is not allowed if a SCO is up */ if (btm_is_sco_active_by_bdaddr(bd_addr)) return(FALSE); #endif p_dev_rec = btm_find_dev (bd_addr); if (p_dev_rec && HCI_SWITCH_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0])) { if (HCI_SWITCH_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0])) { BTM_TRACE_DEBUG0("btm_dev_support_switch return TRUE (feature found)"); return (TRUE); } /* If the feature field is all zero, we never received them */ for (xx = 0 ; xx < BD_FEATURES_LEN ; xx++) { if (p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0][xx] != 0x00) { feature_empty = FALSE; /* at least one is != 0 */ break; } } /* If we don't know peer's capabilities, assume it supports Role-switch */ if (feature_empty) { BTM_TRACE_DEBUG0("btm_dev_support_switch return TRUE (feature empty)"); return (TRUE); } } BTM_TRACE_DEBUG0("btm_dev_support_switch return FALSE"); return(FALSE); }
/******************************************************************************* ** ** Function btm_decode_ext_features_page ** ** Description This function is decodes a features page. ** ** Returns void ** *******************************************************************************/ static void btm_decode_ext_features_page (UINT8 page_number, const UINT8 *p_features) { BTM_TRACE_DEBUG ("btm_decode_ext_features_page page: %d", page_number); switch (page_number) { /* Extended (Legacy) Page 0 */ case HCI_EXT_FEATURES_PAGE_0: /* Create ACL supported packet types mask */ btm_cb.btm_acl_pkt_types_supported = (BTM_ACL_PKT_TYPES_MASK_DH1 + BTM_ACL_PKT_TYPES_MASK_DM1); if (HCI_3_SLOT_PACKETS_SUPPORTED(p_features)) btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3); if (HCI_5_SLOT_PACKETS_SUPPORTED(p_features)) btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5); /* Add in EDR related ACL types */ if (!HCI_EDR_ACL_2MPS_SUPPORTED(p_features)) { btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 + BTM_ACL_PKT_TYPES_MASK_NO_2_DH5); } if (!HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) { btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH5); } /* Check to see if 3 and 5 slot packets are available */ if (HCI_EDR_ACL_2MPS_SUPPORTED(p_features) || HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) { if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(p_features)) btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3); if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(p_features)) btm_cb.btm_acl_pkt_types_supported |= (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH5); } BTM_TRACE_DEBUG("Local supported ACL packet types: 0x%04x", btm_cb.btm_acl_pkt_types_supported); /* Create (e)SCO supported packet types mask */ btm_cb.btm_sco_pkt_types_supported = 0; #if BTM_SCO_INCLUDED == TRUE btm_cb.sco_cb.esco_supported = FALSE; #endif if (HCI_SCO_LINK_SUPPORTED(p_features)) { btm_cb.btm_sco_pkt_types_supported = BTM_SCO_PKT_TYPES_MASK_HV1; if (HCI_HV2_PACKETS_SUPPORTED(p_features)) btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_HV2; if (HCI_HV3_PACKETS_SUPPORTED(p_features)) btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_HV3; } if (HCI_ESCO_EV3_SUPPORTED(p_features)) btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_EV3; if (HCI_ESCO_EV4_SUPPORTED(p_features)) btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_EV4; if (HCI_ESCO_EV5_SUPPORTED(p_features)) btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_EV5; #if BTM_SCO_INCLUDED == TRUE if (btm_cb.btm_sco_pkt_types_supported & BTM_ESCO_LINK_ONLY_MASK) { btm_cb.sco_cb.esco_supported = TRUE; /* Add in EDR related eSCO types */ if (HCI_EDR_ESCO_2MPS_SUPPORTED(p_features)) { if (!HCI_3_SLOT_EDR_ESCO_SUPPORTED(p_features)) btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_NO_2_EV5; } else { btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 + BTM_SCO_PKT_TYPES_MASK_NO_2_EV5); } if (HCI_EDR_ESCO_3MPS_SUPPORTED(p_features)) { if (!HCI_3_SLOT_EDR_ESCO_SUPPORTED(p_features)) btm_cb.btm_sco_pkt_types_supported |= BTM_SCO_PKT_TYPES_MASK_NO_3_EV5; } else { btm_cb.btm_sco_pkt_types_supported |= (BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 + BTM_SCO_PKT_TYPES_MASK_NO_3_EV5); } } #endif BTM_TRACE_DEBUG("Local supported SCO packet types: 0x%04x", btm_cb.btm_sco_pkt_types_supported); /* Create Default Policy Settings */ if (HCI_SWITCH_SUPPORTED(p_features)) btm_cb.btm_def_link_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH; else btm_cb.btm_def_link_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH; if (HCI_HOLD_MODE_SUPPORTED(p_features)) btm_cb.btm_def_link_policy |= HCI_ENABLE_HOLD_MODE; else btm_cb.btm_def_link_policy &= ~HCI_ENABLE_HOLD_MODE; if (HCI_SNIFF_MODE_SUPPORTED(p_features)) btm_cb.btm_def_link_policy |= HCI_ENABLE_SNIFF_MODE; else btm_cb.btm_def_link_policy &= ~HCI_ENABLE_SNIFF_MODE; if (HCI_PARK_MODE_SUPPORTED(p_features)) btm_cb.btm_def_link_policy |= HCI_ENABLE_PARK_MODE; else btm_cb.btm_def_link_policy &= ~HCI_ENABLE_PARK_MODE; btm_sec_dev_reset (); if (HCI_LMP_INQ_RSSI_SUPPORTED(p_features)) { if (HCI_EXT_INQ_RSP_SUPPORTED(p_features)) BTM_SetInquiryMode (BTM_INQ_RESULT_EXTENDED); else BTM_SetInquiryMode (BTM_INQ_RESULT_WITH_RSSI); } #if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE if( HCI_NON_FLUSHABLE_PB_SUPPORTED(p_features)) l2cu_set_non_flushable_pbf(TRUE); else l2cu_set_non_flushable_pbf(FALSE); #endif BTM_SetPageScanType (BTM_DEFAULT_SCAN_TYPE); BTM_SetInquiryScanType (BTM_DEFAULT_SCAN_TYPE); break; /* Extended Page 1 */ case HCI_EXT_FEATURES_PAGE_1: /* Nothing to do for page 1 */ break; /* Extended Page 2 */ case HCI_EXT_FEATURES_PAGE_2: /* Nothing to do for page 2 */ break; default: BTM_TRACE_ERROR("btm_decode_ext_features_page page=%d unknown", page_number); break; } }