⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gprs_smm.cpp

📁 利用该程序可以通过短信让远程GPRS模块上线
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -