Telephony: Handling Phone Call, SIM Card, and Network Information
This tutorial demonstrates how you can get the state of both voice and video calls, get notified when the user makes a voice or video call or hangs up the phone, extract information stored on a SIM card, and get IMEI information.
Warm-up
Become familiar with the Telephony API basics by learning about:
-
Initializing the Telephony Service
Initialize telephony for use.
-
Getting Call Information
Access call information and track changes in call status.
-
Getting SIM Information
Access SIM information and track changes in SIM status.
-
Getting Network Information
Access network information and track changes in network status.
-
Getting Modem Information
Access modem information.
Initializing the Telephony Service
To initialize the telephony service:
In a multi-SIM scenario, you must define which subscription you need, in case the application is related to calling, networks, modems, or SIM cards. Telephony provides a function to create handles for different subscriptions.
-
To use the functions and data types of the Telephony Information API (in mobile and wearable applications), include the <telephony.h> header file in your application:
#include <telephony.h>
-
To create a telephony handle, use the telephony_handle_list_s structure that holds the handles for all the subscriptions defined in telephony_common.h.
typedef struct { unsigned int count; telephony_h *handle; } telephony_handle_list_s;
Pass the telephony_handle_list_s structure pointer to get the telephony handles for all subscriptions. You can send requests to specific subscriptions using the telephony handle for that subscription.
-
Get the telephony handle by using the telephony_init() function.
#include <telephony.h> telephony_handle_list_s handle_list; int main() { int i; ret = telephony_init(&handle_list); // In case of single SIM, we get only one handle if (ret != TELEPHONY_ERROR_NONE) { // Error handling return -1; } for (i = 0; i < handle_list.count; i++) { dlog_print(DLOG_INFO, LOG_TAG, "telephony handle[%p] for subscription[%d]", handle_list.handle[i], i); } return 0; }
-
When the telephony handle is no longer needed, the telephony_deinit() function must be called to free the handle.
void tutorial_telephony_deinit() { ret = telephony_deinit(&handle_list); }
Getting Call Information
To get the voice and video call states and be notified when the user makes a voice or video call or hangs up the phone, use the Telephony Call API (in mobile and wearable applications) in call-related actions:
Getting the Call State
-
You can get the state of the current voice call by using the telephony_call_get_voice_call_state() function. It returns one of the telephony_call_state_e values (in mobile and wearable applications).
void tutorial_telephony_call_get_voice_call_state() { telephony_error_e ret; telephony_call_state_e voice_call_state; ret = telephony_call_get_voice_call_state(handle_list.handle[0], &voice_call_state); if (ret != TELEPHONY_ERROR_NONE) { // Error handling } dlog_print(DLOG_INFO, LOG_TAG, "Voice call state: [%d]", voice_call_state); }
-
You can use the previous process to get to the video call state by replacing voice with video in the function: telephony_call_get_video_call_state().
void tutorial_telephony_call_get_video_call_state() { telephony_error_e ret; telephony_call_state_e video_call_state; ret = telephony_call_get_video_call_state(handle_list.handle[0], &video_call_state); if (ret != TELEPHONY_ERROR_NONE) { // Error handling } dlog_print(DLOG_INFO, LOG_TAG, "Video call state: [%d]", video_call_state); }
Receiving Change Notifications for the Call States
The callback function can be used to obtain change notifications for the call state asynchronously. The call state is returned through a callback function, given to the function as one of its parameters.
-
To be notified when the voice call state changes, implement a callback function compatible with the telephony_noti_cb() function typedef and register this function.
void voice_call_state_noti_cb(telephony_h handle, telephony_noti_e noti_id, void *data, void* user_data) { telephony_call_state_e voice_call_state = *(int *)data; dlog_print(DLOG_INFO, LOG_TAG, "Voice call state: [%d]", voice_call_state); } void tutorial_telephony_set_noti_cb_voice() { telephony_error_e ret; ret = telephony_set_noti_cb(handle_list.handle[0], TELEPHONY_NOTI_VOICE_CALL_STATE, voice_call_state_noti_cb, NULL); if (ret != TELEPHONY_ERROR_NONE) { // Error handling } }
After registering, you are notified of the voice call state until you cancel the registration of the callback function. To unregister the callback, invoke the telephony_unset_noti_cb() function with TELEPHONY_NOTI_VOICE_CALL_STATE.
-
To be notified when the video call state changes, use the same callback function typedef as for the voice calls.
void video_call_state_noti_cb(telephony_h handle, telephony_noti_e noti_id, void *data, void* user_data) { telephony_call_state_e video_call_state = *(int *)data; dlog_print(DLOG_INFO, LOG_TAG, "Video call state: [%d]", video_call_state); } void tutorial_telephony_set_noti_cb_video() { telephony_error_e ret; ret = telephony_set_noti_cb(handle_list.handle[0], TELEPHONY_NOTI_VIDEO_CALL_STATE, video_call_state_noti_cb, NULL); if (ret != TELEPHONY_ERROR_NONE) { // Error handling } }
After registering, you are notified of the video call state information until you cancel the registration of the callback function. To unregister the callback, invoke the telephony_unset_noti_cb() function with TELEPHONY_NOTI_VIDEO_CALL_STATE.
Getting SIM Information
To extract information stored on a SIM card, use the Telephony SIM API (in mobile and wearable applications):
Getting the State of the SIM
Before retrieving information from the SIM card, retrieve the state of the SIM card. You can get SIM-related information only if the state of the SIM is TELEPHONY_SIM_STATE_AVAILABLE.
You can get the state of the SIM card by calling the telephony_sim_get_state() function. It returns the status of the SIM, which is one of the telephony_sim_state_e values (in mobile and wearable applications), through its output parameters.
void tutorial_telephony_sim_get_state() { telephony_sim_state_e state; ret = telephony_sim_get_state(handle_list.handle[0], &state); if (ret != TELEPHONY_ERROR_NONE) { // Error handling return -1; } dlog_print(DLOG_INFO, LOG_TAG, "SIM status: [%d]", status); return 0; }
Receiving Change Notifications for the SIM State
The telephony_noti_cb() callback function can be used to obtain notifications for the changes in the SIM state asynchronously. The SIM status is returned through a callback function, given to the function as one of its parameters.
void sim_state_noti_cb(telephony_h handle, telephony_noti_e noti_id, void *data, void* user_data) { telephony_sim_state_e sim_state = *(int *)data; dlog_print(DLOG_INFO, LOG_TAG, "SIM state: [%d]", sim_state); } void tutorial_telephony_set_noti_cb_sim() { telephony_error_e ret; ret = telephony_set_noti_cb(handle_list.handle[0], TELEPHONY_NOTI_SIM_STATUS, sim_state_noti_cb, NULL); if (ret != TELEPHONY_ERROR_NONE) { // Error handling } return 0; }
The callback function is invoked automatically when the status of the SIM changes, if you register the callback function using the telephony_set_noti_cb() function.
Once the callback function of the SIM state change is registered, this callback function is invoked until it is unregistered with the telephony_unset_noti_cb() function by passing the notification ID.
Getting SIM Information
If you know the current SIM state and, for example, it is SIM_STATE_AVAILABLE, call the SIM API to get the following information from the SIM card: ICC-ID, MCC, MNC, SPN, Subscriber name, and Subscriber number.
If you do not get an error (SIM_ERROR_NONE), the requested SIM information is received and stored in an output parameter. You must free all returned variables once you are done with them.
To get ICCID information from a SIM card:
void tutorial_telephony_sim_get_icc_id() { telephony_error_e ret; char *iccid; ret = telephony_sim_get_icc_id(handle_list.handle[0], &iccid); if (ret == TELEPHONY_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "Integrated Circuit Card IDentification: %s", iccid); free(iccid); return ret; }
Getting Network Information
To access, but not change, information about the current cellular network and telephony service, use the Telephony Network API (in mobile and wearable applications):
Getting the Network Service State
Determine the state of the service network. The network service state is one of the telephony_network_service_state_e enumeration values (in mobile and wearable applications).
You can only get telephony network information if the state is TELEPHONY_NETWORK_SERVICE_STATE_IN_SERVICE.
void tutorial_telephony_network_get_service_state() { telephony_network_service_state_e network_service_state; int ret; ret = telephony_network_get_service_state(handle_list.handle[0], &network_service_state); if (ret != TELEPHONY_ERROR_NONE) { // Error handling return -1; } dlog_print(DLOG_INFO, LOG_TAG, "Network Service State [%d]", network_service_state); return 0; }
Receiving Network Service State Change Notifications
The telephony_noti_cb() callback function can be used to obtain change notifications for a network asynchronously. The network status is returned through a callback function, given to the function as one of its parameters.
The Telephony Network API provides change notifications for the following information:
- Network service state changes (telephony_set_noti_cb(), TELEPHONY_NOTI_NETWORK_SERVICE_STATE)
- Cell ID changes (telephony_set_noti_cb(), TELEPHONY_NOTI_NETWORK_CELLID)
- Roaming state changes (telephony_set_noti_cb(), TELEPHONY_NOTI_NETWORK_ROAMING_STATUS)
- Signal strength changes (telephony_set_noti_cb(), TELEPHONY_NOTI_NETWORK_SIGNALSTRENGTH_LEVEL)
void network_service_state_noti_cb(telephony_h handle, telephony_noti_e noti_id, void *data, void* user_data) { telephony_network_service_state_e network_state = *(int *)data; dlog_print(DLOG_INFO, LOG_TAG, "SIM state: [%d]", network_state); } void tutorial_telephony_set_noti_cb_network() { telephony_error_e ret; ret = telephony_set_noti_cb(handle_list.handle[0], TELEPHONY_NOTI_NETWORK_SERVICE_STATE, network_service_state_noti_cb, NULL); if (ret != TELEPHONY_ERROR_NONE) { // Error handling } return 0; }
The callback function is invoked automatically when the status of the network changes, if you register the callback function using the telephony_set_noti_cb() function. To get additional notifications when the Cell ID, RSSI level, or roaming state changes, define corresponding callback functions. Register each one of them with their corresponding notification ID.
Once the callback function of the network state change is registered, this callback function is invoked until it is unregistered with the telephony_unset_noti_cb() function by passing the notification ID.
Getting Network Information
If the current network service state is NETWORK_INFO_SERVICE_STATE_IN_SERVICE, use the Telephony Network API to get the network information: LAC, Cell ID, RSSI, roaming state, MNC, network provider name, and network type.
You must free all returned variables (strings) once you are done with them.
To get network information:
-
To get the Cell ID:
void tutorial_telephony_network_get_cell_id() { telephony_error_e ret; int cell_id; ret = telephony_network_get_cell_id(handle_list.handle[0], &cell_id); if (ret == TELEPHONY_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "Cell Id: %d", cell_id); return ret; }
-
To get the MNC:
void tutorial_telephony_network_get_mnc() { telephony_error_e ret; char *mnc; ret = telephony_network_get_mnc(handle_list.handle[0], &mnc); if (ret == TELEPHONY_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "mnc: %s", mnc); free(mnc); return ret; }
Getting Modem Information
To get IMEI information, use the Telephony Modem API (in mobile and wearable applications):
Use the telephony_modem_get_imei() function, and free all returned variables (strings) once you are done with them.
void tutorial_telephony_modem_get_imei() { telephony_error_e ret; char *imei; ret = telephony_modem_get_imei(handle_list.handle[0], &imei); if (ret == TELEPHONY_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "imei: %s", imei); free(imei); return ret; }