📄 gmodem.cpp
字号:
{
//new SM indicate format:+CMTI: <mem>,<index>
int iPos=sNewSm.Find(",");
if(-1==iPos)
{
return ;//error AT command result format
}
iPos++;
//Resove the index of the new SM
CString sSmIndex=sNewSm.Right(sNewSm.GetLength()-iPos);
int index=atoi((const char *)sSmIndex);
ASSERT(index!=0);
//Notify new SM received
::PostMessage(m_hMessageWnd,m_nMessageID,0,long(index));
//Read SM
/*
STRU_SMS sm;
if(-1==ReadSm(&sm,-1,index))
{
AfxMessageBox("Read new Sm Fail");
}
else
{
AfxMessageBox(sm.cMessage);
}*/
}
/*****************************************************************************
* Class : CGModem
* Function : ExecCmd
* Description: Execute AT Command
* Parameters : AT Command string
* Return :
******************************************************************************/
BOOL CGModem::ExecCmd(CString sCommand)
{
char cBuffer[1024]; //command max length is 1024
strcpy(cBuffer,sCommand);
if(0==m_ComPort.Output(cBuffer,sCommand.GetLength()))
{
return FALSE; //if 'Output' return 0 byte, return FALSE
}
return TRUE;
}
/*****************************************************************************
* Class : CGModem
* Function : DelSms
* Description: Delete sm from TA
* Parameters : the index of the sm to delete
* Return :
******************************************************************************/
BOOL CGModem::DelSm(UINT nIndex)
{
if(!m_fIsLinked)
{
return FALSE;
}
CString sCommand;
sCommand.Format("AT+CMGD=%d\r",nIndex);
ExecCmd(sCommand);
if(RESPONSE_ERROR==WaitAnswer(3*1000))
{
return FALSE;
}
return TRUE;
}
/*****************************************************************************
* Class : CGModem
* Function : ReadSms
* Description: Read sm from TE
* Parameters : sms: the pointer of sms struct,
* nProperty:
-1 a single sm(default)
0 Received unread messages
1 Stored read messages
2 Stored unsent message
3 Stored sent message
4 All messages
* nIndex: the index of the sm to read(when nProperty=-1,it's valid)
* Return : the count of the read sm. If read message fail, return -1
******************************************************************************/
INT CGModem::ReadSm(STRU_SMS* pSm, UINT nIndex ,INT iProperty/*=-1*/)
{
if(!m_fIsLinked)
{
m_nError=GMODEM_NOT_LINKED;
return -1;
}
int iCount=-1;
CString sCommand;
//a single mode
if(-1==iProperty)
{
m_iCurrentIndex=nIndex;
sCommand.Format("AT+CMGR=%d\r",nIndex);
ExecCmd(sCommand);
int iResult=-1;
iResult=WaitSingleAnswer(RESPONSE_READ_SM, 5*1000); //time out 5s
if(RESPONSE_READ_SM !=iResult)
{
::ZeroMemory(pSm,sizeof(*pSm));
return -1;
}
//return read result, m_readSm Created by ResolvePdu()
*pSm=m_readSm;
//return the address of the read Sm
//it can display a valid Sm, if the index==0,
//the Sm is invalid, so read fail.
if(0==pSm->iIndex) //0: invalid message
{
//if the index SM is not exist, return -1;
return -1;
}
//must delete SM from SIM
return 1;
}
//mulity message mode---------------------------------------
else
{
int nCount=-1;
sCommand.Format("AT+CMGL=%d\r",iProperty);
ExecCmd(sCommand);
int iResult=WaitAnswer(30*1000); //30seconds timeout
if(RESPONSE_OK==iResult)
{
return 0;
}
if(RESPONSE_LIST_SM==iResult)
{
return nCount;
}
if(RESPONSE_ERROR==iResult)
{
return -1;
}
return nCount;
}
}
/*****************************************************************************
* Class : CGModem
* Function : ResolvePduSm
* Description: Resolve UDP format data
* Parameters : sReceiveData: the UDP data
* iLength: the length of valid UDP data exclude the CSCA address
* iProperty: indicate the states of message in memory
* iCurrentIndex: the index of sm to resovle
* Return : sm struct contained the all information
******************************************************************************/
STRU_SMS CGModem::ResolvePduSm(CString sReceiveData, int iLength, int iProperty, int iCurrentIndex)
{
//the data is can't empty.
ASSERT(0!=sReceiveData.GetLength());
STRU_SMS newSm;
STRU_SMS *pNewSm=&newSm;
memset(pNewSm,0,sizeof(STRU_SMS)); //initialize
pNewSm->iIndex=iCurrentIndex;
pNewSm->iProperty=iProperty;
//Get Valid data
CString sData=sReceiveData.Right(iLength*2);
//Get Sender number----------------------------------------
//Get OrgAddress length
int iLengthAddr=ctoi((char)sData.Mid(3,1).GetAt(0));
ASSERT(iLengthAddr>0);
CString sSender; //contain sender information
if(0==iLengthAddr%2)
{
sSender=sData.Mid(6,iLengthAddr);
}
else
{
sSender=sData.Mid(6,iLengthAddr+1); //extra 'F'
iLengthAddr++;
}
//BCD translation
char cSender[20];
memset(cSender,0,sizeof(cSender));
strcpy(cSender,sSender);
sSender=from_BCD(cSender,sSender.GetLength());
//trim 'F'
sSender.TrimRight("F");
//have get Sender number
strcpy(pNewSm->cSender,sSender);
//Get TP_DCS-------------------------------------------------
int iCurPos=6+iLengthAddr;
iCurPos+=2; //jump TP_PID
CString sTp_Dcs=sData.Mid(iCurPos,2);//Get TP_DCS
//Get TimeStamp--------------------------------------------
iCurPos+=2; //jimp TP_DCS
CString sTimeStamp=sData.Mid(iCurPos,14);
//Time format: mm/dd/YYYY HH:MM:SS
CString sYear=Exchange(sTimeStamp.Mid(0,2));
sYear="20"+sYear;
CString sMonth=Exchange(sTimeStamp.Mid(2,2));
CString sDay=Exchange(sTimeStamp.Mid(4,2));
CString sHour=Exchange(sTimeStamp.Mid(6,2));
CString sMinute=Exchange(sTimeStamp.Mid(8,2));
CString sSecond=Exchange(sTimeStamp.Mid(10,2));
sTimeStamp.Format("%s/%s/%s %s:%s:%s", sMonth, sDay
,sYear, sHour, sMinute, sSecond);
//Aleady Get stamp time
strcpy(pNewSm->cTimeStamp,(const char *)sTimeStamp);
iCurPos+=14; //jump the time data
//Get PDU Data Length------------------------------------------------
CString sTp_Udl=sData.Mid(iCurPos,2);
iCurPos+=2; //jump the length data
//Get content-----------------------------------------------
char cContent[160]; //字符缓冲
memset(cContent,0,sizeof(cContent));
CString sContent=sData.Right(sData.GetLength()-iCurPos);
if(sTp_Dcs=="08")//UCS8 handling
{
for(int i=0; i<sContent.GetLength()/2; i++)
{
cContent[i]=(BYTE)ahtoi((const char *)sContent.Mid(i*2,2));
}
//Get normal content
sContent=to_MultiByte(cContent,sContent.GetLength()/2);
//AfxMessageBox(sContent);
}
else if(sTp_Dcs=="00" )//7bit to 8 bit
{
int iPduLength=ctoi(sTp_Udl.GetAt(0))*16+
ctoi(sTp_Udl.GetAt(1));
sContent=From7Bit(sContent, iPduLength);
}
strcpy(pNewSm->cMessage, sContent);
return newSm;
}
/*****************************************************************************
* Class : CGModem
* Function : OnReceiveData
* Description: Receive data from COM
* Parameters : pSender--unkown
pBuf--point to the buffer
InBufferCount--the count of receive data
* Return :
******************************************************************************/
void CGModem::OnReceiveData(LPVOID pSender,void* pBuf,DWORD InBufferCount)
{
char cReadBuffer[2048];
memset(cReadBuffer,0,sizeof(cReadBuffer));
memcpy(cReadBuffer,pBuf,InBufferCount);
HandleResponse(cReadBuffer);
}
/*****************************************************************************
* Class : CGModem
* Function : WaitAnswer
* Description: Wait the comm return answer character, multi-answer
* Parameters : dwMilliseconds--timeout
* Return :
******************************************************************************/
CGModem::COMM_RESPONSE CGModem::WaitAnswer(DWORD dwMilliseconds)
{
COMM_RESPONSE result;
//the number of single object :RESPONSE_LIST_SM+1
HANDLE h[RESPONSE_LIST_SM+1];
for(int i=0; i<RESPONSE_LIST_SM+1; i++)
{
h[i]=m_responseEvent[i];
}
//handle array
DWORD dwHandle;
dwHandle=::WaitForMultipleObjects(RESPONSE_LIST_SM+1,
h,
FALSE,
dwMilliseconds);
switch(dwHandle)
{
case WAIT_FAILED:
//Bad cal to function (invali handle?)
AfxMessageBox("Wait Valid handle");
break;
case WAIT_TIMEOUT:
//None of the objects become singaled within dwMillisecondes
//AfxMessageBox("TimeOUt");
m_nError=GMODEM_EXECUTE_TIME_OUT;
result=RESPONSE_ERROR;
break;
case WAIT_OBJECT_0+RESPONSE_OK:
//Receive the 'OK' nofity
result=RESPONSE_OK;
break;
case WAIT_OBJECT_0+RESPONSE_ERROR:
//Receive the '+CMS ERROR: ...'
result=RESPONSE_ERROR;
break;
case WAIT_OBJECT_0+RESPONSE_FAIL:
result=RESPONSE_FAIL;
break;
case WAIT_OBJECT_0+RESPONSE_SEND_SM:
result=RESPONSE_SEND_SM;
break;
case WAIT_OBJECT_0+RESPONSE_LIST_SM:
result=RESPONSE_LIST_SM;
break;
default:
ASSERT(FALSE);
}
return result;
}
/*****************************************************************************
* Class : CGModem
* Function : WaitSingleAnswer
* Description: Wait the comm return answer character, single-answer
* Parameters : response:answer to wait
dwMilliseconds--timeout
* Return : resoponse
******************************************************************************/
CGModem::COMM_RESPONSE CGModem::WaitSingleAnswer(COMM_RESPONSE response, DWORD dwMiliseconds)
{
DWORD dw=WaitForSingleObject(m_responseEvent[response], dwMiliseconds);
switch(dw)
{
case WAIT_OBJECT_0:
return response;
case WAIT_TIMEOUT:
//AfxMessageBox("Time out");
return RESPONSE_TIMEOUT;
case WAIT_FAILED:
return RESPONSE_ERROR;
default:
return RESPONSE_ERROR;
}
}
/*****************************************************************************
* Class : CGModem
* Function : SaveLog
* Description: Save deceive log
* Parameters : logFileName--log file name
add--TRUE:add the log to end of file
FALSE:create a log file
* Return : open or create file fail, return FALSE
******************************************************************************/
BOOL CGModem::SaveLog(LPCTSTR logFileName, BOOL add/*=TRUE*/)
{
//open file
if(add)
{
ofstream logFile(logFileName,ios::ate);
if(logFile.fail())
{
m_sErrorDesp="Can not open file or create file";
return FALSE;
}
//write data
for(int i=0; i<m_commandSet.GetSize(); i++)
{
logFile<<(LPCTSTR)m_commandSet.GetAt(i);
}
}
else
{
ofstream logFile(logFileName);
if(logFile.fail())
{
AfxMessageBox("Can't open file or create file");
return FALSE;
}
//write data
for(int i=0; i<m_commandSet.GetSize(); i++)
{
logFile<<(LPCTSTR)m_commandSet.GetAt(i);
}
}
return TRUE;
}
/*****************************************************************************
* Class : CGModem
* Function : SetNewSmEvent
* Description: Resiger new SM received windows message
* Parameters : nMessage:MessageID
hWnd:the handle of Window who receive the message
* Return :
******************************************************************************/
void CGModem::SetNewSmEvent(UINT nMessage, HWND hWnd)
{
m_nMessageID=nMessage;
m_hMessageWnd=hWnd;
}
/*****************************************************************************
* Class : CGModem
* Function : GetLog
* Description: Get log string
* Parameters : log: pointer of string buffer
nMaxLength:the maxlength of string
* Return :
******************************************************************************/
void CGModem::GetLog(LPSTR log, UINT nMaxLength)
{
CString strLog="";
for(int i=0; i<m_commandSet.GetSize(); i++)
{
strLog+=m_commandSet[i];
}
//Get the Last nMaxLength letter
strLog=strLog.Right(nMaxLength);
strcpy(log, strLog);
}
/*****************************************************************************
* Class : CGModem
* Function : Close()
* Description: Close com port
* Parameters :
* Return :
******************************************************************************/
void CGModem::Close()
{
m_ComPort.Close();
m_fIsLinked=FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -