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

📄 smsoper.cpp

📁 PDA通讯网关服务器源码程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	const char* pchManufacturer;
	DoAtCmd(hCom,"AT+CGMI");
	//do with what the program received from serial device.
	char chBack[200]={0};
	int nLength=OnReadComm(hCom,chBack,sizeof(chBack));
	if (nLength==0) return NULL;
	//没有成功的响应
	if (strstr(chBack, "OK") ==NULL) return NULL;
	char m_chManufacturer[50];
	memset(m_chManufacturer,'\0',sizeof(m_chManufacturer));
	memcpy(m_chManufacturer,chBack+3,14);
	pchManufacturer=m_chManufacturer;
	return pchManufacturer;
}

// 如果手机号码字符串前面有"+"则去掉,如果前面没有86号码,则加上86
// 输入: 手机号码字符串
const char* CSmsOper::OnIs86(const char *p)
{
	const char *pTel;
	char chTmp[20]={0};
	if (strncmp(p,"+",1)==0)
	{
		memcpy(chTmp,p+1,sizeof(chTmp));	
		pTel=chTmp;
	}
	else
	{
		pTel=p;
	}
	
	if (strncmp(pTel,"86",2)!=0)
	{
		char chTel[20]={0};
		memcpy(chTel,"86",2);
		memcpy(chTel+2,pTel,sizeof(chTel)-2);
		pTel=chTel;
	}
	return pTel;
}

// 发送短消息
// 输入: pchMobile - 对方手机号码
// 输入: pchSms - 要发送短消息缓冲区
// 输入:const char*pchSCA,短信中心号码
// 输入: nType表示对方手机类型,比如小灵通还是移动、联通的手机
// 输入:nHcom为哪个串口的句柄
// 返回: -1失败,0为成功
int CSmsOper::OnSendMess(int nHcom,int nType,const char*pchSCA,const char*pchMobile, const char* pchSms)
{
		SM_PARAM st_Param;
		memset(&st_Param, 0, sizeof(SM_PARAM));
		char chSCA[16]={0};
		char chMobile[16]={0};
		memcpy(chSCA,OnIs86(pchSCA),sizeof(chSCA));
		//memcpy(chMobile,OnIs86(pchMobile),sizeof(chMobile));

		// 填充短消息结构
		memcpy(st_Param.SCA, chSCA,sizeof(st_Param.SCA));
		memcpy(st_Param.TPA, pchMobile,sizeof(st_Param.TPA));
		memcpy(st_Param.TP_UD, pchSms,sizeof(st_Param.TP_UD));
		st_Param.TP_PID = 0;
		st_Param.TP_DCS = GSM_UCS2;
		return OnSendSms(nHcom,&st_Param,nType);
}
/*
// 接收短信函数
// 输入: hCom - 从那个com口句柄接收到的消息
// 输入: nLenOutBuffer-输出数据的长度
// 输出: bDel - 读到新消息后是否将其删除
// 输出:pchText-接收到短信内容,固定格式如下:
typedef struct {
	char SCA[16];			// 短消息服务中心号码(SMSC地址)
	char TPA[16];			// 目标号码或回复号码(TP-DA或TP-RA)
	char TP_PID;			// 用户信息协议标识(TP-PID)
	char TP_DCS;			// 用户信息编码方式(TP-DCS)
	char TP_SCTS[16];		// 服务时间戳字符串(TP_SCTS), 接收时用到
	char TP_UD[160];		// 原始用户信息(编码前或解码后的TP-UD)
	short index;			// 短消息序号,在读取时用到
} SM_PARAM
将结构体数据依次放入缓冲区中间(所以建议输出缓冲区尽量定义大一些)
// 返回: -1失败,大于0则成功,为短信条数
*/
int CSmsOper::OnRecvMess(int hCom,const unsigned int nLenOutBuffer,const char *pchOutBuffer,bool bDel)
{
	SM_PARAM st_Param[200];
	for (int i=0;i<200;i++)
	{
		memset(&st_Param[i],'\0',sizeof(SM_PARAM));
	}
	int iCount=OnRecvSms(hCom,st_Param);
	if (iCount<1) return iCount;
	for(i=0;i<iCount;i++)
	{
		//如果输出的字符串的长度比存储短信长度短,则只复制一定长度的数据
		if (nLenOutBuffer<(i*sizeof(SM_PARAM)) ) break;	
		//将结构体数据放入到缓冲区中输出
		memcpy((void *)(pchOutBuffer+i*sizeof(SM_PARAM)),&st_Param[i],sizeof(SM_PARAM));
		//读写一条消息后,就从sim卡上删除掉该消息(要问清楚,也可以自己测试下)
		if (bDel) OnDeleteAppointed(hCom,st_Param[i].index);
	}
	return iCount;
}


// 打开串口
// 返回: 如果大于0则为获取的com接口的句柄,小于0则为失败
int CSmsOper::OnOpenCom(char *pPort, int nBaudRate, int nParity, int nByteSize, int nStopBits)
{
	DCB dcb;		// 串口控制块
	COMMTIMEOUTS timeouts = {	// 串口超时控制参数
		200,				// 读字符间隔超时时间: 100 ms
		1,					// 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
		600,				// 基本的(额外的)读超时时间: 500 ms
		1,					// 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
		200};				// 基本的(额外的)写超时时间: 100 ms

	HANDLE hCom = CreateFile(pPort,	// 串口名称或设备路径
			GENERIC_READ | GENERIC_WRITE,	// 读写方式
			0,				// 共享方式:独占
			NULL,			// 默认的安全描述符
			OPEN_EXISTING,	// 创建方式
			0,				// 不需设置文件属性
			NULL);			// 不需参照模板文件
	
  
	if(hCom == INVALID_HANDLE_VALUE)
	{
		return -1;    // 打开串口失败
	}        

	dcb.BaudRate = nBaudRate;
	dcb.ByteSize = nByteSize;
	dcb.Parity = nParity;
	dcb.StopBits = nStopBits;
	dcb.fBinary=TRUE;
	dcb.fDsrSensitivity=false;
	dcb.fParity=0;
	dcb.fOutX=false;
	dcb.fInX=false;
	dcb.fNull=false;
	dcb.fAbortOnError=TRUE;
	dcb.fOutxCtsFlow=FALSE;
	dcb.fOutxDsrFlow=false;
	dcb.fDtrControl=DTR_CONTROL_DISABLE;
	dcb.fDsrSensitivity=false;
	dcb.fRtsControl=RTS_CONTROL_DISABLE;
	dcb.fOutxCtsFlow=false;
	dcb.fOutxCtsFlow=false;

	// 设置输入输出缓冲区大小
	if (0==SetupComm(hCom, 4096, 1024))
	{
		OnErrorMsg("设置串口通讯失败SetupComm失败");
		return -2;
	}

	if (0==SetCommTimeouts(hCom, &timeouts))
	{
		OnErrorMsg("设置串口通讯SetCommTimeouts!失败");
		return -3;
	}// 设置超时

	// 取DCB
	if (0 == GetCommState(hCom, &dcb))
	{
		OnErrorMsg("获取串口通讯状态失败");
		return -4;
	}

	char chBaud[40]={0};
	sprintf(chBaud,"baud=%d parity=%c data=%d stop=%d",nBaudRate,'N',nByteSize,nStopBits);
	if (0==BuildCommDCB(chBaud,&dcb))
	{
		OnErrorMsg("BuildCommDCB失败");
		return -5;  
	}
	if (0 == SetCommState(hCom, &dcb))
	{
		 OnErrorMsg("设置串口时候失败SetCommState");
		 return  -6;
	}  
	InitializeCriticalSection(&m_ComOperCritical); //发送短信的锁
    return int(hCom); 
}


void CSmsOper::OnErrorMsg(char *pchInput)
{
	TCHAR szBuf[300]={0}; 
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    _snprintf(szBuf,sizeof(szBuf)-1,"%s failed with error %d: %s", pchInput, dw, lpMsgBuf); 
    MessageBox(NULL, szBuf, "Error", MB_OK); 
    LocalFree(lpMsgBuf);
}


// 关闭串口
int CSmsOper::OnCloseComm(int hCom)
{
	FlushFileBuffers((void *)hCom); 
	return CloseHandle((void *)hCom);
}

// 写串口
// 输入: pData - 待写的数据缓冲区指针
//       nLength - 待写的数据长度
// 返回: 实际写入的数据长度
int CSmsOper::OnWriteComm(int hCom,void* pData, int nLength)
{
	DWORD dwNumWrite;	// 串口发出的数据长度
	DWORD dwErrors=0;
	try
	{
		EnterCriticalSection(&m_ComOperCritical);
		ClearCommError((void *)hCom, &dwErrors, NULL);
		PurgeComm((void *)hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
		WriteFile((void *)hCom, pData, (DWORD)nLength, &dwNumWrite, NULL);
		LeaveCriticalSection(&m_ComOperCritical);
	}
	catch(...)
	{
		LeaveCriticalSection(&m_ComOperCritical);
		return -1;
	}	
	return (int)dwNumWrite;
}

// 读串口
// 输入: pData - 待读的数据缓冲区指针
//       nLength - 待读的最大数据长度
// 返回: 实际读出的数据长度
int CSmsOper::OnReadComm(int hCom,void* pData, int nLength)
{
	DWORD dwNumRead;	// 串口收到的数据长度
	try
	{
		EnterCriticalSection(&m_ComOperCritical);
		BOOL bRet=ReadFile((void *)hCom, pData, (DWORD)nLength, &dwNumRead, NULL);
		if (!bRet)
		{
			PurgeComm((void *)hCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
			ReadFile((void *)hCom, pData, (DWORD)nLength, &dwNumRead, NULL);
		}
		LeaveCriticalSection(&m_ComOperCritical);
	}
	catch(...)
	{
		LeaveCriticalSection(&m_ComOperCritical);
		return -1;
	}
//	PurgeComm((void *)hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
	return (int)dwNumRead;
}

//清空串口的缓冲区,如果失败了则结果为0,没有失败的话,结果为非0
int CSmsOper::OnClearCom(int nHCom)
{
	return PurgeComm((void *)nHCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);	
}

int CSmsOper::OnReadCommOkErr(int hCom, char *pchBuf, int nLength)
{
	DWORD dwNumRead;	// 串口收到的数据长度
	char chData[8000]={0};
	int nRecvDataLen=0;
	int nDataLen=0;
		// 串口错误号
	DWORD dwErrors = 0;

	try
	{
		EnterCriticalSection(&m_ComOperCritical);
		while( nRecvDataLen < nLength ) 
		{
			if( ReadFile( (void *)hCom, chData + nRecvDataLen, nLength - nRecvDataLen, &dwNumRead, NULL ) )
			{
				if( dwNumRead > 0 )
				{
					nRecvDataLen += dwNumRead;
				}
				else
				{
					LeaveCriticalSection(&m_ComOperCritical);
					return -1;
				}
			}
			else
			{
				ClearCommError((void *)hCom, &dwErrors, NULL);
				PurgeComm((void *)hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
				LeaveCriticalSection(&m_ComOperCritical);
				return -1;
			}

			//判断是否接收到错误或者正确的信息
			nDataLen=0;
			nDataLen=OnRecWhole(chData,pchBuf,"OK\r\n");
			if (nDataLen>0)
			{			
				LeaveCriticalSection(&m_ComOperCritical);
				return nDataLen;
			}

			//判断是否接收到错误或者正确的信息
			nDataLen=OnRecWhole(chData,pchBuf,"ERROR\r\n");
			if (nDataLen>0)
			{			
				LeaveCriticalSection(&m_ComOperCritical);
				return nDataLen;
			}
		}
		LeaveCriticalSection(&m_ComOperCritical);	
	}
	catch(...)
	{
		LeaveCriticalSection(&m_ComOperCritical);
		return -1;
	}
	return nDataLen;
}

int CSmsOper::OnRecWhole(char *pchData,char *pchBuf, char *pchEnd)
{
	//如果接收到数据当中包含了正确或者错误则停止接收数据
	char *pdest;
	int  result=0,nDataLen=0;
	pdest = strstr( pchData, pchEnd );
	if (pdest!=NULL) 
	{
		result = pdest - pchData + 1;
		nDataLen=result+strlen(pchEnd);
		try
		{
			memcpy(pchBuf,pchData,nDataLen);
		}
		catch(...)
		{
			return -1;
		}

		return nDataLen;
	}
	return 0;
}


int CSmsOper::OnReadBack(int hCom, char *pchBack,int nBack,char *pchOk, char *pchError,int nTimeOut)
{
	long LastSaveBillTime=time(NULL);
	//循环接受通讯终端的数据
	while(1)
	{
		int iLen=OnReadComm(hCom,pchBack,nBack);
		if (strstr(pchBack, pchOk)!=NULL)
		{
			return 1;		
		}
		if (strstr(pchBack, pchError)!=NULL) 
		{
			return -1;
			break;
		}
		if(time(NULL) - LastSaveBillTime >= nTimeOut)
		{
			return -1;
			break;
		}
	}
	return 1;
}
//CMS ERROR: 304

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -