AT Commands On Modem Through A C++ Program
AT Commands On Modem Through A C++ Program
(OP)
Hello,
I want to develop an application where i have to interact with a GSM Modem and require to write AT Commands on the modem via the com port from a C++ program.
Can anyone provide guidance in this regard ..
Highly URGENT ...
Thanks in advance ... :)
I want to develop an application where i have to interact with a GSM Modem and require to write AT Commands on the modem via the com port from a C++ program.
Can anyone provide guidance in this regard ..
Highly URGENT ...
Thanks in advance ... :)





RE: AT Commands On Modem Through A C++ Program
Most of the data enabled GSM sets are exactly like an external modem. They support all the AT commands, plus some manufacturer specific additional commands. This is from software side.
From hardware side, the communication interface is a bit inflexible for some handsets. I worked with Siemens C35 sets extensively. They'll talk to you only at 19200 Baud, no parity, 8 data bits and 1 stop bit configuration. No other combination works.
Well, some other sets, mostly Nokia ones, have another driver layer below the AT command layer. So, you cannot issue AT commands directly to the comm port. You have to use their driver for this.
Accessing comm port from C++ requires quite standard techniques. There is a difference between Windows environment and Unix/Linux environment in this regard.
Regards
Yeasir Rahul
System Analyst
RE: AT Commands On Modem Through A C++ Program
I used this for controlling Siemens C35 handsets. It is well tested for that particular phone. The OS was SCO OpenServer. Porting to Linux should not be difficult.
I'll post C++ codes for Windows a few minutes later.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/termio.h>
int intModem;
int initModem(char * DeviceFileName, char * InitString)
{
int i,length;
unsigned char buf[255],ch;
printf("init len=%d\n",strlen(InitString));
printf("m=%d\n",(intModem=open(DeviceFileName,2)));
if(strlen(InitString)<3)
printf("port setting=%d",set_port( intModem));
else
{
printf("w=%d\n",write(intModem,InitString,strlen(InitString)));
while(ReadModemData(&ch)!=-4);
}
printf("w=%d\n",write(intModem,(char *)"ate0\r",5));
while(ReadModemData(&ch)!=-4);
printf("w=%d\n",write(intModem,(char *)"ats0=3\r",7));
while(ReadModemData(&ch)!=-4);
printf("\nint Done for %s\n",DeviceFileName);
}
int ReadModemData(unsigned char *byte)
{
unsigned char ModemStatus[5][15]={"NO CARRIER","RING","CONNECT","OK","ERROR"};
int ReturnCodes[5]={-1,-2,-3,-4,-5};
static int ModemStatusCount[5]={0};
int i,byteCont;
char Message[20];
byteCont=read(intModem,byte,1);
//printf("%d",*byte);
*byte=*byte & 0x7f;
//printf("m=%d\n",byteCont);
if(byteCont<=0)
return 0;
//printf("%c",*byte);
ModemAlive=1;
alarm(60);
for (i=0;i<5;i++)
{
if(ModemStatus[i][ModemStatusCount[i]]==*byte)
{
ModemStatusCount[i]++;
if(ModemStatusCount[i]==strlen((char *)ModemStatus[i]))
{
ModemStatusCount[i]=0;
//printf("Returning=%d",ReturnCodes[i]);
sprintf(Message,"%s\n",ModemStatus[i]);
LogMessage(Message);
return ReturnCodes[i];
}
}
else
ModemStatusCount[i]=0;
}
return byteCont;
}
long WriteModemData( char *buf,long bufLength)
{
int i;
long ByteCount;
for(ByteCount=0;ByteCount<bufLength;ByteCount++)
{
write(intModem,(buf+ByteCount),1);
//printf("%02X ",*(buf+ByteCount));
/*for(i=0;i<10;i++)
{}*/
}
return ByteCount;
}
int set_port(int port)
{
struct termio line_settings;
if( ioctl (port, TCGETA, &line_settings ) == -1 )
{
exit(1);
}
/* 19200 baud, 8 bits, no parity, 1 stop bit */
line_settings.c_cflag = B19200 | CS8 | CREAD | HUPCL | CLOCAL;
/* input modes */
line_settings.c_iflag = IGNBRK;
/* output modes */
line_settings.c_oflag = 0;
/* line disciple modes */
line_settings.c_lflag = 0;
/* control chars */
line_settings.c_cc[4] = 0; /* VMIN */
line_settings.c_cc[5] = 20; /* VTIME */
if( ioctl (port, TCSETA, &line_settings ) == -1 )
{
exit(1);
}
return 0;
}
Best regards
Rahul
NB: Contact me over email if you need further clarification.
Yeasir Rahul
System Analyst
ReadyCash Bangladesh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Email: Rahul_Y0020@AmericanReadyCash.com ~
~ Phone: 880-2-8125296 ~
~ Fax : 880-2-8115167 &
RE: AT Commands On Modem Through A C++ Program
I'm sorry that my promised "few minutes" turned out to be one whole month!
Anyway, here is the Windows VC++ code for accessing serial port. This sample contains a class for serial port data I/O. The main function assumes that a modem is connected at the port, and inquires it for its identification - "ATI7".
Regards
Rahul
#include<windows.h>
#include<stdio.h>
class CSerialComm
{
public:
BOOL m_bPortReady;
HANDLE m_hCom;
DCB PortDCB;
COMMTIMEOUTS m_CommTimeouts;
BOOL bWriteRC;
BOOL bReadRC;
DWORD iBytesWritten;
DWORD iBytesRead;
BOOL m_CommOpen;
BOOL _bPortReady;
char sBuffer[128];
char cPortName[5];
CSerialComm();
virtual ~CSerialComm();
BOOL OpenSerialPort();
BOOL Read(char *buffer, unsigned int ByteCount);
BOOL Write(char *buffer);
BOOL CloseSerialPort();
DWORD GetModemInfo();
};
DWORD dwError;
CSerialComm::CSerialComm()
{
}
CSerialComm::~CSerialComm()
{
CloseHandle(m_hCom);
}
BOOL CSerialComm::OpenSerialPort()
{
strcpy(cPortName,"COM1");
m_hCom = CreateFile (cPortName ,// Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE,
// Access (read/write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING,// How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute
// to copy
// if fail to open the port, return FALSE.
if ( m_hCom == INVALID_HANDLE_VALUE )
// Could not open the port.
return FALSE;
PortDCB.DCBlength = sizeof (DCB);
// Get the default port setting information.
GetCommState (m_hCom, &PortDCB);
// Change the DCB structure settings.
// PortDCB.BaudRate = 9600; // Current baud
// PortDCB.fBinary = TRUE; // Binary mode; no EOF check
// PortDCB.fParity = TRUE; // Enable parity checking.
// PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
// PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
// PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
// 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;
// RTS flow control
// PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on
// error.
// PortDCB.ByteSize = 8; // Number of bits/bytes, 4-8
// PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
// PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
// unsigned long inBuff = 1200;
// unsigned long outBuff = 1200;
// SetupComm(m_hCom,inBuff,outBuff);
// Configure the port according to the specifications of the DCB
// structure.
SetCommState(m_hCom,&PortDCB);
return true;
}
BOOL CSerialComm::Write(char *buffer)
{
DWORD dummy;
if(buffer == NULL)
return FALSE;
WriteFile( m_hCom,
buffer,
(DWORD)strlen(buffer),
&dummy,
0
);
return true;
}
BOOL CSerialComm::Read(char *buffer, unsigned int ByteCount)
{
DWORD dummy;
if((ByteCount==0) || (buffer == NULL))
return FALSE;
if(!ReadFile(m_hCom,buffer,(DWORD)ByteCount,&dummy,NULL))
return FALSE;
return TRUE;
}
BOOL CSerialComm::CloseSerialPort()
{
if(CloseHandle(m_hCom)) return TRUE ;
else return FALSE;
}
void main()
{
char buff[800];
for(int i=0;i<800;i++)
buff[i] = 0;
CSerialComm oSerialComm;
oSerialComm.OpenSerialPort();
oSerialComm.Write("ATI7\r");
oSerialComm.Read(buff,510);
oSerialComm.CloseSerialPort();
printf("%s",buff);
}
Yeasir Rahul
System Analyst
ReadyCash Bangladesh
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Email: Rahul_Y0020@AmericanReadyCash.com ~
~ Phone: 880-2-8125296 ~
~ Fax : 880-2-8115167 &