/**************************************************************************** NAME sinkDialStoredNumber DESCRIPTION Dials a number stored in CONFIG_PHONE_NUMBER If HFP and connected - issues command If HFP and not connected - connects and issues if not in call If HSP sends button press RETURNS void */ void sinkDialStoredNumber ( void ) { uint16 ret_len; Sink sink; uint16 phone_number_key[SIZE_CONFIG_PHONE_NUMBER]; CM_DEBUG(("sinkDialStoredNumber\n")) ; if ((ret_len = ConfigRetrieve(CONFIG_PHONE_NUMBER, phone_number_key, SIZE_CONFIG_PHONE_NUMBER ))) { if((HfpLinkGetSlcSink(hfp_primary_link, &sink)) && SinkIsValid(sink)) { /* Send the dial request now */ CM_DEBUG(("CM:Dial Stored Number (Connected) len=%x\n",ret_len)) ; HfpDialNumberRequest(hfp_primary_link, ret_len, (uint8 *)&phone_number_key[0]); } else { /* Not connected, connect and queue the dial request */ #ifdef ENABLE_AVRCP sinkAvrcpCheckManualConnectReset(NULL); #endif MessageSend ( &theSink.task , EventUsrEstablishSLC , 0 ) ; sinkQueueEvent( EventUsrDialStoredNumber ) ; } } else { /*The PSKEY could not be read*/ MessageSend(&theSink.task, EventUsrUpdateStoredNumber, 0); } }
/**************************************************************************** NAME linkPolicySetLinkinActiveMode DESCRIPTION set the link as active mode for phonebook access RETURNS void */ void linkPolicySetLinkinActiveMode(Sink sink) { LP_DEBUG(("LP: Set Link in Active Mode for Pbapc Access\n")); if(SinkIsValid(sink)) { ConnectionSetLinkPolicy(sink, 1 , lp_powertable_pbap_access); } }
static void linkPolicySetDataActiveMode(Sink sink) { LP_DEBUG(("LP: Set Link in Active Mode for data access\n")); if(SinkIsValid(sink)) { ConnectionSetLinkPolicy(sink, 1 , lp_powertable_data_access); } }
/**************************************************************************** NAME linkPolicyGetRole DESCRIPTION Request CL to get the role for a specific sink if one passed, or all connected HFP sinks if NULL passed. RETURNS void */ void linkPolicyGetRole(Sink* sink_passed) { /* no specific sink to check, check all available - happens on the back of each hfp connect cfm * and handleA2DPSignallingConnected */ LP_DEBUG(("LP: linkPolicyGetRole - sink = %x\n",(uint16)*sink_passed)); if (sink_passed) { if (SinkIsValid(*sink_passed) ) { /*only attempt to switch the sink that has failed to switch*/ ConnectionGetRole(&theSink.task , *sink_passed) ; LP_DEBUG(("LP: GET 1 role[%x]\n", (int)*sink_passed)); } } }
/**************************************************************************** NAME sinkUpdateStoredNumber DESCRIPTION Request a number to store from the primary AG RETURNS void */ void sinkUpdateStoredNumber (void) { Sink sink; /* validate HFP available for use, i.e. AG connected */ if((HfpLinkGetSlcSink(hfp_primary_link, &sink))&&SinkIsValid(sink)) { /* Request user select a number on the AG */ HfpVoiceTagNumberRequest(hfp_primary_link); } else { /* Connect and queue request */ #ifdef ENABLE_AVRCP sinkAvrcpCheckManualConnectReset(NULL); #endif MessageSend ( &theSink.task , EventUsrEstablishSLC , 0 ) ; sinkQueueEvent( EventUsrUpdateStoredNumber ) ; } }
/**************************************************************************** NAME hfpSlcCheckAtAck DESCRIPTION Generic handler for AT Acks during SLC establishment RETURNS TRUE if Ack was successful, FALSE otherwise */ bool hfpSlcCheckAtAck(hfp_link_data* link, hfp_lib_status status) { /* An AT command in the SLC establishment has failed */ if(status != hfp_success) { /* If we have an RFCOMM connection we want to get rid of it */ if(link->ag_slc_state == hfp_slc_connected && SinkIsValid(hfpGetLinkSink(link))) { /* We have a valid RFCOMM connection still, tear it down */ hfpSendCommonInternalMessage(HFP_INTERNAL_SLC_DISCONNECT_REQ, link); /* NB. When disconnecting in hfp_slc_connected this can result in two disconnect requests being sent to the CL. This either results in the CL rejecting the request with status rfcomm_disconnect_unknown_sink which we ignore, or BlueStack rejecting the request with RFC_INVALID_CHANNEL which the CL does not forward on to us. In both cases only one HFP_SLC_CONNECT_CFM will be sent to the app when disconnected */ } return FALSE; } return TRUE; }
/**************************************************************************** DESCRIPTION configure the sub woofer and connect its audio if present */ void CsrA2dpDecoderPluginSetSubWoofer(AUDIO_SUB_TYPE_T sub_type, Sink sub_sink) { DECODER_t * DECODER = CsrA2dpDecoderGetDecoderData(); /* ensure the decoder is loaded */ if(DECODER) { A2dpPluginConnectParams *codecData = (A2dpPluginConnectParams *) DECODER->params; /* update the decoder params with the new sub woofer status */ codecData->sub_woofer_type = sub_type; codecData->sub_sink = sub_sink; /* determine sub woofer type and connect (or disconnect if gone away) the sink to the appropriate dsp port */ switch(sub_type) { /* SUB no longer available, disconnect port if still connected */ case AUDIO_SUB_WOOFER_NONE: PRINT(("DECODER: Disconnect woofer\n" )); /* if source is still connected then disconnect it */ if(codecData->sub_connection_port != DSP_SUB_PORT_NOT_CONNECTED) { /* determine if the subwoofer has connected after the decoder was loaded, configured and unmuted */ if(codecData->sub_is_available == FALSE) { /* mute the outputs whilst the subwoofer port is connected and decoder restarted */ csrA2dpDecoderPluginOutputMute(multi_channel_group_all, AUDIO_MUTE_ENABLE); } PRINT(("DECODER: Disconnect kalimba port %x\n", codecData->sub_connection_port)); StreamDisconnect(StreamKalimbaSource(codecData->sub_connection_port), 0); /* update connected ports state */ codecData->sub_connection_port = DSP_SUB_PORT_NOT_CONNECTED; /* set volume levels to desired level */ SubConnectedNowUnmuteVolume(DECODER); /* determine if the subwoofer has connected after the decoder was loaded, configured and unmuted */ if(codecData->sub_is_available == FALSE) { /* unmute the outputs again */ csrA2dpDecoderPluginOutputMute(multi_channel_group_all, AUDIO_MUTE_DISABLE); } } break; /* SUB using esco as its bt link, connect to dsp port 2 */ case AUDIO_SUB_WOOFER_ESCO: PRINT(("DECODER: connect esco dsp port 2, sub_sink = %x\n", (uint16)sub_sink )); /* ensure the correct ype of link is requested */ if(DECODER->sink_type != AUDIO_SINK_AV) { /* connect SUB output from dsp, source port 2, to esco sink */ if(codecData->sub_connection_port != DSP_ESCO_SUB_PORT) { /* determine if the subwoofer has connected after the decoder was loaded, configured and unmuted */ if(codecData->sub_is_available == FALSE) { /* mute the outputs whilst the subwoofer port is connected and decoder restarted */ csrA2dpDecoderPluginOutputMute(multi_channel_group_all, AUDIO_MUTE_ENABLE); } /* if not already connected */ if(codecData->sub_connection_port == DSP_L2CAP_SUB_PORT) { /* wrong port connected, disconnect it first */ StreamDisconnect(StreamKalimbaSource(codecData->sub_connection_port), 0); PRINT(("DECODER: Disconnect kalimba port %x\n", codecData->sub_connection_port)); } /* ensure sink is valid */ if(SinkIsValid(sub_sink)) { /* connect esco (2) port */ if(StreamConnect(StreamKalimbaSource(DSP_ESCO_SUB_PORT),sub_sink)) { /* update connected ports state */ codecData->sub_connection_port = DSP_ESCO_SUB_PORT; PRINT(("DECODER: Connect kalimba port %x\n", codecData->sub_connection_port)); /* set volume levels to desired level */ SubConnectedNowUnmuteVolume(DECODER); } else PRINT(("DECODER: connect esco dsp port 2 FAILED\n" )); } else { PRINT(("DECODER: connect esco dsp port 2, sub_sink = %x NOT VALID\n", (uint16)sub_sink )); } /* determine if the subwoofer has connected after the decoder was loaded, configured and unmuted */ if(codecData->sub_is_available == FALSE) { /* unmute the outputs again */ csrA2dpDecoderPluginOutputMute(multi_channel_group_all, AUDIO_MUTE_DISABLE); } } } else PRINT(("DECODER: ESCO - ****wrong link type****\n")); break; /* SUB using l2cap as its bt link, connect to dsp port 3 */ case AUDIO_SUB_WOOFER_L2CAP: PRINT(("DECODER: connect l2cap dsp port 3, sub_sink = %x\n", (uint16)sub_sink )); /* ensure the correct ype of link is requested */ if(DECODER->sink_type == AUDIO_SINK_AV) { /* connect SUB output from dsp, source port 2, to esco sink */ if(codecData->sub_connection_port != DSP_L2CAP_SUB_PORT) { /* determine if the subwoofer has connected after the decoder was loaded, configured and unmuted */ if(codecData->sub_is_available == FALSE) { /* mute the outputs whilst the subwoofer port is connected and decoder restarted */ csrA2dpDecoderPluginOutputMute(multi_channel_group_all, AUDIO_MUTE_ENABLE); } /* if not already connected */ if(codecData->sub_connection_port == DSP_ESCO_SUB_PORT) { /* wrong port connected, disconnect it first */ StreamDisconnect(StreamKalimbaSource(codecData->sub_connection_port), 0); PRINT(("DECODER: Disconnect kalimba port %x\n", codecData->sub_connection_port)); } /* ensure sink is valid */ if(SinkIsValid(sub_sink)) { /* connect l2cap (3) port */ if(StreamConnect(StreamKalimbaSource(DSP_L2CAP_SUB_PORT),sub_sink)) { /* update connected ports state */ codecData->sub_connection_port = DSP_L2CAP_SUB_PORT; PRINT(("DECODER: Connect kalimba port %x\n", codecData->sub_connection_port)); /* set volume levels to desired level */ SubConnectedNowUnmuteVolume(DECODER); } else PRINT(("DECODER: connect l2cap dsp port 3 FAILED\n" )); } else { PRINT(("DECODER: connect l2cap dsp port 3, sub_sink = %x NOT VALID\n", (uint16)sub_sink )); } /* determine if the subwoofer has connected after the decoder was loaded, configured and unmuted */ if(codecData->sub_is_available == FALSE) { /* unmute the outputs again */ csrA2dpDecoderPluginOutputMute(multi_channel_group_all, AUDIO_MUTE_DISABLE); } } } else PRINT(("DECODER: L2CAP - ****wrong link type****\n")); break; } } else PRINT(("DECODER: CsrA2dpDecoderPluginSetSubWoofer ERROR NO DECODER\n" )); }