📄 gprs_smm.cpp
字号:
// GPRS_SMM.cpp : Defines the initialization routines for the DLL.
// Edited by xie hong sheng , 2002-11 , CopyRight hongdian
#include "stdafx.h"
#include "GPRS_SMM.h"
//#include "winsock2.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CGPRS_SMMApp, CWinApp)
//{{AFX_MSG_MAP(CGPRS_SMMApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGPRS_SMMApp construction
CGPRS_SMMApp::CGPRS_SMMApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CGPRS_SMMApp object
CGPRS_SMMApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CGPRS_SMMApp initialization
BOOL CGPRS_SMMApp::InitInstance()
{
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
return TRUE;
}
/********global variant*******************/
SMM_information smminfo;
int gnModemType = 0;
extern "C" void HDCALL SetModemType(int nModemType)
{
gnModemType = nModemType;
}
/****************************************/
extern "C" int HDCALL
SMMInit(char *DSCIpAddr, int DSCSrvPort,
char *SerialCom, DCB *dcb,
char *SMSCNumber, char *SMMNumber, int WorkMode)
{
int nDSCIpAddrLen, nSMSCNumberLen, nSMMNumberLen;
//argument check
nDSCIpAddrLen = strlen(DSCIpAddr);
nSMMNumberLen = strlen(SMMNumber);
if(1==gnModemType)
{
if (
(nSMMNumberLen != 11)
|| ((DSCSrvPort < 5/*1024*/) ||(DSCSrvPort > 65535))
)
return -10;
}else
{
nSMSCNumberLen = strlen(SMSCNumber);
if (
(nSMSCNumberLen != 11)
|| (nSMMNumberLen != 11)
|| ((DSCSrvPort < 5/*1024*/) ||(DSCSrvPort > 65535))
)
return -10;
memcpy(smminfo.m_szSMSCNumber, SMSCNumber, nSMSCNumberLen);
smminfo.m_szSMSCNumber[nSMSCNumberLen] = '\0';
}
memcpy(smminfo.m_szSMMNumber, SMMNumber, nSMMNumberLen);
smminfo.m_szSMMNumber[nSMMNumberLen] = '\0';
Initsmminfo();
smminfo.m_nWordMode = WorkMode;
if (-1 == SMMSetting(DSCIpAddr, DSCSrvPort))
{
WriteLog("Error:DSC Ip or DSC Port",strlen("Error:DSC Ip or DSC Port"));
return -1;
}
if (-1 == ConfigSerialCom(SerialCom, dcb))
{
WriteLog("ConfigSerialCom Failed", strlen("ConfigSerialCom Failed"));
return -2;
}
//create a socket in order to send data to dsc
smminfo.m_sock = ::socket(AF_INET, SOCK_DGRAM, 0);
if (INVALID_SOCKET == smminfo.m_sock)
{
CloseHandle(smminfo.m_hComm);
WriteLog("can not open socket", strlen("can not open socket"));
return -3;
}
//create a mutex , if you want to write to com , you must wait this mutex
smminfo.m_hCommMutex = ::CreateMutex(NULL, false, "GPRSSMM_MUTEX");
if (NULL == smminfo.m_hCommMutex)
{
CloseHandle(smminfo.m_hComm);
closesocket(smminfo.m_sock);
WriteLog("can not create Mutex", strlen("can not create Mutex"));
return -4;
}
if (-1 == ConfigSMM(SMSCNumber))
{
CloseHandle(smminfo.m_hComm);
closesocket(smminfo.m_sock);
CloseHandle(smminfo.m_hCommMutex);
WriteLog("Config SMM failed", strlen("Config SMM failed"));
return -5;
}
//create the timer routine , which read data from com then process the data
smminfo.m_unTimerId = ::SetTimer(NULL, 1, TIMERINTERVAL, (TIMERPROC)ReadAndProcessData);
if (!smminfo.m_unTimerId)
{
CloseHandle(smminfo.m_hComm);
closesocket(smminfo.m_sock);
CloseHandle(smminfo.m_hCommMutex);
WriteLog("can not create Timer Routine", strlen("can not create Timer Routine"));
return -6;
}
//SendDataToDSC("SMMInit Success!",strlen("SMMInit Success!"));
return 0;
}
extern "C" int HDCALL
SMMFree()
{
::KillTimer(NULL,smminfo.m_unTimerId);
closesocket(smminfo.m_sock);
::PurgeComm(smminfo.m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
CloseHandle(smminfo.m_hComm);
CloseHandle(smminfo.m_hCommMutex);
WriteLog("SMMFree Success", strlen("SMMFree Success"));
return 0;
}
extern "C" int HDCALL
SMMSetting(char *DSCIpAddr,int DSCSrvPort)
{
int nDSCIpAddrLen;
char szHostIp[16];
int nResult;
bool bLegalIp = false;
if ((DSCSrvPort < 5/*1024*/) || (DSCSrvPort > 65535))
{
return -1;
}
//Modified by sea on sep 16,2003
// if (!DSCIpAddr)
if (DSCIpAddr)
{
nDSCIpAddrLen = strlen(DSCIpAddr);
if ((nDSCIpAddrLen >= 7) || (nDSCIpAddrLen <= 15))
{
strcpy(smminfo.m_DSCIpAddr, DSCIpAddr);
bLegalIp = true;
nResult = 0;
}
}
if (!bLegalIp)
{
nResult = GetHostName(szHostIp, 16);
if (0 == nResult)
{
strcpy(smminfo.m_DSCIpAddr, szHostIp);
}
else
{
nResult = -1;
}
}
smminfo.m_nDSCSrvPort = DSCSrvPort;
return nResult;
}
extern "C" int HDCALL
MakeDTUOnLine(int Changed, char *DTUNumber)
{
int success, nNumLen;
success = -1;
nNumLen = strlen(DTUNumber);
if ((0 == smminfo.m_nOKNOCARRIERNumber) && (11 == nNumLen))
{
switch (Changed)
{
case 0: //not changed
if (USECALL==smminfo.m_nWordMode)
success=MakeDTUOnLine_Call(DTUNumber);
else
success=MakeDTUOnLine_SM(DTUNumber);
break;
case 1: //changed
success=MakeDTUOnLine_SM(DTUNumber);
break;
default:
success=-2;
break;
}
}
return success;
}
extern "C" int HDCALL
SendDataToDTUBySM(char *DTUNumber, char *szData,int nDataLen,int nProtoType)
{
char szBuf[280];
WCHAR szWBuf[512];
int nWLen;
int i, nTemp;
char *p;
if ((strlen(DTUNumber) != 11)
|| (!szData))
{
return -1;
}
switch (nProtoType)
{
//普通数据,不加协议
case NOPROTOCOL:
nWLen = MultiByteToWideChar(CP_ACP, 0, szData, nDataLen, szWBuf, sizeof(szWBuf));
szWBuf[nWLen] = '\0';
p = (char *)szWBuf;
for (i=0; i<nWLen*2; i+=2)
{
nTemp = p[i];
p[i] = p[i+1];
p[i+1] = nTemp;
}
return SendSMToDTU(DTUNumber, (char *)szWBuf, nWLen*2);
case CONFIGUREDATA:
szBuf[1]=(char)PROTO_CONFIGUREDATA;
break;
case USERDATA:
szBuf[1]=(char)PROTO_USERDATA;
break;
default:
return -1;
}
szBuf[0]=(char)0x7B;
*((unsigned short *)(szBuf+2))=nDataLen+5;
memcpy(szBuf+4,szData,nDataLen);
szBuf[nDataLen+4]=(char)0x7B;
return SendSMToDTU(DTUNumber,szBuf,nDataLen+5);
}
int ReadDataFromSerialCom(void)
{
DWORD dwRdCount = 0, dwError;
COMSTAT cs;
if ((::ClearCommError(smminfo.m_hComm, &dwError, &cs)) && (cs.cbInQue > 0))
{
if (::ReadFile(smminfo.m_hComm,
smminfo.m_szBuf + smminfo.m_nBeginPosition,
cs.cbInQue,
&dwRdCount,
NULL))
{
if (dwRdCount>0)
{
smminfo.m_szBuf[smminfo.m_nBeginPosition + dwRdCount] = '\0';
smminfo.m_nBufLen = smminfo.m_nBeginPosition+dwRdCount;
smminfo.m_nEndPosition = smminfo.m_nBeginPosition + dwRdCount - 1;
smminfo.m_nBeginPosition = 0;
return 0;
}
}
}
return -1;
}
int MakeDTUOnLine_Call(char *DTUNumber)
{
char szDialBuf[64];
smminfo.m_nOKNOCARRIERNumber = 2;
sprintf(szDialBuf, "ATH\r");
SendDataToSerialCom(szDialBuf, strlen(szDialBuf), 0);
Sleep(500);
sprintf(szDialBuf, "ATD%s;\r", DTUNumber);
return SendDataToSerialCom(szDialBuf, strlen(szDialBuf), (1000 / TIMERINTERVAL) * WAITCALLTODTU);
}
int MakeDTUOnLine_SM(char *DTUNumber)
{
char szData[16];
szData[0] = (char)0x7B;
szData[1] = (char)PROTO_SMDTUONLINE;
szData[2] = 0x00;
szData[3] = 0x0B;
*((unsigned long *)(szData + 4)) = ::inet_addr(smminfo.m_DSCIpAddr);
//*((unsigned short *)(szData+8))=(unsigned short)smminfo.m_nDSCSrvPort;
szData[8] = (char)(smminfo.m_nDSCSrvPort / 256);
szData[9] = (char)(smminfo.m_nDSCSrvPort % 256);
szData[10] = (char)0x7B;
return SendSMToDTU(DTUNumber,szData,11);
}
int SendDataToSerialCom(char *szData, int nDataLen, int nTimeOut)
{
DWORD dwWrCount = 0;
int nResult = -1;
if ((0 == smminfo.m_nCanUse)
&& (WAIT_OBJECT_0 == ::WaitForSingleObject(smminfo.m_hCommMutex,2000)))
{
if ((0 == smminfo.m_nCanUse)
&& (::WriteFile(smminfo.m_hComm, szData, nDataLen, &dwWrCount, NULL)))
{
if (dwWrCount > 0)
{
smminfo.m_nCanUse = nTimeOut;
nResult = 0;
}
}
::ReleaseMutex(smminfo.m_hComm);
}
return nResult;
}
int SendDataToDSC(char *szData, int nDataLen)
{
int nResult;
SOCKADDR_IN sa;
sa.sin_addr.S_un.S_addr = inet_addr(smminfo.m_DSCIpAddr);
sa.sin_family = AF_INET;
sa.sin_port = htons(smminfo.m_nDSCSrvPort);
if (SOCKET_ERROR == ::sendto(smminfo.m_sock, szData, nDataLen, 0, (SOCKADDR *)&sa, sizeof(SOCKADDR)))
{
WriteLog("Error:sendto to DSC", strlen("Error:sendto to DSC"));
nResult = -1;
}
else
{
nResult = 0;
}
return nResult;
}
int ProcessDataFromSerialCom()
{
int nResult, nCMTProcessed, nFlag = 0;
char szCMGD[16];
smminfo.m_nOKNOCARRIERNumber -= OKNumber(smminfo.m_szBuf, smminfo.m_nBufLen, 1);
if (smminfo.m_nOKNOCARRIERNumber <= 0)
{
smminfo.m_nOKNOCARRIERNumber = 0;
smminfo.m_nCanUse = 0;
}
nCMTProcessed = 0;
while (nFlag != 5)
{
nResult = ProtocolAnalysis();
if (0 == nResult)
{
smminfo.m_nBeginPosition = 0;
smminfo.m_nBufLen = 0;
break;
}
switch (nResult)
{
case 1:
nFlag=Process_CLIP(); //Process the call from DTU
break;
case 2:
nFlag=Process_CMT(); //Process the SM from DTU
nCMTProcessed=1;
break;
/* case 3:
Process_OKNOCARRIER(2);
break;
case 4:
Process_OKNOCARRIER(strlen("CARRIER"));
break;
*/
case 5:
return 0;
default:
break;
}
}
//All READ messages and SENT mobile originated messages are deleted
if (1 == nCMTProcessed)
{
sprintf(szCMGD, "AT+CMGD=1,2\r");
return SendDataToSerialCom(szCMGD, strlen(szCMGD), 0);
}
smminfo.m_nBufLen = smminfo.m_nEndPosition - smminfo.m_nBeginPosition;
if (smminfo.m_nBufLen < 0)
smminfo.m_nBufLen = 0;
return 0;
}
int ProtocolAnalysis()
{
int nResult=0;
while(1)
{
//the szBuf has been completely Processed
if (smminfo.m_nBeginPosition + 2 > smminfo.m_nEndPosition)
{
nResult = 0;
MoveDataInBuf();
break;
}
//CLIP string
if (('C' == smminfo.m_szBuf[smminfo.m_nBeginPosition])
&& ('L' == smminfo.m_szBuf[smminfo.m_nBeginPosition + 1])
&& ('I' == smminfo.m_szBuf[smminfo.m_nBeginPosition + 2])
&& ('P' == smminfo.m_szBuf[smminfo.m_nBeginPosition + 3]))
{
nResult = 1;
break;
}
//CMT string
if (('C' == smminfo.m_szBuf[smminfo.m_nBeginPosition])
&& ('M' == smminfo.m_szBuf[smminfo.m_nBeginPosition + 1])
&& ('T' == smminfo.m_szBuf[smminfo.m_nBeginPosition + 2]))
{
nResult = 2;
break;
}
/*
//OK
if (('O'==smminfo.m_szBuf[smminfo.m_nBeginPosition])
&& ('K'==smminfo.m_szBuf[smminfo.m_nBeginPosition+1]))
{
nResult=3;
break;
}
//NO CARRIER
if (('C'==smminfo.m_szBuf[smminfo.m_nBeginPosition])
&& ('A'==smminfo.m_szBuf[smminfo.m_nBeginPosition+1])
&& ('R'==smminfo.m_szBuf[smminfo.m_nBeginPosition+1])
&& ('R'==smminfo.m_szBuf[smminfo.m_nBeginPosition+1])
&& ('I'==smminfo.m_szBuf[smminfo.m_nBeginPosition+1])
&& ('E'==smminfo.m_szBuf[smminfo.m_nBeginPosition+1])
&& ('R'==smminfo.m_szBuf[smminfo.m_nBeginPosition+1]))
{
nResult=4;
break;
}
*/
smminfo.m_nBeginPosition++;
}
return nResult;
}
int Process_OKNOCARRIER(int len)
{
if (smminfo.m_nOKNOCARRIERNumber > 0)
{
smminfo.m_nOKNOCARRIERNumber--;
if (smminfo.m_nOKNOCARRIERNumber <= 0)
{
smminfo.m_nOKNOCARRIERNumber = 0;
smminfo.m_nCanUse = 0;
}
}
smminfo.m_nBeginPosition += len;
return 0;
}
/*
//CLIP: "13902944285",129\r\n 12+phone GPRS
//CLIP:"13510006407",129\r\n cdma
*/
//+CLIP: "07558389018",129
int Process_CLIP()
{
int p,i,j;
int nPNumLen;
char szATH[16], szPNum[16];
CALLFROMDTU cfd;
bool bFound = false;
//hook off the phone
sprintf(szATH, "ATH\r");
if (-1 == SendDataToSerialCom(szATH, strlen(szATH), 0))
{
WriteLog("Error:Send ATH Failed",strlen("Error:Send ATH Failed"));
}
if ((smminfo.m_nBeginPosition + 19 - 1)>smminfo.m_nEndPosition)
return MoveDataInBuf();
//read phone number from buf
p = smminfo.m_nBeginPosition;
nPNumLen = 0;
for (i=0; i<15; i++)
{
if ((char)0x22 == smminfo.m_szBuf[p]) //"
{
for (j=0; j<16; j++)
{
p++;
if (p>smminfo.m_nEndPosition)
return MoveDataInBuf();
if ((char)0x22 == smminfo.m_szBuf[p]) //"
{
bFound = true;
break;
}
if ((smminfo.m_szBuf[p] > '9') || (smminfo.m_szBuf[p] < '0'))
break;
szPNum[j] = smminfo.m_szBuf[p];
nPNumLen++;
}
break;
}
p++;
if ((p + 10)>smminfo.m_nEndPosition)
return MoveDataInBuf();
}
if (!bFound)
{
smminfo.m_nBeginPosition++;
return -1;
}
smminfo.m_nBeginPosition += (8 + nPNumLen);
if ((nPNumLen > 7) && (nPNumLen < 15))
{
szPNum[nPNumLen] = '\0';
//if the last DTU phone number not euqal the current
//DTU phone number or they are equal but ttl>5 then
//send it to dsc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -