/**************************************************************************** NAME hfpHandleServiceSearchAttributeCfm DESCRIPTION Service search has completed, check it has succeeded and get the required attrubutes from the returned list. RETURNS void */ void hfpHandleServiceSearchAttributeCfm(const CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM_T *cfm) { /* Get the link from the bdaddr */ hfp_link_data* link = hfpGetLinkFromBdaddr(&cfm->bd_addr); /* The link may have been pulled from under us by an early disconnect request. If this has happened ignore SDP result */ if(link) { /* Check the outcome of the service search */ if (cfm->status == sdp_response_success) { uint16 sdp_data = 0; if(link->ag_slc_state == hfp_slc_searching) { if (getRfcommChannelNumber(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data)) { /* We have an rfcomm channel we can proceed with the connection establishment */ hfpSetLinkSlcState(link, hfp_slc_outgoing); /* Use the local channel to specify the security requirements for this connection */ ConnectionRfcommConnectRequest(&theHfp->task, &cfm->bd_addr, link->service->rfc_server_channel, sdp_data, 0); } else { /* Received unexpected data. Should never happen since we're issuing the search and should know what we're looking. However, if it does, treat as SDP failure. */ hfpSdpRetry(link); } } else if(link->ag_slc_state == hfp_slc_connected) { /* If SLC is up then this must be a features request */ if (getHfpAgSupportedFeatures(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data)) { /* Send an internal message with the supported features. */ hfpHandleSupportedFeaturesNotification(link, sdp_data); } /* else { Received unexpected data. Should never happen since we're issuing the search and should know what we're looking. However, if it does, just ignore since SLC setup is already being continued. } */ } } else { /* RFCOMM channel search failed, tell the application */ if(link->ag_slc_state == hfp_slc_searching) { if (cfm->status == sdp_no_response_data) { /* Retry next profile if possible... */ hfpSdpRetry(link); } else { /* Generic fail by default */ hfp_connect_status status = hfp_connect_failed; /* Was it a page timeout? */ if (cfm->status == sdp_connection_error) status = hfp_connect_timeout; /* Tell the app */ hfpSendSlcConnectCfmToApp(link, NULL, status); } } } } }
/**************************************************************************** NAME hfpHandleServiceSearchAttributeCfm DESCRIPTION Service search has completed, check it has succeeded and get the required attrubutes from the returned list. RETURNS void */ void hfpHandleServiceSearchAttributeCfm(HFP *hfp, const CL_SDP_SERVICE_SEARCH_ATTRIBUTE_CFM_T *cfm) { /* Check the outcome of the service search */ if (cfm->status == sdp_response_success) { uint16 sdp_data = 0; switch ( hfp->sdp_search_mode ) { case hfp_sdp_search_rfcomm_channel: if (getRfcommChannelNumber(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data)) { /* We have an rfcomm channel we can proceed with the connection establishment */ HFP_INTERNAL_RFCOMM_CONNECT_REQ_T message ; message.addr = cfm->bd_addr; message.rfc_channel = sdp_data; if (hfp->state == hfpSlcConnecting) hfpHandleRfcommConnectRequest(hfp, &message); } else { /* Received unexpected data. Should never happen since we're issuing the search and should know what we're looking. However, if it does, assume a failure has occurred as below. */ /* Tell the app the connection attempt has failed. */ hfpSendSlcConnectCfmToApp(hfp_connect_sdp_fail, hfp); } break; case hfp_sdp_search_profile_version: if (getHfpAgProfileVersion(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data)) { /* Obtained version of HFP running on AG */ hfp->agSupportedProfile = (hfp_profile)sdp_data; if( supportedProfileIsHfp15(hfp->agSupportedProfile) ) { hfpSendRemoteAGProfileVerIndToApp(hfp->agSupportedProfile, hfp); } } else { /* Received unexpected data. Should never happen since we're issuing the search and should know what we're looking. However, if it does, assume a failure has occurred as below. */ /* Incorrect response from AG, so assume it's running HFP v1.0 */ hfp->agSupportedProfile = hfp_handsfree_profile; } break; case hfp_sdp_search_supported_features: if (getHfpAgSupportedFeatures(cfm->attributes, cfm->attributes+cfm->size_attributes, &sdp_data)) { /* Send an internal message with the supported features. */ hfpHandleSupportedFeaturesNotification(hfp, sdp_data); } else { /* Received unexpected data. Should never happen since we're issuing the search and should know what we're looking. However, if it does, just ignore since SLC setup is already being continued. */ } break; default: /* else ... We have received data we don't know what to do with. This shouldn't happen since we're issuing the search and should know what we're looking for so for the moment just ignore. */ break; } } else { switch ( hfp->sdp_search_mode ) { case hfp_sdp_search_rfcomm_channel: /* A RFCOMM connection will not exist at this point */ if (cfm->status == sdp_no_response_data) { /* Tell the app the connection attempt has failed. */ hfpSendSlcConnectCfmToApp(hfp_connect_sdp_fail, hfp); } else if (cfm->status == sdp_connection_error) { /* If it was a page timeout the client would like to know */ hfpSendSlcConnectCfmToApp(hfp_connect_timeout, hfp); } else { /* All other sdp fails */ hfpSendSlcConnectCfmToApp(hfp_connect_failed, hfp); } break; case hfp_sdp_search_profile_version: /* No response from AG, so assume it's running HFP v1.0 */ hfp->agSupportedProfile = hfp_handsfree_profile; break; case hfp_sdp_search_supported_features: /* Just ignore. SLC setup is already being continued */ break; default: /* else ... We have received data we don't know what to do with. This shouldn't happen since we're issuing the search and should know what we're looking for so for the moment just ignore. */ break; } } /* Reset sdp search mode */ hfp->sdp_search_mode = hfp_sdp_search_none; }