Skip to main content

How to use GSM Modem

A GSM modem is a specialized type of modem which accepts a SIM card, and operates over a subscription to a mobile operator, just like a mobile phone.

This tutorial will explain how to interface a GSM modem with Toradex modules. In this tutorial, Telit GL868 GSM modem has been interfaced with Iris Board V1.1A.

  1. GSM Modem works on Serial communication.

  2. Iris Board V1.1A has 3 com port available on Connector X13 and X14 for serial communication, we can use any one, as for GSM Modem we need RXD & TXD Only.

  3. Connect X14 connector to UART Port of GSM Modem with Serial cable.

    GSM Modem Interface

Header file for GSM Modem

Follow this tutorial up to step 9 to create a new VC++ project. Right click on Header Files > Add > New Item...

Click on Header File (.h) and name it gsmmodem.h

Copy this code in gsmmodem.h


/// @file gsmmodem.h
/// @copyright Copyright (c) 2014 Toradex AG
/// @date $ 2014-03-26 $
/// @brief Contains function declarations to be used to access GSM Modem

#ifndef _GSMMODEM_H_
#define _GSMMODEM_H_

#include <windows.h>

#define DELIVERY_REPORT_SMS_SENT 0
#define DELIVERY_REPORT_SMS_DELIVERED 1
#define IMEI_NUMBER_MAX_LENGTH 15
#define DATE_MAX_LENGTH 8
#define TIME_MAX_LENGTH 11

//******************************************************************************
/// Configure COM port to communicate with GSM modem
/// @param[out] port COM port for GSM modem
/// @param[in] baudRate Baudrate for communication
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmOpen(HANDLE *port, DWORD baudRate);

//******************************************************************************
/// Send SMS to a phone number
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[in] phoneNumber Phone number to which SMS is send
/// @param[in] message Message to send in SMS
/// @param[out] deliveryReport Message delivery report
/// @retval TRUE Success
/// FALSE See GetLastError()
BOOL GsmSendSms(HANDLE port, char *phoneNumber, char *message, DWORD *deliveryReport);

//******************************************************************************
/// Read received SMS
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[in] messageIndex Index of received SMS
/// @param[out] senderPhoneNumber SMS sender phone number
/// @param[out] dateTimeStamp Date and time of received SMS
/// @param[out] message Message received in SMS
/// @param[in] messageSize Message size
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmRecieveSms(HANDLE port, char *messageIndex, char *senderPhoneNumber, char *dateTimeStamp, char *message, DWORD messageSize);

//******************************************************************************
/// Delete SMS
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[in] messageIndex Index of SMS to be deleted
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmDeleteSms(HANDLE port, char *messageIndex);

//******************************************************************************
/// Give miss call on a phone number
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[in] phoneNumber Phone number
/// @param[out] deliveryReport delivery report
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmGiveMissCall(HANDLE port, char *phoneNumber, DWORD *deliveryReport);

//******************************************************************************
/// Close COM port used for GSM modem
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmClose(HANDLE *port);

//******************************************************************************
/// Send AT command to GSM modem
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[in] commandString AT command to be send
/// @param[in] terminate End of message
/// @param[in] responseString Expected AT command response
/// @retval TRUE Success
/// FALSE Failure
BOOL SendATCommand(HANDLE port, char *commandString, BOOL terminate, char *responseString);

//******************************************************************************
/// Gets IMEI number of the modem
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[out] imeiNumber IMEI number of the device
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmGetIMEINumber(HANDLE port, char *imeiNumber);

//******************************************************************************
/// Gets information about modem manufacturer
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[out] manufacturer Manufacturer information
/// @param[out] modelNumber Model number of modem
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmGetManufacturerInfo(HANDLE port, char *manufacturer, char *modelNumber);

//******************************************************************************
/// Gets SIM pin status
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[out] status SIM status
/// @retval Returns the status of SIM
BOOL GsmGetSIMStaus(HANDLE port, DWORD *status);

//******************************************************************************
/// Gets information of SIM registration and network provider
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[out] status Status of SIM registration
/// @param[out] networkProvider Network provider information
/// @retval TRUE Success
/// @retval FALSE Failure
BOOL GsmGetNetworkRegistrationSIMStaus(HANDLE port, DWORD *status, char *networkProvider);

//******************************************************************************
/// Gets signal strength information
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[out] signalStrength signal strength information
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmGetSignalStength(HANDLE port, char *signalStrength);

//******************************************************************************
/// Gets Network Date and Time Information
/// @param[in] port GSM Port Handle returned by call to GsmOpen().
/// @param[out] date Pointer to date string
/// @param[out] time Pointer to time string
/// @retval TRUE Success
/// FALSE Failure
BOOL GsmGetNetworkDateTimeInformation(HANDLE port, char *date, char *time);

#endif // _GSMMODEM_H_

Source file for GSM Modem

Right click on Source Files > Add > New Item...

Click on C++ file (.cpp) and name it gsmmodem.c

Copy and paste this code in gsmmodem.c


/// @file gsmmodem.c
/// @copyright Copyright (c) 2014 Toradex AG
/// @date $ 2014-03-26 $
/// @brief Contains function to be used to access GSM Modem

#include <windows.h>
#include "gsmmodem.h"

//******************************************************************************
BOOL GsmOpen(HANDLE *port, DWORD baudRate)
{
DCB PortDCB; ///< COM port configuration structure
BOOL returnValue = 0;
COMMTIMEOUTS comTimeOut;
/// Open Interface to reader
*port = CreateFile(TEXT("COM2:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);
if (*port == INVALID_HANDLE_VALUE)
{
printf("Error Opening COM Port\n");
Sleep(1000);
*port = NULL;
return FALSE;
}
/// COM Port Configuration

/// Initialize the DCBlength member.
PortDCB.DCBlength = sizeof(DCB);
/// Get the default port setting information.
GetCommState(*port, &PortDCB);
/// Change the DCB structure settings.
PortDCB.BaudRate = baudRate; ///< Current baudrate
PortDCB.fBinary = TRUE; ///< Binary mode; no EOF check
PortDCB.fParity = FALSE; ///< Disable parity checking
PortDCB.fOutxCtsFlow = FALSE; ///< No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE; ///< No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_DISABLE; ///< Disable DTR flow control type
PortDCB.fDsrSensitivity = FALSE; ///< DSR sensitivity
PortDCB.fTXContinueOnXoff = TRUE; ///< XOFF continues Tx
PortDCB.fOutX = FALSE; ///< No XON/XOFF out flow control
PortDCB.fInX = FALSE; ///< No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE; ///< Disable error replacement
PortDCB.fNull = FALSE; ///< Disable null stripping
PortDCB.fRtsControl = RTS_CONTROL_ENABLE; ///< Disable RTS flow control
PortDCB.fAbortOnError = FALSE; ///< Do not abort reads/writes on error
PortDCB.ByteSize = 8; ///< Number of bits/byte, 4-8
PortDCB.Parity = NOPARITY; ///< 0 - 4 = no, odd, even, mark, space
PortDCB.StopBits = ONESTOPBIT; ///< 0, 1, 2 = 1, 1.5, 2

/// Configure the port according to the specifications of the DCB structure.
if (!SetCommState (*port, &PortDCB))
{
/// Could not configure the serial port.
printf("Error Configuring COM2 Port\n");
return FALSE;
}

/// Get Communication time out values
returnValue = GetCommTimeouts(*port, &comTimeOut);
comTimeOut.ReadIntervalTimeout = 10;
comTimeOut.ReadTotalTimeoutMultiplier = 1;
comTimeOut.ReadTotalTimeoutConstant = 1;
/// Set Communication time out values
returnValue = SetCommTimeouts(*port, &comTimeOut);
return TRUE;
}

//******************************************************************************
BOOL GsmSendSms(HANDLE port, char *phoneNumber, char *message, DWORD *deliveryReport)
{
DWORD bytesTransmitted = 0;
DWORD bytesRead = 0;
BYTE readBuffer[1024] = {0};
BOOL returnValue = 0;
BYTE byteTransmit[4] = {0};

/// Input parameter check
if (port == NULL || phoneNumber == NULL || strlen(phoneNumber) < 13 || message == NULL || strlen(message) > 160)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
returnValue = SendATCommand(port, "AT+CMGS=\"", FALSE, 0);
returnValue = SendATCommand(port, phoneNumber, FALSE, 0);
returnValue = SendATCommand(port, "\"", TRUE, ">");
WriteFile(port, message, strlen(message), &bytesTransmitted, NULL);
byteTransmit[0] = 26; ///< SMS Termination character
WriteFile(port, byteTransmit, 1, &bytesTransmitted, NULL);

/// Wait for +CMGS:
Sleep(1000);
returnValue = ReadFile(port, readBuffer, 100, &bytesRead, NULL); ///< False = Failure

/// Set deliveryReport
if (deliveryReport != NULL)
{

}
return TRUE;
}

//******************************************************************************
BOOL SendATCommand(HANDLE port, char *commandString, BOOL terminate, char *responseString)
{
DWORD timeOut = 50; ///< 2.5 Seconds + ReadFile Delay
DWORD noOfBytesRead = 0;
DWORD bytesTransmitted = 0;
BYTE readBuffer[100] = {0};

WriteFile(port, commandString, strlen(commandString), &bytesTransmitted, NULL); ///< Send command to GSM modem
if (terminate == 1) WriteFile(port, "\r\n", 2, &bytesTransmitted, NULL);

if (responseString == NULL)
{
return TRUE;
}
while (timeOut) ///< If response to command is expected
{
// memset(readBuffer, 0, 100);
ReadFile(port, readBuffer, 100, &noOfBytesRead, NULL);
if (strstr(readBuffer, responseString))
{
return TRUE;
}
else
{
Sleep(50);
}
timeOut--;
}
return FALSE;
}

//******************************************************************************
BOOL GsmRecieveSms(HANDLE port, char *messageIndex, char *senderPhoneNumber, char *dateTimeStamp, char *message, DWORD messageSize)
{
BOOL returnValue = 0;
char readBuffer[256] = {0};
DWORD bytesRead = 0;

returnValue = SendATCommand(port, "AT+CMGR=", FALSE, 0);
returnValue = SendATCommand(port, messageIndex, TRUE, 0);

ReadFile(port, readBuffer, 256, &bytesRead, NULL);
Sleep(1000);
ReadFile(port, readBuffer, 256, &bytesRead, NULL);
if (!strstr(readBuffer, "+91"))
{
return FALSE;
}
strncat_s(senderPhoneNumber, 16, strstr(readBuffer, "+91"), 13); ///< Phone number string length = 13, +919876543210
strncat_s(dateTimeStamp, 21, strstr(readBuffer, "/") - 2, 20); ///< Date time string length = 20, "12/12/24,18:08:44+22" "YY/MM/DD,HH:MM+SS"
strncat_s(message, 160, strstr(readBuffer, "/") + 18, 160);
message[strlen(message) - 1] = 0;
message[strlen(message) - 2] = 0;
message[strlen(message) - 3] = 0;
/// Sort out time, date , message, sender's phone number
return TRUE;
}

//******************************************************************************
BOOL GsmDeleteSms(HANDLE port, char *messageIndex)
{
BOOL returnValue = 0;

returnValue = SendATCommand(port, "AT+CMGD=", FALSE, 0);
if (returnValue == TRUE)
{
returnValue = SendATCommand(port, messageIndex, TRUE, "OK");
if (returnValue)
{
return TRUE; ///< Command Success
}
else
{
return FALSE; ///< Command Failure
}
}
else
{
return FALSE; ///< Command Failure
}

}

//******************************************************************************
BOOL GsmGiveMissCall(HANDLE port, char *phoneNumber, DWORD *deliveryReport)
{
BOOL returnValue = 0;

returnValue = SendATCommand(port, "ATD", FALSE, 0);
returnValue = SendATCommand(port, phoneNumber, FALSE, 0);
returnValue = SendATCommand(port, ";", TRUE, "OK");
if (returnValue)
{
Sleep(7500);
returnValue = SendATCommand(port, "ATH", TRUE, "OK");
}
else
{
return FALSE;
}
return TRUE;

}

//******************************************************************************
BOOL GsmClose(HANDLE *port)
{
if (*port == NULL)
{
return FALSE;
}

CloseHandle(*port);
*port = NULL;
return TRUE;
}

//******************************************************************************
BOOL GsmGetIMEINumber(HANDLE port, char *imeiNumber)
{
DWORD noOfBytesTransmitted = 0;
DWORD noOfBytesRead = 0;
char readBuffer[32] = {0};

WriteFile(port, "AT+CGSN\r\n", 8, &noOfBytesTransmitted, NULL);
Sleep(250);
ReadFile(port, readBuffer, 32, &noOfBytesRead, NULL); ///< Receive IMEI number in response
if (noOfBytesRead >= IMEI_NUMBER_MAX_LENGTH + 2)
{
strncpy_s(imeiNumber, IMEI_NUMBER_MAX_LENGTH + 1, readBuffer + 2, IMEI_NUMBER_MAX_LENGTH);
return TRUE;
}
else
{
return FALSE;
}
}

//******************************************************************************
BOOL GsmGetManufacturerInfo(HANDLE port, char *manufacturer, char *modelNumber)
{
DWORD noOfBytesTransmitted = 0;
DWORD noOfBytesRead = 0;
char readBuffer[100] = {0};

while (TRUE)
{
ReadFile(port, readBuffer, 100, &noOfBytesRead, NULL);
memset(readBuffer, 0, 100);
if (noOfBytesRead == 0)
{
break;
}
}

WriteFile(port, "AT+CGMI\r\n", 9, &noOfBytesTransmitted, NULL);
Sleep(250);
ReadFile(port, readBuffer, 100, &noOfBytesRead, NULL); ///< Get manufacturer information in response
if (noOfBytesRead == 0)
{
return FALSE;
}
else
{
strncat_s(manufacturer, 100, readBuffer + 2, strlen(readBuffer)- 10);
}

WriteFile(port, "AT+CGMM\r\n", 9, &noOfBytesTransmitted, NULL);
Sleep(250);
ReadFile(port, readBuffer, 100, &noOfBytesRead, NULL); ///< Get model identification in response
if (noOfBytesRead == 0)
{
return FALSE;
}
else
{
strncat_s(modelNumber, 100, readBuffer + 2, strlen(readBuffer)- 10);
return TRUE;
}
}

//******************************************************************************
BOOL GsmGetSIMStaus(HANDLE port, DWORD *status)
{
if (!SendATCommand(port, "AT+CPIN?", TRUE, "+CPIN")) ///< Check if SIM is inserted and if PIN required
{
return FALSE;
}
return TRUE;
}

//******************************************************************************
BOOL GsmGetNetworkRegistrationSIMStaus(HANDLE port, DWORD *status, char *networkProvider)
{
DWORD noOfBytesTransmitted = 0;
DWORD noOfBytesRead = 0;
DWORD length = 0;
DWORD timeout = 100;
char readBuffer[100] = {0};
char *start = NULL;
char *end = NULL;

*status = SendATCommand(port, "AT+CREG?", TRUE, "+CREG: 0,1"); ///< Check registration status

if (*status == 1)
{
WriteFile(port, "AT+COPS?\r\n", 10, &noOfBytesTransmitted, NULL);
Sleep(250);
ReadFile(port, readBuffer, 100, &noOfBytesRead, NULL); ///< Get network information
if (noOfBytesRead == 0)
{
return FALSE;
}
else
{
start = strstr(readBuffer, "\"");
end = strstr(start + 1, "\"");
if (!start || !end)
{
return FALSE;
}
length = end - start;
strncat_s(networkProvider, 50, start, length);
return TRUE;
}
}
else
{
return FALSE;
}
}

//******************************************************************************
BOOL GsmGetSignalStength(HANDLE port, char *signalStrength)
{
DWORD noOfBytesTransmitted = 0;
DWORD noOfBytesRead = 0;
DWORD length = 0;
char readBuffer[100] = {0};
char *start = NULL;
char *end = NULL;

WriteFile(port, "AT+CSQ\r\n", 8, &noOfBytesTransmitted, NULL);
Sleep(250);
ReadFile(port, readBuffer, 100, &noOfBytesRead, NULL); ///< Get network signal strength
if (noOfBytesRead == 0)
{
return FALSE;
}
else
{
start = strstr(readBuffer, ": ");
end = strstr(start + 1, ",");
if (!start || !end)
{
return FALSE;
}
length = end - (start + 2);
strncat_s(signalStrength, 4, (start + 2), length);
return TRUE;
}
}

//******************************************************************************
BOOL GsmGetNetworkDateTimeInformation(HANDLE port, char *date, char *time)
{
DWORD noOfBytesTransmitted = 0;
DWORD noOfBytesRead = 0;
char readBuffer[100] = {0};
char *start = NULL;
char *end = NULL;
DWORD length = 0;

WriteFile(port, "AT+CCLK?\r\n", 10, &noOfBytesTransmitted, NULL);
Sleep(250);
ReadFile(port, readBuffer, 100, &noOfBytesRead, NULL);
if (noOfBytesRead == 0)
{
return FALSE;
}
else
{
start = strstr(readBuffer, "\"");
end = strstr(start + 1, ",");
if (!start || !end)
{
return FALSE;
}
length = end - (start + 1);
strncat_s(date, DATE_MAX_LENGTH + 1, (start + 1), length);

start = strstr(readBuffer, ",");
end = strstr(start + 1, "\"");
if (!start || !end)
{
return FALSE;
}
length = end - (start + 1);
strncat_s(time, TIME_MAX_LENGTH + 1, (start + 1), length);
return TRUE;
}
}

Main function code


#include <windows.h>
#include "gsmmodem.h"

int wmain(void)
{
HANDLE gsmHandle = NULL; ///< Handle for COM port
BOOL returnValue = 0; ///< variable holding return values
char phoneNumber[16] = {0};
char messageRecieved[160] = {0};
char dateTimeStamp[21] = {0};
char IMEINumber[IMEI_NUMBER_MAX_LENGTH + 1] = {0};
char manufacturerName[100] = {0};
char modelNumber[100] = {0};
char networkProvider[50] = {0};
char signalStrength[4] = {0};
char date[DATE_MAX_LENGTH + 1] = {0};
char time[TIME_MAX_LENGTH + 1] = {0};
DWORD SimStatus = 0;
DWORD networkStatus = 0;

/// Configure COM port for GSM modem
returnValue = GsmOpen(&gsmHandle, 9600);
if (returnValue == FALSE)
{
printf("cannot open port \n");
getchar();
return FALSE;
}
returnValue = SendATCommand(gsmHandle, "AT", TRUE, "OK"); ///< Check communication with modem
if (returnValue == FALSE)
{
printf("error \n");
getchar();
return FALSE;
}
returnValue = SendATCommand(gsmHandle, "ATE0", TRUE, "OK"); ///< Disable echo
if (returnValue == FALSE)
{
printf("cannot disable echo \n");
getchar();
return FALSE;
}

returnValue = GsmGetIMEINumber(gsmHandle, IMEINumber);
if (returnValue == FALSE)
{
printf("error in obtaining IMEI number \n");
getchar();
return FALSE;
}
printf(" IMEI = %s\n", IMEINumber);
returnValue = GsmGetManufacturerInfo(gsmHandle, manufacturerName, modelNumber);
if (returnValue == FALSE)
{
printf("error in obtaining manufacturer information \n");
getchar();
return FALSE;
}
printf(" Manufacturer Name = %s, Model Number = %s\n", manufacturerName, modelNumber);
returnValue = GsmGetSIMStaus(gsmHandle, &SimStatus);
if (returnValue == FALSE)
{
printf("error to obtain SIM status\n");
getchar();
return FALSE;
}
returnValue = GsmGetSignalStength(gsmHandle, signalStrength);
if (returnValue == FALSE)
{
getchar();
return FALSE;
}
printf(" Signal Strength = %s \n", signalStrength);
returnValue = GsmGetNetworkRegistrationSIMStaus(gsmHandle, &networkStatus, networkProvider);
if (returnValue == FALSE)
{
getchar();
return FALSE;
}
printf(" Network Status = %d, Network Provider = %s \n", networkStatus, networkProvider);

returnValue = GsmGetNetworkDateTimeInformation(gsmHandle, date, time);
if (returnValue == FALSE)
{
getchar();
return FALSE;
}
printf(" date = %s, time = %s\n", date, time);
returnValue = SendATCommand(gsmHandle, "AT+CMGF=1", TRUE, "OK"); ///< Set Text Mode
if (returnValue == FALSE)
{
printf("cannot set to text mode \n");
getchar();
return FALSE;
}
/// Example to send SMS
returnValue = GsmSendSms(gsmHandle, "+918792792826", "Toradex GSM Modem Test 4", 0);
Sleep(2000);

/// Example to receive SMS
//returnValue = GsmRecieveSms(gsmHandle, "1", phoneNumber, dateTimeStamp, messageRecieved, 160);

/// Example to delete SMS
//returnValue = GsmDeleteSms(gsmHandle, "1");

/// Example to give a miss call
//returnValue = GsmGiveMissCall(gsmHandle, "+917204200289", 0);
printf(" press enter to exit\n");
getchar();
GsmClose(&gsmHandle); ///< Free resources allocated
return TRUE;
}

Output

GSM Modem_output

Download project

You can download demo source code from here.

Send Feedback!