/****************************************************************************
	Profile handler function called in response to issuing an AGHFP_INTERNAL_CALL_MGR_CREATE_WITH_AUDIO_REQ
	message.  Will actually begin the call creation process.
*/
void aghfpHandleCallCreateAudio (AGHFP *aghfp, AGHFP_INTERNAL_CALL_MGR_CREATE_WITH_AUDIO_REQ_T *req)
{
	/* B-11839: should validate parameters here? */
	if ( aghfp->audio_connection_state!=aghfp_audio_connected )
	{
		if ( aghfp->audio_connection_state==aghfp_audio_disconnected ||
		     aghfp->audio_connection_state==aghfp_audio_codec_connect ) /* Carry on if we've just completed codec negotiation. */
		{
			if ( aghfpStoreAudioParams(aghfp, req->packet_type, &req->audio_params) )
			{
				aghfp->call_params.call_type = req->call_type;
				aghfp->call_params.in_band = req->in_band;
			
				aghfpManageCall(aghfp, CallEventCreate, CallFlagOpenAudio);
			}
			else
			{
				aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_invalid_params);
			}
		}
		else
		{
			aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_audio_handler_active);
		}
	}
	else
	{
		aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_have_audio);
	}
}
/*
	Handle Codec Connection request from the HF (AT+BCC).
	This function performs the the actual actions of handling the AT+BCC (once the audio params have been
	obtained from the app, i.e. after aghfpHandleWbsCodecConReq() and ).
*/
static void aghfpHandleWbsCodecConReqProcessing(AGHFP *aghfp)
{
	/* Are we supporting WBS */
	if (aghfp->use_wbs)
	{
		/* OK to initiate WBS Codec Negotiation. */
	
		/* Send OK */
		aghfpSendOk(aghfp);
	
		/* If we haven't negotiatied a codec we need to do so.
		   If we have, we're gonna go ahead and use it here. */
		if (aghfp->use_codec == 0)
		{
			/* Start codec negotiation with HF. */
			if (aghfpWbsStartCodecNegotiation(aghfp, aghfp_negotiate_audio_at_hf))
			{
				aghfp->audio_connection_state = aghfp_audio_codec_connect;
			}
		}
		else
		{
			if (!aghfpCallManagerActiveNotComplete(aghfp))
			{
				MAKE_AGHFP_MESSAGE(AGHFP_INTERNAL_AUDIO_CONNECT_REQ);
				AGHFP_DEBUG(("	  Normal Audio Connection\n"));
				
				message->audio_params = aghfp->audio_params;
				message->packet_type = aghfp->audio_packet_type;
				MessageSend(&aghfp->task, AGHFP_INTERNAL_AUDIO_CONNECT_REQ, message);
			}
			else
			{
				/* Save the audio packet type for Call Manager */
				aghfpStoreAudioParams(aghfp, aghfp->audio_packet_type, &aghfp->audio_params);
				
				/* Answer the call again now that the WBS negotiation is complete. */
				aghfpManageCall(aghfp, CallEventAnswer, CallFlagOpenAudio);
			}
		}
	}
	else
	{
		/* WBS not supported, send ERROR. */
		aghfpSendError(aghfp);
	}
}
/* Attempt to create a new audio (Synchronous) connection */
static void audioConnectRequest(AGHFP *aghfp, sync_pkt_type packet_type, const aghfp_audio_params *audio_params)
{
	if ( !aghfpCallManagerActiveNotComplete(aghfp) )
	{
	    if ( aghfpStoreAudioParams(aghfp, packet_type, audio_params) )
	    {
		    startAudioConnectRequest(aghfp);
	    }
	    else
	    {
			/* Inform app that one or more parameters were invalid */
			sendAudioConnectCfmToApp(aghfp, aghfp_audio_connect_invalid_params, hci_success);
	    }
    }
    else
    {
		/* Inform app that call manager is active, setting up or shutting down a call */
		sendAudioConnectCfmToApp(aghfp, aghfp_audio_connect_call_manager_active, hci_success);
    }
}
/*
	Handle set audio parameters request from the app.
*/
void aghfpHandleSetAudioParamsReq(AGHFP *aghfp, const AGHFP_INTERNAL_SET_AUDIO_PARAMS_REQ_T *req)
{
	/* Only act upon the apps request if in the correct state. */
	switch ( aghfp->audio_connection_state )
	{
	case aghfp_audio_disconnected:
	case aghfp_audio_codec_connect:
		aghfpStoreAudioParams(aghfp, req->packet_type, &req->audio_params);

		/* Continue the Codec Connection */
		aghfpHandleWbsCodecConReqProcessing(aghfp);
		break;
	case aghfp_audio_connecting_esco:
	case aghfp_audio_connecting_sco:
	case aghfp_audio_accepting:
	case aghfp_audio_disconnecting:
	case aghfp_audio_connected:
	default:
		AGHFP_DEBUG(("aghfpHandleAudioConnectReq invalid state %d\n",aghfp->audio_connection_state));
		break;
	}
}
/*
	Handle Codec Negotiation resopnse from the HF (AT+BCS)
*/
void aghfpHandleWbsCodecNegReq(AGHFP *aghfp, uint16 codecUUID16)
{
    sync_pkt_type		audio_packet_type = aghfp->audio_packet_type;
    aghfp_audio_params	audio_params = aghfp->audio_params;
	uint16 codec; 		/* Codec bitmap used internally */
	
    AGHFP_DEBUG(("aghfpHandleWbsCodecNegReq : "));
    
	/* Translate from codec UUID16 format to internal bitmap. */
	codec = WbsUuid16ToCodec((codecs_info*)&(aghfp->codecs_info), codecUUID16);

	/* Note that one bit should be set in the bitmaps and it must be the same bit for success. */
	if(aghfp->use_wbs && (aghfp->use_codec == codec))
	{
		AGHFP_DEBUG(("Starting WB-Speech eSCO\n"));
		
		/* Send OK */
		aghfpSendOk(aghfp);

		/* audio_packet_type and audio_params already set to WBS values. */
		
		/* Force connection create.
		   WBS SCO connection are always initiated by the AG. */
		if(aghfp->wbs_negotiate_action != aghfp_negotiate_no_audio)
		{
			aghfp->wbs_negotiate_action = aghfp_negotiate_audio_at_ag;
		}
	}
	else
	{
		AGHFP_DEBUG(("Falling back to request eSCO type\n"));
		/* send Error */
		aghfpSendError(aghfp);

		/* Reset any saved codecs; Codec Negotiation aborted. */
		aghfp->use_codec = 0;
		
		/* For normal SCO we only set up the SCO here if the AG initiated the connection. */
		if (aghfp->wbs_negotiate_action == aghfp_negotiate_audio_at_ag)
		{ /* Start eSCO Connection */
	        audio_packet_type = aghfp->audio_packet_type;
	        audio_params = aghfp->audio_params;
	        audio_params.override_wbs = TRUE;
        }
	}
	
	if (aghfp->wbs_negotiate_action == aghfp_negotiate_audio_at_ag)
	{ /* Start eSCO Connection. We get here if we are setting up a WBS link or an AG initiated normal SCO. */
		if (!aghfpCallManagerActiveNotComplete(aghfp))
		{
		    MAKE_AGHFP_MESSAGE(AGHFP_INTERNAL_AUDIO_CONNECT_REQ);
		    AGHFP_DEBUG(("    Normal Audio Connection\n"));
		    
			message->audio_params = audio_params;
			message->packet_type = audio_packet_type;
	        MessageSend(&aghfp->task, AGHFP_INTERNAL_AUDIO_CONNECT_REQ, message);
		}
		else
		{
			/* Save the audio packet type for Call Manager */
			aghfpStoreAudioParams(aghfp, audio_packet_type, &audio_params);
			
			/* Answer the call again now that the WBS negotiation is complete. */
			aghfpManageCall(aghfp, CallEventAnswer, CallFlagOpenAudio);
        }
	}
	
	aghfp->wbs_negotiate_action = aghfp_negotiate_undefined; /* Reset flag to ensure it is correct next time */
}