Download the source code

NOTE: To work with RIL and to compile this sample you have to install the Platform Builder for Windows CE.

Radio Interface Layer (RIL) is an interface between the radio hardware and the CellCore system. This is an abstraction layer which enables to create single driver modal for different radio hardware. This is a part the Platform Builder of Windows CE and is not present in the standard SDKs. So in order to work with the RIL layer, you should install the Platform Builder for Windows CE. The APIs are defined in ril.h and the library file is ril.lib.

RIL consists of two modules: RIL proxy layer and RIL driver layer. The RIL proxy layer is created by Microsoft and RIL driver layer is created by hardware vendors.

To use work with RIL, first we have to initialize the RIL system. The RIL_Initialize API is used to initialize the RIL for the client. The syntax is:

HRESULT RIL_Initialize(DWORD dwIndex, RILRESULTCALLBACK pfnResult, RILNOTIFYCALLBACK pfnNotify, DWORD dwNotificationClasses, DWORD dwParam, HRIL* lphRil);

The first parameter dwIndex is the index of the RIL port to use, this is normally 1.
The second and third parameters are callback function which will be called for different notifications. The fourth parameter represents the classes of notification. This represents different notifications we have to register for. There are different classed for the notification. They are defined in the header file ril.h as:

#define RIL_NCLASS_FUNCRESULT (0x00000000)
#define RIL_NCLASS_CALLCTRL (0x00010000)
#define RIL_NCLASS_MESSAGE (0x00020000)
#define RIL_NCLASS_NETWORK (0x00040000
#define RIL_NCLASS_SUPSERVICE (0x00080000)
#define RIL_NCLASS_PHONEBOOK (0x00100000
#define RIL_NCLASS_SIMTOOLKIT (0x00200000)
#define RIL_NCLASS_MISC (0x00400000)
#define RIL_NCLASS_RADIOSTATE (0x00800000)
#define RIL_NCLASS_POLLING (0x01000000)
#define RIL_NCLASS_NDIS (0x40000000)
#define RIL_NCLASS_DEVSPECIFIC (0x80000000)
#define RIL_NCLASS_ALL (0x01ff0000)

The fifth parameter is an application defined value that will be passed to the callback functions. Sixth parameter is an out parameter which is the returned handle to the RIL instance.

There are two types of callback functions. On is unsolicited callback and other is solicited callback. The parameter pfnResult represents the unsolicited callback function and pfnNotify represents the solicited callback function. The unsolicited callback function (pfnResult ) will be events occur, for example for an incoming call or for incoming SMS messages. The other callback will be called for the responses to the RIL function calls. For example the API RIL_GetCellTowerInfo which is used to retrieve the Cell Tower Information. We use this API in our sample application to retrieve the cell information. The syntax of the callback functions are:

void CALLBACK ResultCallback(DWORD dwCode,HRESULT hrCmdID,const void *lpData,DWORD cbData,DWORD dwParam);
void CALLBACK NotifyCallback(DWORD dwCode,const void *lpData,DWORD cbData, DWORD dwParam);

For ResultCallback function, the dwCode parameter will be the notifiacation code which depends on the notifications. The hrCmdID parameter will be the HRESULT value of the resulting function call. This parameter is used to ensure that the response callbacks are correctly mached with the corresponding function calls. The function call will return and HRESULT and the same HRESULT value will be passed to the ResultCallback function for the response of the particular function. The lpData parameter depents on the notification and wil be different for each notification. The cbData is the size in bytes of the memory that the lpData points to. The dwParam will be the application supplied value supplied in RIL_Initialize call.

For the NotifyCallback function the parameters are same but the HRESULT will not be present.

In our sample application we use the RIL_GetCellTowerInfo API to retrieve the Cell Tower Information. The Cell Tower Information consists of Mobile Country Code (MCC), Mobile Network Code (MNC), Location Area Code (LAC), Cell ID, etc… The MCC is a part of IMSI Number which is uniquely identifies the subscriber and is stored in SIM card. The MCC combined with MNC (MCC/MNC) to identify the networks. For a list of MCCs refer to this link and for MNCs refer to this.

The RIL_GetCellTowerInfo will reurn the RILCELLTOWERINFO in the lpData parameter of the ResultCallback function. This callback will be called for different API calls and it is very important to check the HRESULT value that is returned by the API and the hrCmdID paramter of the ResultCallback function. The RILCELLTOWERINFO structure is defined as:

typedef struct rilcelltowerinfo_tag {
DWORD cbSize;
DWORD dwParams;
DWORD dwMobileCountryCode;
DWORD dwMobileNetworkCode;
DWORD dwLocationAreaCode;
DWORD dwCellID;
DWORD dwBaseStationID;
DWORD dwBroadcastControlChannel;
DWORD dwRxLevel;
DWORD dwRxLevelFull;
DWORD dwRxLevelSub;
DWORD dwRxQuality;
DWORD dwRxQualityFull;
DWORD dwRxQualitySub;
DWORD dwIdleTimeSlot;
DWORD dwTimingAdvance;
DWORD dwGPRSCellID;
DWORD dwGPRSBaseStationID;
DWORD dwNumBCCH;
BYTE rgbBCCH[MAXLENGTH_BCCH];
BYTE rgbNMR[MAXLENGTH_NMR];
} RILCELLTOWERINFO, *LPRILCELLTOWERINFO;

In this sample we are interested in dwMobileCountryCode, dwMobileNetworkCode, dwLocationAreaCode and dwCellID members only. The sample displays these member in a EDIT control.

I have included the binary of the sample which is working well on my HTC TyTn II. It is not tested on other platforms.