Modem Call Control

API Reference


The Modem Call Control (mcc) API functions of this API are provided by the modemService service.

IPC interfaces binding

Here's a code sample binding to modem services:

bindings:
{
   clientExe.clientComponent.le_mcc -> modemService.le_mcc
}

Starting a Call

To initiate a call, create a new call object with a destination telephone number calling the le_mcc_Create() function.

le_mcc_Start() must still initiate the call when ready.

The le_mcc_Start() function initiates a call attempt (it's asynchronous because it can take time for a call to connect).

It's essential to register a handler function to get the call events. Use le_mcc_AddCallEventHandler() API to install that handler function. The handler will be called for all calls' events (incoming and outgoing).

The le_mcc_RemoveCallEventHandler() API uninstalls the handler function.

The following APIs can be used to manage incoming or outgoing calls:

When finished with the call object, call le_mcc_Delete() to free all the allocated resources associated with the object.

This code example uses CallAndPlay() to dial a phone number, and if successful, play a sound file. Once the file has played, the call hangs up.

typedef struct
{
char filePath[MAX_FILE_PATH_BYTES];
}
PlayContext_t;
void CallAndPlay
(
const char* destinationTelPtr,
const char* filePathPtr
)
{
PlayContext_t* contextPtr = (PlayContext_t*)le_mem_ForceAlloc(PlayContextPoolRef);
le_str_Copy(contextPtr->filePath, filePathPtr, sizeof(contextPtr->filePath), NULL);
contextPtr->callRef = le_mcc_Create(destinationTelPtr);
contextPtr->eventHandlerRef = le_mcc_AddCallEventHandler(MyCallEventHandler,
contextPtr);
le_mcc_Start(contextPtr->callRef);
}
static void MyCallEventHandler
(
void* contextPtr
)
{
PlayContext_t* myContextPtr = (PlayContext_t*)contextPtr;
switch (event)
{
{
[...]
le_audio_PlayFile(FileAudioRef, AudioFileFd);
[...]
}
break;
le_mcc_Delete(callRef);
// I don't release the Profile for further use
le_mcc_RemoveCallEventHandler(contextPtr->eventHandlerRef);
le_mem_Release(myContextPtr);
break;
}
}
static void MyAudioFinishedHandler
(
le_audio_PlayComplete reason,
void* contextPtr
)
{
PlayContext_t* myContextPtr = (PlayContext_t*)contextPtr;
le_mcc_HangUp(myContextPtr->callRef); // This will trigger a TERMINATED event.
}

Answering a call

Receiving calls is similar sending calls. Add a handler through le_mcc_AddCallEventHandler() to be notified of incoming calls.

To answer, call le_mcc_Answer(). To reject it, call le_mcc_HangUp().

This code example uses InstallAutomaticAnswer() to install a call event handler that automatically answers incoming calls. The handler function verifies the incoming call is permitted (through a predefined list), and then decides whether to answer or terminate it.

static le_audio_ConnectorRef_t AudioRxConnectorRef = NULL;
static le_audio_ConnectorRef_t AudioTxConnectorRef = NULL;
static le_audio_StreamRef_t MicRef = NULL;
static le_audio_StreamRef_t SpeakerRef = NULL;
static le_audio_StreamRef_t CallRxAudioRef = NULL;
static le_audio_StreamRef_t CallTxAudioRef = NULL;
void InstallAutomaticAnswer
(
void
)
{
le_mcc_AddCallEventHandler( MyVoiceCallEventHandler,
contextPtr);
}
static void MyVoiceCallEventHandler
(
void* contextPtr
)
{
char tel[TEL_NMBR_MAX_BYTES];
switch (event)
{
{
le_mcc_GetRemoteTel(callRef, &tel, sizeof(tel));
if (IsAnAuthorizedIncomingCall(tel) == TRUE)
{
SpeakerRef = le_audio_OpenSpeaker();
CallRxAudioRef = le_audio_OpenModemVoiceRx();
MicRef = le_audio_OpenMic();
CallTxAudioRef = le_audio_OpenModemVoiceTx();
AudioRxConnectorRef = le_audio_CreateConnector();
AudioTxConnectorRef = le_audio_CreateConnector();
le_audio_Connect(AudioRxConnectorRef, speakerRef);
le_audio_Connect (AudioRxConnectorRef, callRxAudioRef);
le_audio_Connect(AudioTxConnectorRef, micRef);
le_audio_Connect (AudioTxConnectorRef, callTxAudioRef);
le_mcc_Answer(callRef);
}
else
{
// Reject the incoming call
le_mcc_HangUp(callRef);
}
}
break;
le_audio_Disconnect(speakerRef);
le_audio_Disconnect(AudioRxConnectorRef);
le_audio_Disconnect(AudioTxConnectorRef);
le_mcc_Delete(callRef);
break;
}
}

Ending all calls

A special function can be used to hang-up all the ongoing calls: le_mcc_HangUpAll(). This function can be used to hang-up any calls that have been initiated through another client like AT commands.

Supplementary service.

Calling Line Identification Restriction (CLIR) can be activated or deactivated by le_mcc_SetCallerIdRestrict API. The status is independent for each call object reference. Status can be read with the le_mcc_GetCallerIdRestrict() API. Default value is LE_OFF (Enable presentation of own phone number to remote).


Copyright (C) Sierra Wireless Inc. Use of this work is subject to license.