×
INTELLIGENT WORK FORUMS
FOR ENGINEERING PROFESSIONALS

Log In

Come Join Us!

Are you an
Engineering professional?
Join Eng-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Eng-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

AT Commands On Modem Through A C++ Program

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 ... :)

RE: AT Commands On Modem Through A C++ Program

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

RE: AT Commands On Modem Through A C++ Program

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.



#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

Hi folks,

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            &

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Eng-Tips Forums free from inappropriate posts.
The Eng-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Eng-Tips forums is a member-only feature.

Click Here to join Eng-Tips and talk with other members!


Resources