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.
GSM Modem works on Serial communication.
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.
Connect X14 connector to UART Port of GSM Modem with Serial cable.
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
Download project
You can download demo source code from here.