/******************************************************************************* ** ** Function bta_ag_disc_int_res ** ** Description This function handles a discovery result when initiator. ** ** ** Returns void ** *******************************************************************************/ void bta_ag_disc_int_res(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) { UINT16 event = BTA_AG_DISC_FAIL_EVT; APPL_TRACE_DEBUG ("bta_ag_disc_int_res: Status: %d", p_data->disc_result.status); /* if found service */ if (p_data->disc_result.status == SDP_SUCCESS || p_data->disc_result.status == SDP_DB_FULL) { /* get attributes */ if (bta_ag_sdp_find_attr(p_scb, p_scb->open_services)) { /* set connected service */ p_scb->conn_service = bta_ag_service_to_idx(p_scb->open_services); /* send ourselves sdp ok event */ event = BTA_AG_DISC_OK_EVT; } } /* free discovery db */ bta_ag_free_db(p_scb, p_data); /* if service not found check if we should search for other service */ if ((event == BTA_AG_DISC_FAIL_EVT) && (p_data->disc_result.status == SDP_SUCCESS || p_data->disc_result.status == SDP_DB_FULL || p_data->disc_result.status == SDP_NO_RECS_MATCH)) { if ((p_scb->open_services & BTA_HFP_SERVICE_MASK) && (p_scb->open_services & BTA_HSP_SERVICE_MASK)) { /* search for HSP */ p_scb->open_services &= ~BTA_HFP_SERVICE_MASK; bta_ag_do_disc(p_scb, p_scb->open_services); } else if ((p_scb->open_services & BTA_HSP_SERVICE_MASK) && (p_scb->hsp_version == HSP_VERSION_1_2)) { /* search for UUID_SERVCLASS_HEADSET for HSP 1.0 device */ p_scb->hsp_version = HSP_VERSION_1_0; bta_ag_do_disc(p_scb, p_scb->open_services); } else { /* send ourselves sdp ok/fail event */ bta_ag_sm_execute(p_scb, event, p_data); } } else { /* send ourselves sdp ok/fail event */ bta_ag_sm_execute(p_scb, event, p_data); } }
/******************************************************************************* ** ** Function bta_ag_disc_acp_res ** ** Description This function handles a discovery result when acceptor. ** ** ** Returns void ** *******************************************************************************/ void bta_ag_disc_acp_res(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) { /* if found service */ if (p_data->disc_result.status == SDP_SUCCESS || p_data->disc_result.status == SDP_DB_FULL) { /* get attributes */ bta_ag_sdp_find_attr(p_scb, bta_ag_svc_mask[p_scb->conn_service]); } /* free discovery db */ bta_ag_free_db(p_scb, p_data); }
/******************************************************************************* ** ** Function bta_ag_collision_cback ** ** Description Get notified about collision. ** ** ** Returns void ** *******************************************************************************/ void bta_ag_collision_cback (tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr) { UINT16 handle; tBTA_AG_SCB *p_scb; UNUSED(status); UNUSED(app_id); /* Check if we have opening scb for the peer device. */ handle = bta_ag_idx_by_bdaddr (peer_addr); p_scb = bta_ag_scb_by_idx (handle); if (p_scb && (p_scb->state == BTA_AG_OPENING_ST)) { if (id == BTA_ID_SYS) /* ACL collision */ { APPL_TRACE_WARNING ("AG found collision (ACL) ..."); } else if (id == BTA_ID_AG) /* RFCOMM collision */ { APPL_TRACE_WARNING ("AG found collision (RFCOMM) ..."); } else { APPL_TRACE_WARNING ("AG found collision (\?\?\?) ..."); } p_scb->state = BTA_AG_INIT_ST; /* Cancel SDP if it had been started. */ if(p_scb->p_disc_db) { (void)SDP_CancelServiceSearch (p_scb->p_disc_db); bta_ag_free_db(p_scb, NULL); } /* reopen registered servers */ /* Collision may be detected before or after we close servers. */ if (bta_ag_is_server_closed (p_scb)) bta_ag_start_servers(p_scb, p_scb->reg_services); /* Start timer to han */ p_scb->colli_timer.p_cback = (TIMER_CBACK*)&bta_ag_colli_timer_cback; p_scb->colli_timer.param = (INT32)p_scb; bta_sys_start_timer(&p_scb->colli_timer, 0, BTA_AG_COLLISION_TIMER); p_scb->colli_tmr_on = TRUE; } }
/******************************************************************************* ** ** Function bta_ag_do_disc ** ** Description Do service discovery. ** ** ** Returns void ** *******************************************************************************/ void bta_ag_do_disc(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK service) { tSDP_UUID uuid_list[2]; UINT16 num_uuid = 1; UINT16 attr_list[4]; UINT8 num_attr; BOOLEAN db_inited = FALSE; /* HFP initiator; get proto list and features */ if (service & BTA_HFP_SERVICE_MASK && p_scb->role == BTA_AG_INT) { attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST; attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST; attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST; attr_list[3] = ATTR_ID_SUPPORTED_FEATURES; num_attr = 4; uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HF_HANDSFREE; } /* HFP acceptor; get features */ else if (service & BTA_HFP_SERVICE_MASK && p_scb->role == BTA_AG_ACP) { attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST; attr_list[1] = ATTR_ID_BT_PROFILE_DESC_LIST; attr_list[2] = ATTR_ID_SUPPORTED_FEATURES; num_attr = 3; uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HF_HANDSFREE; } /* HSP initiator; get proto list */ else if (service & BTA_HSP_SERVICE_MASK && p_scb->role == BTA_AG_INT) { attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST; attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST; attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST; attr_list[3] = ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL; num_attr = 4; uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HEADSET; /* Legacy from HSP v1.0 */ if (p_scb->hsp_version >= HSP_VERSION_1_2) { uuid_list[1].uu.uuid16 = UUID_SERVCLASS_HEADSET_HS; num_uuid = 2; } } /* HSP acceptor; no discovery */ else { return; } /* allocate buffer for sdp database */ p_scb->p_disc_db = (tSDP_DISCOVERY_DB *) GKI_getbuf(BTA_AG_DISC_BUF_SIZE); if(p_scb->p_disc_db) { /* set up service discovery database; attr happens to be attr_list len */ uuid_list[0].len = LEN_UUID_16; uuid_list[1].len = LEN_UUID_16; db_inited = SDP_InitDiscoveryDb(p_scb->p_disc_db, BTA_AG_DISC_BUF_SIZE, num_uuid, uuid_list, num_attr, attr_list); } if(db_inited) { /*Service discovery not initiated */ db_inited = SDP_ServiceSearchAttributeRequest(p_scb->peer_addr, p_scb->p_disc_db, bta_ag_sdp_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]); } if(!db_inited) { /*free discover db */ bta_ag_free_db(p_scb, NULL); /* sent failed event */ bta_ag_sm_execute(p_scb, BTA_AG_DISC_FAIL_EVT, NULL); } }