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.
Connect X14 connector to UART Port of GSM Modem with Serial cable.
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_
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; } }
#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; }
You can download demo source code from here.