Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations GregLocock on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

AT Commands On Modem Through A C++ Program

Status
Not open for further replies.

GeeKoo

Computer
Jul 8, 2003
1
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 ... :)
 
Replies continue below

Recommended for you

Hi,

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
 
C code for GSM modem acces through comm port in Unix.
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.


Code:
#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(&quot;init len=%d\n&quot;,strlen(InitString));
	printf(&quot;m=%d\n&quot;,(intModem=open(DeviceFileName,2)));
	if(strlen(InitString)<3)
		printf(&quot;port setting=%d&quot;,set_port( intModem));
	else
		{
		printf(&quot;w=%d\n&quot;,write(intModem,InitString,strlen(InitString)));
		while(ReadModemData(&ch)!=-4);
		}

	printf(&quot;w=%d\n&quot;,write(intModem,(char *)&quot;ate0\r&quot;,5));
	while(ReadModemData(&ch)!=-4);
	
	printf(&quot;w=%d\n&quot;,write(intModem,(char *)&quot;ats0=3\r&quot;,7));
	while(ReadModemData(&ch)!=-4);
		
	printf(&quot;\nint Done for %s\n&quot;,DeviceFileName);
  	}



int ReadModemData(unsigned char *byte)
	{

	unsigned char ModemStatus[5][15]={&quot;NO CARRIER&quot;,&quot;RING&quot;,&quot;CONNECT&quot;,&quot;OK&quot;,&quot;ERROR&quot;};
	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(&quot;%d&quot;,*byte);
	*byte=*byte & 0x7f;
      //printf(&quot;m=%d\n&quot;,byteCont);
	if(byteCont<=0)
		return 0;
	//printf(&quot;%c&quot;,*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(&quot;Returning=%d&quot;,ReturnCodes[i]);
				sprintf(Message,&quot;%s\n&quot;,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(&quot;%02X &quot;,*(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 ~
~ Cell : 880-19-355436 ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 
Hi folks,

I'm sorry that my promised &quot;few minutes&quot; 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 - &quot;ATI7&quot;.

Regards
Rahul


Code:
#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,&quot;COM1&quot;);	
  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(&quot;ATI7\r&quot;);
	oSerialComm.Read(buff,510);
	oSerialComm.CloseSerialPort();

	printf(&quot;%s&quot;,buff);
	
}


Yeasir Rahul

System Analyst
ReadyCash Bangladesh

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Email: Rahul_Y0020@AmericanReadyCash.com ~
~ Phone: 880-2-8125296 ~
~ Fax : 880-2-8115167 ~
~ Cell : 880-19-355436 ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor