/****************************************************************************
	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);
	}
}
static void manageCallWaitAudioCancel (AGHFP *aghfp, aghfp_call_event call_event, aghfp_call_flags call_flags)
{
	switch ( call_event )
	{
	case CallEventCreate:
	case CallEventAnswer:
	case CallEventRemoteAnswered:
	case CallEventTerminate:
	case CallEventAudioConnected:
		break;
		
	case CallEventAudioDisconnected:
		setCallFlags(aghfp, call_flags & (CallFlagsAll));
		
		if ( checkCallFlag(aghfp, CallFlagSuccess) )
		{	/* Audio disconnect succeeded */
			clearCallFlags(aghfp, CallFlagSuccess);
			
			if ( !usingHsp(aghfp) )
			{
				aghfpSendCallIndicator(aghfp, aghfp_call_none);
				aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_none);
			}
			setCallProgress(aghfp, CallProgressIdle);
            aghfpSetState(aghfp, aghfp_slc_connected);
            aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_aborted);
		}
		else
		{	/* Audio disconnect failed */
			Panic();  /* B-11841: Should do something more meaningful here */
		}
		break;
		
	case CallEventAudioTransfer:
	case CallEventRing:
    case CallEventTerminateHeld:
    case CallEventAcceptHeld:
		break;
		
	case CallEventSlcRemoved:
		/* SLC has been removed */
		setCallProgress(aghfp, CallProgressIdle);
		aghfpSetState(aghfp, aghfp_ready);
        aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_slc_removed);
		aghfpSendSlcDisconnectIndToApp(aghfp, convertCallFlagToDisconnectStatus(call_flags));
		break;
		
	default:
		Panic();
	}
}
/****************************************************************************
	Profile handler function called in response to issuing an AGHFP_INTERNAL_CALL_MGR_CREATE_REQ
	message.  Will actually begin the call creation process.
*/
void aghfpHandleCallCreate (AGHFP *aghfp, AGHFP_INTERNAL_CALL_MGR_CREATE_REQ_T *req)
{
	/* B-11839: should validate parameters here? */
	if ( aghfp->audio_connection_state==aghfp_audio_disconnected || aghfp->audio_connection_state==aghfp_audio_connected )
	{
		aghfp->call_params.call_type = req->call_type;
		aghfp->call_params.in_band = req->in_band;
	
		aghfpManageCall(aghfp, CallEventCreate, CallFlagsNone);
	}
	else
	{
		aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_audio_handler_active);
	}
}
static void handleAghfpMessages(Task task, MessageId id, Message message)
{
	AGHFP *aghfp = (AGHFP *) task;
	aghfp_state profileState = aghfp->state;

	switch(id)
	{
		/*************************************************************************/
		/* Init messages                                                         */
		/*************************************************************************/



		case AGHFP_INTERNAL_INIT_REQ:
			PRINT(("AGHFP_INTERNAL_INIT_REQ\n"));

			switch(profileState)
			{
				case aghfp_initialising:
					aghfpHandleInternalInitReq(aghfp);
					break;
				default:
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		case AGHFP_INTERNAL_INIT_CFM:
			PRINT(("AGHFP_INTERNAL_INIT_CFM\n"));

			switch(profileState)
			{
				case aghfp_initialising:
					aghfpHandleInternalInitCfm(aghfp, (AGHFP_INTERNAL_INIT_CFM_T *) message);
					break;
				default:
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		/*************************************************************************/
		/* SDP Messages                                                          */
		/*************************************************************************/

		case AGHFP_INTERNAL_SDP_REGISTER_CFM:
			PRINT(("AGHFP_INTERNAL_SDP_REGISTER_CFM\n"));

			switch(profileState)
			{
				case aghfp_initialising:
					aghfpHandleSdpInternalRegisterInit(aghfp, (AGHFP_INTERNAL_SDP_REGISTER_CFM_T *) message);
					break;
				case aghfp_ready:
					aghfpHandleSdpInternalRegisterCfm((AGHFP_INTERNAL_SDP_REGISTER_CFM_T *) message);
					break;
				default:
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		/*************************************************************************/
		/* SLC Messages                                                          */
		/*************************************************************************/

		case AGHFP_INTERNAL_SLC_CONNECT_REQ:
			PRINT(("AGHFP_INTERNAL_SLC_CONNECT_REQ\n"));

			switch(profileState)
			{
				case aghfp_ready:
					aghfpHandleSlcConnectRequest(aghfp, (AGHFP_INTERNAL_SLC_CONNECT_REQ_T *) message);
					break;

				case aghfp_slc_connecting:
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
					/*  If this profile instance is already connecting/connected then
					reject the SLC connect request and inform the app. */
					aghfpSendSlcConnectCfmToApp(aghfp_connect_failed_busy, aghfp);
					break;

				default:
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		case AGHFP_INTERNAL_SLC_CONNECT_RES:
			PRINT(("AGHFP_INTERNAL_SLC_CONNECT_RES\n"));

			switch(profileState)
			{
				case aghfp_slc_connecting:
					aghfpHandleSlcConnectResponse(aghfp, (AGHFP_INTERNAL_SLC_CONNECT_RES_T *) message);
					break;

				case aghfp_ready:
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
					/*  If the app is sending us an SLC connect response when we're not
					connecting then send it an error message since we currently don't
					have an SLC being established. */
					aghfpSendSlcConnectCfmToApp(aghfp_connect_failed_busy, aghfp);
					break;

				default:
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		case AGHFP_INTERNAL_RFCOMM_CONNECT_REQ:
			PRINT(("AGHFP_INTERNAL_RFCOMM_CONNECT_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connecting:
					aghfpHandleRfcommConnectRequest(aghfp, (AGHFP_INTERNAL_RFCOMM_CONNECT_REQ_T *) message);
					break;
				default:
					/* Something wrong, this message is sent internally from the AGHFP */
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		case AGHFP_INTERNAL_SLC_DISCONNECT_REQ:
			PRINT(("AGHFP_INTERNAL_SLC_DISCONNECT_REQ"));

			switch(profileState)
			{
				case aghfp_slc_connecting:
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
                case aghfp_active_call:				
					aghfpHandleSlcDisconnect(aghfp);
					break;
				case aghfp_ready:
					/* Send disconnect message with error - nothing to disconnect */
					aghfpHandleDisconnectRequestFail(aghfp);
					break;
                case aghfp_initialising:
				default:
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;


		/*************************************************************************/
		/* AT Messages                                                           */
		/*************************************************************************/

		case AGHFP_INTERNAL_AT_CKPD_CMD:
			PRINT(("AGHFP_INTERNAL_AT_CKPD_CMD\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleKeypadCommand(aghfp, ((AGHFP_INTERNAL_AT_CKPD_CMD_T*)message)->keycode);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;
			
		case AGHFP_INTERNAL_AT_BRSF_REQ:
			PRINT(("AGHFP_INTERNAL_AT_BRSF_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connecting:
				{
					uint16 hf_supported_features = ((AGHFP_INTERNAL_AT_BRSF_REQ_T *)message)->hf_supported_features;

					/* Only allowed if we are an HFP device */
					if (!supportedProfileIsHfp(aghfp->supported_profile)) Panic();

					aghfpHandleBrsfRequest(aghfp, hf_supported_features);
					break;
				}
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_AT_CIND_SUPPORTED_REQ:
			PRINT(("AGHFP_INTERNAL_AT_CIND_SUPPORTED_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connecting:
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					/* Only allowed if we are an HFP device */
					if (!supportedProfileIsHfp(aghfp->supported_profile)) Panic();
					aghfpHandleCindSupportedRequest(aghfp);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_AT_CIND_STATUS_REQ:
			PRINT(("AGHFP_INTERNAL_AT_CIND_STATUS_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connecting:
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					/* Only allowed if we are an HFP device */
					if (!supportedProfileIsHfp(aghfp->supported_profile)) Panic();
					aghfpHandleCindStatusRequest(aghfp);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_AT_CMER_REQ:
			PRINT(("AGHFP_INTERNAL_AT_CMER_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connecting:
				{
					AGHFP_INTERNAL_AT_CMER_REQ_T *data = (AGHFP_INTERNAL_AT_CMER_REQ_T *)message;

					/* Only allowed if we are an HFP device */
					if (!supportedProfileIsHfp(aghfp->supported_profile)) Panic();

					aghfpHandleCmerRequest(aghfp, data->mode, data->ind);
					break;
				}
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_CALL_HOLD_SUPPORT_REQ: /* HF sent AT+CHLD=? query */
			PRINT(("AGHFP_INTERNAL_CALL_HOLD_SUPPORT_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connecting:
					/* Only allowed if we are an HFP device */
					if (!supportedProfileIsHfp(aghfp->supported_profile)) Panic();
					aghfpHandleCallHoldSupportRequest(aghfp);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_CALL_HOLD_REQ: /* HF sent AT+CHLD=<action>[<idx>] instruction */
		{
    		AGHFP_INTERNAL_CALL_HOLD_REQ_T *msg = (AGHFP_INTERNAL_CALL_HOLD_REQ_T *)message;
			PRINT(("AGHFP_INTERNAL_CALL_HOLD_REQ\n"));

			switch(profileState)
			{
				case aghfp_active_call:
					aghfpHandleCallHoldReq(aghfp, msg->action, msg->index);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}

			break;
		}

		case AGHFP_INTERNAL_ANSWER_REQ: /* HF wants to answer the call */
			PRINT(("AGHFP_INTERNAL_ANSWER_REQ\n"));

			switch(profileState)
			{
				case aghfp_incoming_call_establish:
#if 0	/* Always pass notification to app and let it call AghfpCallAnswer() */						
					if ( aghfpCallManagerActive(aghfp) )
					{
						aghfpSendOk(aghfp);
						aghfpManageCall(aghfp, CallEventAnswer, CallFlagOpenAudio);
					}
					else
#endif
					{
						aghfpHandleAnswer(aghfp);
					}
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_CALLER_ID_SETUP_REQ: /* HF wants to enable/disable caller ID notification */
			PRINT(("AGHFP_INTERNAL_CALLER_ID_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleCallerIdSetupReq(aghfp, ((AGHFP_INTERNAL_CALLER_ID_SETUP_REQ_T*)message)->state);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_CALL_WAITING_SETUP_REQ: /* HF wants to enable/disable call waiting notification */
			PRINT(("AGHFP_INTERNAL_CALL_WAITING_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleCallWaitingSetupReq(aghfp, ((AGHFP_INTERNAL_CALL_WAITING_SETUP_REQ_T*)message)->state);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_CALL_HANG_UP_REQ: /* HF wants to reject incoming call */
			PRINT(("AGHFP_INTERNAL_CALL_HANG_UP_REQ\n"));

			switch(profileState)
			{
				case aghfp_incoming_call_establish:
                case aghfp_outgoing_call_establish:
				case aghfp_active_call:
#if 0	/* Always pass notification up to app and let it call AghfpCallTerminate() */
					if ( aghfpCallManagerActive(aghfp) )
					{
						aghfpSendOk(aghfp);
						aghfpManageCall(aghfp, CallEventTerminate, CallFlagCloseAudio);
					}
					else
#endif
					{
						aghfpHandleCallHangUpReq(aghfp);
					}
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_DIAL_REQ: /* HF wants to dial a number */
			PRINT (("AGHFP_INTERNAL_DIAL_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_active_call:
				{
					AGHFP_INTERNAL_DIAL_REQ_T *data = (AGHFP_INTERNAL_DIAL_REQ_T*)message;
					aghfpHandleDialReq(aghfp, data->number, data->size_number);
					break;
				}
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_MEMORY_DIAL_REQ: /* HF wants to dial a number from the AG's phonebook */
			PRINT (("AGHFP_INTERNAL_MEMORY_DIAL_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				{
					AGHFP_INTERNAL_MEMORY_DIAL_REQ_T *data = (AGHFP_INTERNAL_MEMORY_DIAL_REQ_T*)message;
					aghfpHandleMemoryDialReq(aghfp, data->number, data->size_number);
					break;
				}
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_LAST_NUMBER_REDIAL_REQ: /* HF wants to redial last number dialed by AG */
			PRINT (("AGHFP_INTERNAL_LAST_NUMBER_REDIAL_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
					aghfpHandleLastNumberRedialReq(aghfp);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_NREC_SETUP_REQ:
			PRINT (("AGHFP_INTERNAL_NREC_SETUP_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleNrecSetupReq(aghfp, ((AGHFP_INTERNAL_NREC_SETUP_REQ_T*)message)->state);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;

		case AGHFP_INTERNAL_VOICE_RECOGNITION_SETUP_REQ:
			PRINT (("AGHFP_INTERNAL_VOICE_RECOGNITION_SETUP_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleVoiceRecognitionSetupReq(aghfp, ((AGHFP_INTERNAL_VOICE_RECOGNITION_SETUP_REQ_T*)message)->state);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;


		case AGHFP_INTERNAL_PHONE_NUMBER_REQ:
			PRINT (("AGHFP_INTERNAL_PHONE_NUMBER_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandlePhoneNumberForVoiceTagReq(aghfp);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;


		case AGHFP_INTERNAL_TRANSMIT_DTMF_CODE:
		{
			AGHFP_INTERNAL_TRANSMIT_DTMF_CODE_T *data = (AGHFP_INTERNAL_TRANSMIT_DTMF_CODE_T*)message;
			PRINT (("AGHFP_INTERNAL_TRANSMIT_DTMF_CODE\n"));

			switch(profileState)
			{
				case aghfp_active_call:
					aghfpHandleTransmitDtmfCode(aghfp, data->code);
					break;
				default:
					aghfpSendError(aghfp);
					break;
			}
			break;
		}

        case AGHFP_INTERNAL_RESPONSE_HOLD_STATUS_REQUEST_REQ:    /* AT+BTRH?         */
            PRINT (("AGHFP_INTERNAL_RESPONSE_HOLD_STATUS_REQUEST_REQ\n"));
        	switch(profileState)
        	{
            	case aghfp_slc_connected:
            	case aghfp_incoming_call_establish:
            	case aghfp_outgoing_call_establish:
            	case aghfp_active_call:
            	    aghfpHandleResponseHoldStatusRequest(aghfp);
            	    break;
        		default:
        			aghfpSendError(aghfp);
        			break;
        	}
            break;

        case AGHFP_INTERNAL_SET_RESPONSE_HOLD_STATUS_REQ:           /* AT+BTRH=c        */
        {
            AGHFP_INTERNAL_SET_RESPONSE_HOLD_STATUS_REQ_T *msg = (AGHFP_INTERNAL_SET_RESPONSE_HOLD_STATUS_REQ_T *)message;
            PRINT (("AGHFP_INTERNAL_SET_RESPONSE_HOLD_STATUS_REQ\n"));
        	switch(profileState)
        	{
            	case aghfp_slc_connected:
            	case aghfp_incoming_call_establish:
            	case aghfp_outgoing_call_establish:
            	case aghfp_active_call:
            	    aghfpHandleSetResponseHoldStatus(aghfp,msg->cmd);
            	    break;
        		default:
        			aghfpSendError(aghfp);
        			break;
        	}
            break;
        }

        case AGHFP_INTERNAL_SUBSCRIBER_NUMBER_REQ:       /* AT+CNUM          */
            PRINT (("AGHFP_INTERNAL_SUBSCRIBER_NUMBER_REQ\n"));
        	switch(profileState)
        	{
            	case aghfp_slc_connected:
            	case aghfp_incoming_call_establish:
            	case aghfp_outgoing_call_establish:
            	case aghfp_active_call:
            	    aghfpHandleSubscriberNumbersRequest(aghfp);
            	    break;
        		default:
        			aghfpSendError(aghfp);
        			break;
        	}
            break;

        case AGHFP_INTERNAL_CURRENT_CALLS_REQ:           /* AT+CLCC          */
            PRINT (("AGHFP_INTERNAL_CURRENT_CALLS_REQ\n"));
        	switch(profileState)
        	{
            	case aghfp_slc_connected:
            	case aghfp_incoming_call_establish:
            	case aghfp_outgoing_call_establish:
            	case aghfp_active_call:
            	    aghfpHandleCurrentCallsRequest(aghfp);
            	    break;
        		default:
        			aghfpSendError(aghfp);
        			break;
        	}
            break;

        case AGHFP_INTERNAL_NETWORK_OPERATOR_FORMAT_REQ: /* AT+COPS=m,f      */
        {
            AGHFP_INTERNAL_NETWORK_OPERATOR_FORMAT_REQ_T *msg = (AGHFP_INTERNAL_NETWORK_OPERATOR_FORMAT_REQ_T *)message;
            PRINT (("AGHFP_INTERNAL_NETWORK_OPERATOR_FORMAT_REQ\n"));
        	switch(profileState)
        	{
            	case aghfp_slc_connected:
            	case aghfp_incoming_call_establish:
            	case aghfp_outgoing_call_establish:
            	case aghfp_active_call:
            	    aghfpHandleNetworkOperatorFormatRequest(aghfp, msg->mode, msg->format);
            	    break;
        		default:
        			aghfpSendError(aghfp);
        			break;
        	}
            break;
        }

        case AGHFP_INTERNAL_NETWORK_OPERATOR_REQ:        /* AT+COPS?         */
            PRINT (("AGHFP_INTERNAL_NETWORK_OPERATOR_REQ\n"));
        	switch(profileState)
        	{
            	case aghfp_slc_connected:
            	case aghfp_incoming_call_establish:
            	case aghfp_outgoing_call_establish:
            	case aghfp_active_call:
            	    aghfpHandleNetworkOperatorRequest(aghfp);
            	    break;
        		default:
        			aghfpSendError(aghfp);
        			break;
        	}
            break;


		/*************************************************************************/
		/* Audio Connection Messages                                             */
		/*************************************************************************/

		case AGHFP_INTERNAL_AUDIO_TRANSFER_REQ:
			/* TODO - really need to handle this message! */
			break;

		case AGHFP_INTERNAL_AUDIO_CONNECT_REQ:
			PRINT(("AGHFP_INTERNAL_AUDIO_CONNECTION_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleAudioConnectReq(aghfp, (AGHFP_INTERNAL_AUDIO_CONNECT_REQ_T*)message);
					break;
				default:
					/* Panic in debug and ignore in release lib variants */
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		case AGHFP_INTERNAL_AUDIO_CONNECT_RES:
			PRINT(("AGHFP_INTERNAL_AUDIO_CONNECT_RES\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
				{
					aghfpHandleAudioConnectRes(aghfp, (AGHFP_INTERNAL_AUDIO_CONNECT_RES_T*)message);
					break;
				}
				default:
					/* Panic in debug and ignore in release lib variants */
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		case AGHFP_INTERNAL_AUDIO_DISCONNECT_REQ:
			PRINT(("AGHFP_INTERNAL_AUDIO_DISCONNECT_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleAudioDisconnectReq(aghfp);
					break;
				default:
					/* Panic in debug and ignore in release lib variants */
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;

		case AGHFP_INTERNAL_SET_AUDIO_PARAMS_REQ:
			PRINT(("AGHFP_INTERNAL_SET_AUDIO_PARAMS_REQ\n"));
			
			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSetAudioParamsReq(aghfp, (AGHFP_INTERNAL_SET_AUDIO_PARAMS_REQ_T*)message);
					break;
				default:
					/* Panic in debug and ignore in release lib variants */
					handleUnexpected(aghfpUnexpectedAghfpPrim, profileState, id);
					break;
			}
			break;
			

		/*************************************************************************/
		/* Indicator Messages                                                    */
		/*************************************************************************/

		case AGHFP_INTERNAL_SEND_SERVICE_INDICATOR:
			PRINT(("AGHFP_INTERNAL_SEND_SERVICE_INDICATOR\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
					aghfpHandleSendServiceIndicator(aghfp,
					((AGHFP_INTERNAL_SEND_SERVICE_INDICATOR_T*)message)->availability);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_SEND_SERVICE_INDICATOR_CFM, aghfp, aghfp_fail);
					break;
			}
			break;

		case AGHFP_INTERNAL_SEND_CALL_INDICATOR:
		{
			aghfp_call_status status = ((AGHFP_INTERNAL_SEND_CALL_INDICATOR_T*)message)->status;

			PRINT(("AGHFP_INTERNAL_SEND_CALL_INDICATOR\n"));

			if ((profileState == aghfp_incoming_call_establish && status == aghfp_call_active) ||
				(profileState == aghfp_outgoing_call_establish && status == aghfp_call_active) ||
				(profileState == aghfp_active_call             && status == aghfp_call_none))
			{
				aghfpHandleSendCallIndicator(aghfp, status);
			}
			else
			{
				aghfpSendCommonCfmMessageToApp(AGHFP_SEND_CALL_INDICATOR_CFM, aghfp, aghfp_fail);
			}

			break;
		}

		case AGHFP_INTERNAL_SEND_CALL_SETUP_INDICATOR:
		{
			aghfp_call_setup_status status;
			status = ((AGHFP_INTERNAL_SEND_CALL_SETUP_INDICATOR_T*)message)->type;

			PRINT(("AGHFP_INTERNAL_SEND_CALL_SETUP_INDICATOR\n"));

			if ((profileState == aghfp_slc_connected    		&& status == aghfp_call_setup_incoming) ||
				(profileState == aghfp_slc_connected    		&& status == aghfp_call_setup_outgoing) ||
				(profileState == aghfp_incoming_call_establish 	&& status == aghfp_call_setup_none) ||
                (profileState == aghfp_outgoing_call_establish 	&& status == aghfp_call_setup_none) ||
				(profileState == aghfp_outgoing_call_establish  && status == aghfp_call_setup_remote_alert) ||
				(profileState == aghfp_active_call) )
			{
				aghfpHandleSendCallSetupIndicator(aghfp, status);
			}
			else
			{
				aghfpSendCommonCfmMessageToApp(AGHFP_SEND_CALL_SETUP_INDICATOR_CFM, aghfp, aghfp_fail);
			}

			break;
		}

		case AGHFP_INTERNAL_SEND_CALL_HELD_INDICATOR:
			/* TODO - really need to handle this message */
			break;
			
		case AGHFP_INTERNAL_SEND_SIGNAL_INDICATOR:
			/* TODO - really need to handle this message */
			break;
		
		case AGHFP_INTERNAL_SEND_ROAM_INDICATOR:
			/* TODO - really need to handle this message */
			break;
			
		case AGHFP_INTERNAL_SEND_BATT_CHG_INDICATOR:
			/* TODO - really need to handle this message */
			break;

		case AGHFP_INTERNAL_SEND_CALL_WAITING_NOTIFICATION:
		{
			AGHFP_INTERNAL_SEND_CALL_WAITING_NOTIFICATION_T *scwn =	(AGHFP_INTERNAL_SEND_CALL_WAITING_NOTIFICATION_T *)message;
			PRINT(("AGHFP_INTERNAL_SEND_CALL_WAITING_NOTIFICATION\n"));

			switch(profileState)
			{
				case aghfp_active_call:
					aghfpHandleSendCallWaitingNotification(aghfp, scwn->type, scwn->size_number, scwn->number, scwn->size_string, scwn->string);
					break;
				default:
					free(scwn->string);
					aghfpSendCommonCfmMessageToApp(AGHFP_SEND_CALL_WAITING_NOTIFICATION_CFM, aghfp, aghfp_fail);
					break;
			}

			break;
		}

		case AGHFP_INTERNAL_SET_SERVICE_STATE:
		{
			PRINT(("AGHFP_INTERNAL_SET_SERVICE_STATE\n"));

			switch (profileState)
			{
				case aghfp_initialising:
					break;	/* Silently ignore */
				case aghfp_ready:
				case aghfp_slc_connecting:
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSetServiceState(aghfp, ((AGHFP_INTERNAL_SET_SERVICE_STATE_T*)message)->service_state);
					break;
			}

			break;
		}


		/*************************************************************************/
		/* Call Related Messages                                                 */
		/*************************************************************************/

		case AGHFP_INTERNAL_SEND_RING_ALERT:
			PRINT(("AGHFP_INTERNAL_SEND_RING_ALERT\n"));

			switch(profileState)
			{
				case aghfp_incoming_call_establish:
					aghfpHandleSendRingAlert(aghfp);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_SEND_RING_ALERT_CFM, aghfp, aghfp_fail);
					break;
			}
			break;

		case AGHFP_INTERNAL_SEND_CALLER_ID:
		{
			AGHFP_INTERNAL_SEND_CALLER_ID_T *msg = (AGHFP_INTERNAL_SEND_CALLER_ID_T*)message;
			switch(profileState)
			{
				case aghfp_incoming_call_establish:
					aghfpHandleSendCallerId(aghfp, msg->type, msg->size_number, msg->size_string, msg->data);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_SEND_CALLER_ID_CFM, aghfp, aghfp_fail);
					break;
			}
			break;
		}
		case AGHFP_INTERNAL_INBAND_RING_TONE_ENABLE:
			PRINT(("AGHFP_INTERNAL_INBAND_RING_TONE_ENABLE\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
					aghfpHandleInBandRingToneEnable(aghfp, ((AGHFP_INTERNAL_INBAND_RING_TONE_ENABLE_T*)message)->enable);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_INBAND_RING_ENABLE_CFM, aghfp, aghfp_fail);
					break;
			}
			break;


		/*************************************************************************/
		/* Call Management Messages                                              */
		/*************************************************************************/

		case AGHFP_INTERNAL_CALL_MGR_CREATE_REQ:
			PRINT(("AGHFP_INTERNAL_CALL_MGR_CREATE_REQ\n"));
			
			switch(profileState)
			{
				case aghfp_slc_connected:
					aghfpHandleCallCreate(aghfp, (AGHFP_INTERNAL_CALL_MGR_CREATE_REQ_T *)message);
					break;
				default:
					aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_error);
					break;
			}
			break;
			
			
		case AGHFP_INTERNAL_CALL_MGR_CREATE_WITH_AUDIO_REQ:
			PRINT(("AGHFP_INTERNAL_CALL_MGR_CREATE_WITH_AUDIO_REQ\n"));
			
			switch(profileState)
			{
				case aghfp_slc_connected:
					aghfpHandleCallCreateAudio(aghfp, (AGHFP_INTERNAL_CALL_MGR_CREATE_WITH_AUDIO_REQ_T *)message);
					break;
				default:
					aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_error);
					break;
			}
			break;
			
			
		case AGHFP_INTERNAL_CALL_MGR_ANSWER_REQ:
			PRINT(("AGHFP_INTERNAL_CALL_MGR_ANSWER_REQ\n"));
			
			switch(profileState)
			{
				case aghfp_incoming_call_establish:
					aghfpHandleCallAnswer(aghfp);
					break;
				default:
					/* Silently ignore message */
					break;
			}
			break;
			
			
		case AGHFP_INTERNAL_CALL_MGR_REMOTE_ANSWERED_REQ:
			PRINT(("AGHFP_INTERNAL_CALL_MGR_REMOTE_ANSWERED_REQ\n"));
			
			switch(profileState)
			{
				case aghfp_outgoing_call_establish:
					aghfpHandleCallRemoteAnswered(aghfp);
					break;
				default:
					/* Silently ignore message */
					break;
			}
			break;
			
			
		case AGHFP_INTERNAL_CALL_MGR_TERMINATE_REQ:
			PRINT(("AGHFP_INTERNAL_CALL_MGR_TERMINATE_REQ\n"));
			
			switch(profileState)
			{
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleCallTerminate(aghfp, (AGHFP_INTERNAL_CALL_MGR_TERMINATE_REQ_T *)message);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_CALL_MGR_TERMINATE_IND, aghfp, aghfp_fail);
					break;
			}
			break;
			
			
		case AGHFP_INTERNAL_RING_REPEAT_REQ:
			PRINT(("AGHFP_INTERNAL_RING_REPEAT_REQ\n"));
			
			switch(profileState)
			{
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
					aghfpManageCall(aghfp, CallEventRing, CallFlagsNone);
					break;
				default:
					/* Silently ignore message */
					break;
			}
			break;
			
		
			
		/*************************************************************************/
		/* Misc Other Messages                                                   */
		/*************************************************************************/

		case AGHFP_INTERNAL_SET_CALLER_ID_DETAILS_REQ:
			PRINT(("AGHFP_INTERNAL_SET_CALLER_ID_DETAILS_REQ\n"));
			
			switch(profileState)
			{
				case aghfp_initialising:
				case aghfp_ready:
				case aghfp_slc_connecting:
				case aghfp_slc_connected:
					aghfpHandleSetCallerIdDetails(aghfp, (AGHFP_INTERNAL_SET_CALLER_ID_DETAILS_REQ_T *)message);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_SET_CALLER_ID_DETAILS_CFM, aghfp, aghfp_fail);
					break;
			}
			break;
			
		case AGHFP_INTERNAL_VOICE_RECOGNITION_ENABLE:
			PRINT(("AGHFP_INTERNAL_VOICE_RECOGNITION_ENABLE\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleVoiceRecognitionEnable(aghfp, ((AGHFP_INTERNAL_VOICE_RECOGNITION_ENABLE_T*)message)->enable);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_VOICE_RECOGNITION_ENABLE_CFM, aghfp, aghfp_fail);
			}
			break;

		case AGHFP_INTERNAL_SEND_PHONE_NUMBER_FOR_VOICE_TAG:
		{
			AGHFP_INTERNAL_SEND_PHONE_NUMBER_FOR_VOICE_TAG_T *data;
			data = (AGHFP_INTERNAL_SEND_PHONE_NUMBER_FOR_VOICE_TAG_T *)message;
			PRINT(("AGHFP_INTERNAL_SEND_PHONE_NUMBER_FOR_VOICE_TAG\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSendPhoneNumberForVoiceTag(aghfp, data->size_number, data->number);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_SEND_PHONE_NUMBER_FOR_VOICE_TAG_CFM, aghfp, aghfp_fail);
			}
			break;
		}

		case AGHFP_INTERNAL_SET_REMOTE_MICROPHONE_GAIN:
			PRINT(("AGHFP_INTERNAL_SET_REMOTE_MICROPHONE_GAIN\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSetRemoteMicrophoneGain(aghfp, ((AGHFP_INTERNAL_SET_REMOTE_MICROPHONE_GAIN_T*)message)->gain);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_SET_REMOTE_MICROPHONE_GAIN_CFM, aghfp, aghfp_fail);
			}
			break;

		case AGHFP_INTERNAL_SET_REMOTE_SPEAKER_VOLUME:
			PRINT(("AGHFP_INTERNAL_SET_REMOTE_SPEAKER_VOLUME\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSetRemoteSpeakerVolume(aghfp, ((AGHFP_INTERNAL_SET_REMOTE_SPEAKER_VOLUME_T*)message)->volume);
					break;
				default:
					aghfpSendCommonCfmMessageToApp(AGHFP_SET_REMOTE_SPEAKER_VOLUME_CFM, aghfp, aghfp_fail);
			}
			break;

		case AGHFP_INTERNAL_SYNC_MIC_GAIN:
			PRINT(("AGHFP_INTERNAL_SYNC_MIC_GAIN\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSyncMicrophoneGain(aghfp, ((AGHFP_INTERNAL_SYNC_MIC_GAIN_T*)message)->gain);
					break;
				default:
					/* We've received a mic gain command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;

		case AGHFP_INTERNAL_SYNC_SPEAKER_VOLUME:
			PRINT(("AGHFP_INTERNAL_SYNC_SPEAKER_VOLUME\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSyncSpeakerVolume(aghfp, ((AGHFP_INTERNAL_SYNC_SPEAKER_VOLUME_T*)message)->volume);
					break;
				default:
					/* We've received a speaker gain command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;

        case AGHFP_INTERNAL_SEND_RESPONSE_HOLD_STATE:
			PRINT(("AGHFP_INTERNAL_SEND_RESPONSE_HOLD_STATE\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSendResponseHoldState(aghfp, ((AGHFP_INTERNAL_SEND_RESPONSE_HOLD_STATE_T*)message)->state);
					break;
				default:
					/* We've received a  command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;

        case AGHFP_INTERNAL_CONFIRM_RESPONSE_HOLD_STATE:
			PRINT(("AGHFP_INTERNAL_CONFIRM_RESPONSE_HOLD_STATE\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleConfirmResponseHoldState(aghfp, ((AGHFP_INTERNAL_CONFIRM_RESPONSE_HOLD_STATE_T*)message)->state);
					break;
				default:
					/* We've received a  command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;

        case AGHFP_INTERNAL_SEND_SUBSCRIBER_NUMBER:
			PRINT(("AGHFP_INTERNAL_SEND_SUBSCRIBER_NUMBER\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSendSubscriberNumber(aghfp, (AGHFP_INTERNAL_SEND_SUBSCRIBER_NUMBER_T*)message);
					break;
				default:
					/* We've received a  command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;

        case AGHFP_INTERNAL_SEND_SUBSCRIBER_NUMBERS_COMPLETE:
			PRINT(("AGHFP_INTERNAL_SEND_SUBSCRIBER_NUMBERS_COMPLETE\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSendSubscriberNumbersComplete(aghfp);
					break;
				default:
					/* We've received a  command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;

        case AGHFP_INTERNAL_SEND_CURRENT_CALL:
			PRINT(("AGHFP_INTERNAL_SEND_CURRENT_CALL\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSendCurrentCall(aghfp, (AGHFP_INTERNAL_SEND_CURRENT_CALL_T*)message);
					break;
				default:
					/* We've received a  command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;

        case AGHFP_INTERNAL_SEND_CURRENT_CALLS_COMPLETE:
			PRINT(("AGHFP_INTERNAL_SEND_CURRENT_CALLS_COMPLETE\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSendCurrentCallsComplete(aghfp);
					break;
				default:
					/* We've received a  command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;

        case AGHFP_INTERNAL_SEND_NETWORK_OPERATOR:
        {
			AGHFP_INTERNAL_SEND_NETWORK_OPERATOR_T *msg = (AGHFP_INTERNAL_SEND_NETWORK_OPERATOR_T*)message;
			PRINT(("AGHFP_INTERNAL_SEND_NETWORK_OPERATOR\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleSendNetworkOperator(aghfp, msg->mode, msg->size_operator, msg->operator);
					break;
				default:
					/* We've received a  command from the HF, but we haven't currently
					   got an SLC. That can't really happen. If it does, then just silently ignore. */
					break;
			}
			break;
		}

        case AGHFP_INTERNAL_USER_DATA_REQ:
            PRINT(("AGHFP_INTERNAL_USER_DATA_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
					aghfpHandleUserDataReq(aghfp, (AGHFP_INTERNAL_USER_DATA_REQ_T *) message);
					break;

                case aghfp_ready:
                case aghfp_slc_connecting:
                    /* Cannot send the data, haven't got a valid SLC established */
                    aghfpHandleUserDataReqFail(aghfp, (AGHFP_INTERNAL_USER_DATA_REQ_T *) message);
                    break;

                case aghfp_initialising:
				default:
					/* We have received a request to send user data and we're in the wrong state */
					break;
			}
            break;

        case AGHFP_INTERNAL_SEND_ERROR_REQ:
            PRINT(("AGHFP_INTERNAL_SEND_ERROR_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
                case aghfp_slc_connecting:
					aghfpSendError(aghfp);
					break;

                case aghfp_ready:
                    /* Cannot send error, haven't got a valid RFCOMM established */
                    aghfpSendCommonCfmMessageToApp(AGHFP_SEND_ERROR_CFM, aghfp, aghfp_fail);
                    break;

                case aghfp_initialising:
				default:
					/* We have received this request in the wrong state */
					break;
			}
            break;

        case AGHFP_INTERNAL_SEND_OK_REQ:
            PRINT(("AGHFP_INTERNAL_SEND_OK_REQ\n"));

			switch(profileState)
			{
				case aghfp_slc_connected:
				case aghfp_incoming_call_establish:
				case aghfp_outgoing_call_establish:
				case aghfp_active_call:
                case aghfp_slc_connecting:
					aghfpSendOk(aghfp);
					break;

                case aghfp_ready:
                    /* Cannot send error, haven't got a valid RFCOMM established */
                    aghfpSendCommonCfmMessageToApp(AGHFP_SEND_OK_CFM, aghfp, aghfp_fail);
                    break;

                case aghfp_initialising:
				default:
					/* We have received this request in the wrong state */
					break;
			}
            break;

		/* WB-Speech Messages */
		case AGHFP_INTERNAL_WBS_CODEC_NEGOTIATE_REQ:
			PRINT(("AGHFP_INTERNAL_WBS_CODEC_NEGOTIATE_REQ\n"));
			aghfpHandleWbsCodecNegReq(aghfp, ((AGHFP_INTERNAL_WBS_CODEC_NEGOTIATE_REQ_T*)message)->codec);
			break;
			
		case AGHFP_INTERNAL_WBS_CODEC_CONNECTION_REQ:
			PRINT(("AGHFP_INTERNAL_WBS_CODEC_CONNECTION_REQ\n"));
			aghfpHandleWbsCodecConReq(aghfp);
			break;
				
		case AGHFP_INTERNAL_CODEC_NEGOTIATION_REQ:
			PRINT(("AGHFP_INTERNAL_CODEC_NEGOTIATION_REQ\n"));
			aghfpHandleCodecNegotiationReq(aghfp, (AGHFP_INTERNAL_CODEC_NEGOTIATION_REQ_T*)message);
			break;

		default:
			PRINT(("Unhandled message\n"));
			/* Received an unhandled message */
			handleUnexpected(aghfpUnexpectedMessage, profileState, id);
			break;
    }
}
static void manageCallWaitResponse (AGHFP *aghfp, aghfp_call_event call_event, aghfp_call_flags call_flags)
{
	switch ( call_event )
	{
	case CallEventCreate:
		break;
		
	case CallEventAnswer:
	case CallEventRemoteAnswered:
		setCallFlags(aghfp, call_flags | CallFlagResponded);
		
		if ( !usingHsp(aghfp) &&
		     aghfp->audio_connection_state != aghfp_audio_codec_connect) /* Do not resend the call indicator info
		     															  if we got here from a WBS codec
		     															  negotiation */
		{	/* Working in HFP mode */
			/* Call is now setup even though we might not have an audio channel */
			aghfpSendCallIndicator(aghfp, aghfp_call_active);
			aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_none);
		}
		
		if ( checkCallFlag(aghfp, CallFlagCloseAudio) )
		{	/* Use CloseAudio flag to shutdown any existing audio channel or prevent one being created */
			clearCallFlags(aghfp, CallFlagOpenAudio | CallFlagCloseAudio);
			
			if ( haveAudio(aghfp) )
			{	/* Audio disconnected event will be picked up in CallConnected state */
				aghfpAudioDisconnectRequest(aghfp);
			}
		}
		
		if ( checkCallFlag(aghfp, CallFlagOpenAudio) && !haveAudio(aghfp))
		{
			clearCallFlags(aghfp, CallFlagOpenAudio);
			aghfpAudioConnectRequest(aghfp);

			/* Check to see if aghfpAudioConnectRequest resulted in the commencement of a WBS negotiation */
			if(aghfp->audio_connection_state != aghfp_audio_codec_connect)
			{
				/* Only move to the CallProgressWaitAudioOpen state if a WBS negotiation has not been started. */
				setCallProgress(aghfp, CallProgressWaitAudioOpen);
			}
		}
		else
		{
			setCallProgress(aghfp, CallProgressComplete);
            aghfpSetState(aghfp, aghfp_active_call);
            aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_success);
		}
		break;
		
	case CallEventTerminate:
		setCallFlags(aghfp, call_flags & (CallFlagsAll));
		
		if ( checkCallFlag(aghfp, CallFlagCloseAudio) && haveAudio(aghfp) )
		{
			aghfpAudioDisconnectRequest(aghfp);
			setCallProgress(aghfp, CallProgressWaitAudioCancel);
		}
		else
		{
            if ( !usingHsp(aghfp) )
			{	/* Working in HFP mode */
				aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_none);
			}
			setCallProgress(aghfp, CallProgressIdle);
            aghfpSetState(aghfp, aghfp_slc_connected);
            aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_aborted);
		}
		break;
        
    case CallEventTerminateHeld:
        /* duplicate of CallEventTerminate but without the aghfpSendCallSetupIndicator */
        setCallFlags(aghfp, CallFlagCloseAudio);
        setCallProgress(aghfp, CallProgressIdle);
        aghfpSetState(aghfp, aghfp_slc_connected);
        aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_aborted);
        
        break;
        
    case CallEventAcceptHeld:
        /*duplicate of CallEventAnswer but without the aghfpSendCallIndicator and aghfpSendCallSetupIndicator */
        /* still need to change aghfp state */
        setCallFlags(aghfp, call_flags | CallFlagResponded);
		aghfpSetState(aghfp, aghfp_active_call);
        /* Use CloseAudio flag to shutdown any existing audio channel or prevent one being created */
        clearCallFlags(aghfp, CallFlagOpenAudio | CallFlagCloseAudio);
			
        if ( haveAudio(aghfp) )
        {	/* Audio disconnected event will be picked up in CallConnected state */
            aghfpAudioDisconnectRequest(aghfp);
        }
        
        setCallProgress(aghfp, CallProgressComplete);
        aghfpSetState(aghfp, aghfp_active_call);
        aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_success);
		break;
        
	case CallEventAudioConnected:
	case CallEventAudioDisconnected:
	case CallEventAudioTransfer:
		break;
		
	case CallEventRing:
		sendRingNotifications(aghfp);
		break;
		
	case CallEventSlcRemoved:
		/* SLC has been removed */
		setCallProgress(aghfp, CallProgressIdle);
		aghfpSetState(aghfp, aghfp_ready);
        aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_slc_removed);
		aghfpSendSlcDisconnectIndToApp(aghfp, convertCallFlagToDisconnectStatus(call_flags));
		break;
		
	default:
		Panic();
	}
}
static void manageCallWaitAudioOpen (AGHFP *aghfp, aghfp_call_event call_event, aghfp_call_flags call_flags)
{
	switch ( call_event )
	{
	case CallEventCreate:
	case CallEventAnswer:
	case CallEventRemoteAnswered:
		break;
		
	case CallEventTerminate:
		/* Queue up call terminate request until audio connect completes */
		setCallFlags(aghfp, call_flags | CallFlagTerminate);
		break;
		
	case CallEventAudioConnected:
		setCallFlags(aghfp, call_flags & (CallFlagsAll));
		
		if ( !checkCallFlag(aghfp, CallFlagSuccess) )
		{	/* Audio connect failed */
			if ( !usingHsp(aghfp) )
			{
				aghfpSendCallIndicator(aghfp, aghfp_call_none);
				aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_none);
			}
			
			setCallProgress(aghfp, CallProgressIdle);
            aghfpSetState(aghfp, aghfp_slc_connected);
            aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_failure);
		}
		else if ( checkCallFlag(aghfp, CallFlagTerminate) )
		{	/* Call terminate request has been made */
			clearCallFlags(aghfp, CallFlagTerminate);
			
			if ( haveAudio(aghfp) && checkCallFlag(aghfp, CallFlagCloseAudio) )
			{	/* Shut down audio connection */
				clearCallFlags(aghfp, CallFlagCloseAudio);
				aghfpAudioDisconnectRequest(aghfp);
				setCallProgress(aghfp, CallProgressWaitAudioCancel);
			}
			else
			{	/* Either audio connection does not exist or it is to remain open */
				if ( !usingHsp(aghfp) )
				{
					aghfpSendCallIndicator(aghfp, aghfp_call_none);
					aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_none);
				}
				
				setCallProgress(aghfp, CallProgressIdle);
	            aghfpSetState(aghfp, aghfp_slc_connected);
	            aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_aborted);
			}
		}
		else if ( checkCallFlag(aghfp, CallFlagResponseReqd) )
		{
			if ( checkCallFlag(aghfp, CallFlagRingAlertsReqd) )
			{
				sendRingNotifications(aghfp);
			}
			
			clearCallFlags(aghfp, CallFlagResponseReqd);
			sendCallCreateWaitingIndToApp(aghfp);
			setCallProgress(aghfp, CallProgressWaitResponse);
		}
		else
		{	/* Call setup is now complete */
			if ( !checkCallFlag(aghfp, CallFlagResponded) && !usingHsp(aghfp) )
			{
				aghfpSendCallIndicator(aghfp, aghfp_call_active);
				aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_none);
			}
		
			clearCallFlags(aghfp, CallFlagsAll);
			setCallProgress(aghfp, CallProgressComplete);
        	aghfpSetState(aghfp, aghfp_active_call);
            aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_success);
		}
		break;
		
	case CallEventAudioDisconnected:
	case CallEventAudioTransfer:
	case CallEventRing:
    case CallEventTerminateHeld:
    case CallEventAcceptHeld:
		break;
		
	case CallEventSlcRemoved:
		/* SLC has been removed */
		setCallProgress(aghfp, CallProgressIdle);
		aghfpSetState(aghfp, aghfp_ready);
        aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_slc_removed);
		aghfpSendSlcDisconnectIndToApp(aghfp, convertCallFlagToDisconnectStatus(call_flags));
		break;
		
	default:
		Panic();
	}
}
static void manageCallIdle (AGHFP *aghfp, aghfp_call_event call_event, aghfp_call_flags call_flags)
{
	switch ( call_event )
	{
	case CallEventCreate:
		clearCallFlags(aghfp, CallFlagsAll);
		setCallFlags(aghfp, call_flags & (CallFlagsAll));
		
		switch (aghfp->call_params.call_type)
		{
		case aghfp_call_type_incoming:
			/* Always require a response and ring indications for this type of call */
			setCallFlags(aghfp, CallFlagResponseReqd | CallFlagRingAlertsReqd);
			
			if ( usingHsp(aghfp) )
			{	/* Working in HSP mode */
				/* HSP mandates that audio must be present */
				setCallFlags(aghfp, CallFlagOpenAudio);  /* B-11840: what if audio params are unspecified? */
				if ( inbandSupported(aghfp) )
				{	/* Ensure audio exists before an answer call response is actioned */
					setCallFlags(aghfp, CallFlagResponseAfterAudio);
				}
			}
			else
			{	/* Working in HFP mode */
				aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_incoming);
				
				if ( inbandSupported(aghfp) && (haveAudio(aghfp) || checkCallFlag(aghfp, CallFlagOpenAudio)) )
				{
					setCallFlags(aghfp, CallFlagResponseAfterAudio);
					aghfpSendInBandRingToneEnable(aghfp, TRUE);
				}
				else
				{
					aghfpSendInBandRingToneEnable(aghfp, FALSE);
				}
			}
	        aghfpSetState(aghfp, aghfp_incoming_call_establish);
			break;
			
		case aghfp_call_type_outgoing:
			/* Always require a response, but not ring alerts, for this type of call */
			setCallFlags(aghfp, CallFlagResponseReqd | CallFlagResponseAfterAudio);
			clearCallFlags(aghfp, CallFlagRingAlertsReqd);
			
			aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_outgoing);
			if ( haveAudio(aghfp) || !checkCallFlag(aghfp, CallFlagOpenAudio) )
			{
				aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_remote_alert);
			}
	        aghfpSetState(aghfp, aghfp_outgoing_call_establish);
			break;
			
		case aghfp_call_type_transfer:
			/* Never require a response or ring alerts for this type of call */
			clearCallFlags(aghfp, CallFlagResponseReqd | CallFlagResponseAfterAudio | CallFlagRingAlertsReqd);
			
			if ( usingHsp(aghfp) )
			{	/* Working in HSP mode */
				/* HSP mandates that audio must be present */
				setCallFlags(aghfp, CallFlagOpenAudio);  /* B-11840: what if audio params are unspecified? */
			}
			else
			{	/* Working in HFP mode */
				/* Call is now setup even though we might not have an audio channel */
			}
			break;
		}
		
		if ( !haveAudio(aghfp) && checkCallFlag(aghfp, CallFlagOpenAudio) && !(checkCallFlag(aghfp, CallFlagResponseReqd) && !checkCallFlag(aghfp, CallFlagResponseAfterAudio)) )
		{	/* Open an audio channel */
			clearCallFlags(aghfp, CallFlagOpenAudio);
			
			if ( usingHsp(aghfp) && checkCallFlag(aghfp, CallFlagRingAlertsReqd) )
			{
				sendRingNotifications(aghfp);
			}
			
			aghfpAudioConnectRequest(aghfp);

			/* Check to see if aghfpAudioConnectRequest resulted in the commencement of a WBS negotiation */
			if(aghfp->audio_connection_state != aghfp_audio_codec_connect)
			{
				/* Only move to the CallProgressWaitAudioOpen state if a WBS negotiation has not been started. */
				setCallProgress(aghfp, CallProgressWaitAudioOpen);
			}
		}
		else if ( checkCallFlag(aghfp, CallFlagResponseReqd) && !(checkCallFlag(aghfp, CallFlagOpenAudio) && checkCallFlag(aghfp, CallFlagResponseAfterAudio)) )
		{	/* Wait for a repsonse from remote end */
			clearCallFlags(aghfp, CallFlagResponseReqd);
			
			if ( checkCallFlag(aghfp, CallFlagRingAlertsReqd) )
			{
				sendRingNotifications(aghfp);
			}
			
			sendCallCreateWaitingIndToApp(aghfp);
			setCallProgress(aghfp, CallProgressWaitResponse);
		}
		else
		{	/* Call setup is complete */
			aghfpSendCallIndicator(aghfp, aghfp_call_active);
			aghfpSendCallSetupIndicator(aghfp, aghfp_call_setup_none);
			setCallProgress(aghfp, CallProgressComplete);
            aghfpSetState(aghfp, aghfp_active_call);
            aghfpSendCallCreateCfmToApp(aghfp, aghfp_call_create_success);
		}
		break;
		
	case CallEventAnswer:
	case CallEventRemoteAnswered:
	case CallEventTerminate:
    case CallEventTerminateHeld:
    case CallEventAcceptHeld:
	case CallEventAudioConnected:
	case CallEventAudioDisconnected:
	case CallEventAudioTransfer:
	case CallEventRing:
		break;
		
	case CallEventSlcRemoved:
		/* SLC has been removed */
		setCallProgress(aghfp, CallProgressIdle);
		aghfpSetState(aghfp, aghfp_ready);
		aghfpSendSlcDisconnectIndToApp(aghfp, convertCallFlagToDisconnectStatus(call_flags));
		break;
		
	default:
		Panic();
	}
}