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

📄 gprser.cpp

📁 gprs开发使用程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*!	\file		GGPRSer.cpp
	\brief		GPRS类实现文件
	\author		陈华毅
	\version	1.0

	通过实现CGPRSer类,应用程序可以通过CGPRSer类的实体来实现对GPRS模块操作。
	\defgroup	GPRSER_IMPLEMENT	CGPRSDer类实现说明
*/

#include "stdafx.h"
#include "GPRS.h"
#include "GPRSer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//@{Group: GPRSER_IMPLEMENT

/*!	CGPRS构造函数,构造时打开串口
	\param	无
	\return	无
*/
CGPRSer::CGPRSer()
{
	m_serial.OpenComm();
}

/*!	CGPRS析构函数,析构时关闭串口
	\param	无
	\return	无
*/
CGPRSer::~CGPRSer()
{
	m_serial.CloseComm();
}

/*!	初始化GSM状态 
	\param	无
	\return		成功返回TRUE,失败返回FALSE。
*/
BOOL CGPRSer::GPRSInit()
{
	/* 测试连接:“AT”测试终端是否连接正确。成功后返回“OK”。*/
	char ans[128];
	m_serial.WriteComm((UCHAR*)"AT\r", 3);
	Sleep(30);
	m_serial.ReadComm((UCHAR*)ans, 128);
	if (strstr(ans, "ERROR") != NULL)
		return FALSE;

	/*设置回显:(此步骤为了测试方便)ATE1 */
	m_serial.WriteComm((UCHAR*)"ATE0\r", 5);
	Sleep(30);
	m_serial.ReadComm((UCHAR*)ans, 128);

	/* PDU模式 */
	m_serial.WriteComm((UCHAR*)"AT+CMGF=0\r", 10);
	Sleep(30);
	m_serial.ReadComm((UCHAR*)ans, 128);

	/* 选择话筒 */
	m_serial.WriteComm((UCHAR*)"AT+SPEAKER=1\r", 15);
	Sleep(30);

	/*设置GPRS新消息提示方式 */
//	m_serial.WriteComm((UCHAR*)"AT+CMGS=2,1,0,0,1\r", 20);
//	m_serial.ReadComm((UCHAR*)ans, 128);
	return TRUE;
}

/*!	发送短消息,仅发送命令,不读取应答
	\param [in]	strNum - 发送消息手机号
	\param [in] strCon - 短消息内容
	\return		成功返回TRUE,失败返回FALSE。
*/
BOOL CGPRSer::gprsSendMessage(CString strNum, CString strCon)
{

	CHAR ans[128] = {0};		/* 应答串 */
	CString strSmsc = "";
	CString strNumber = "";
	CString strContent = "";

	m_serial.WriteComm((UCHAR*)"AT+CSCA?\r", 10);
	Sleep(60);
	m_serial.ReadComm((UCHAR*)ans, 128);
	if (strstr(ans, "+CSCA:"))
	{
		CString strTempCsca = CString(ans);
		strSmsc = strTempCsca.Mid(10, 14);
		if ((strSmsc.GetLength() != 14) || (strSmsc.GetAt(0) != '+'))
		{
			AfxMessageBox(_T("提取短消息中心号码失败!请重新设置短消息中心号码!"));
		}
	}else{
		AfxMessageBox(_T("提取短消息中心号码失败!请重新设置短消息中心号码!"));
	}

	strNumber = strNum;
	strContent = strCon;

	SM_PARAM SmParam;
	memset(&SmParam, 0, sizeof(SM_PARAM));

	/* 去掉号码前的"+" */
	if(strSmsc[0] == '+')  strSmsc = strSmsc.Mid(1);
	if(strNumber[0] == '+')  strNumber = strNumber.Mid(1);

	/* 在号码前加"86" */
	if(strSmsc.Left(2) != "86")  strSmsc = "86" + strSmsc;
	if(strNumber.Left(2) != "86")  strNumber = "86" + strNumber;

	/* 填充短消息结构 */
	strcpy(SmParam.SCA, CStringToCharArray(strSmsc));
	strcpy(SmParam.TPA, CStringToCharArray(strNumber));
	wcscpy(SmParam.TP_UD, strContent);
	SmParam.TP_PID = 0;
	SmParam.TP_DCS = GSM_UCS2;

	int nPduLength;		/* PDU串长度 */
	UCHAR nSmscLength;	/* SMSC串长度 */
	int nLength;		/* 串口收到的数据长度 */
	char cmd[16];		/* 命令串 */
	char pdu[512];		/* PDU串 */

	nPduLength = gprsEncodePdu(&SmParam, pdu);	/* 根据PDU参数,编码PDU串 */
	strcat(pdu, "\x01a");		/* 以Ctrl-Z结束  strcat---字符串拼接函数 */

	gprsString2Bytes(pdu, &nSmscLength, 2);	/* 取PDU串中的SMSC信息长度 */
	nSmscLength++;		/* 加上长度字节本身 */

	/* 命令中的长度,不包括SMSC信息长度,以数据字节计 */
	sprintf(cmd, "AT+CMGS=0%d\r", nPduLength / 2 - nSmscLength);	/* 生成命令 */
	/*送格式化输出到字符串cmd中 */

//	TRACE("%s", cmd);
//	TRACE("%s\n", pdu);

	m_serial.WriteComm((UCHAR*)cmd, strlen(cmd));	/* 先输出命令串 */

	Sleep(60);
	nLength = m_serial.ReadComm((UCHAR*)ans, 128);	/* 读应答数据 */

	/* 根据能否找到"+CMS ERROR"决定成功与否 */
	if(nLength > 0 && strncmp(ans, "+CMS ERROR", 10) != 0)
	{
		m_serial.WriteComm((UCHAR*)pdu, strlen(pdu));
		Sleep(30);
		nLength = m_serial.ReadComm((UCHAR*)ans, 128);
		if((nLength > 0) && strstr(ans, "> "))
		{
			AfxMessageBox(TEXT("Send succeessfully!"));
		}
		return TRUE;
	}
	else
	{
		AfxMessageBox(TEXT("Send fail!"));
		return FALSE;
	}
}

/*!	PDU编码,用于编制、发送短消息
	\param [in]	pSrc - 源PDU参数指针 
	\param [in] pDst - 目标PDU串指针 
	\return	目标PDU串长度
*/
DWORD CGPRSer::gprsEncodePdu(const SM_PARAM *pSrc, CHAR *pDst)
{
	DWORD nLength;			/* 内部用的串长度 */
	DWORD nDstLength;		/* 目标PDU串长度 */
	UCHAR buf[256];			/* 内部用的缓冲区 */

	/* SMSC地址信息段 */
	nLength = strlen(pSrc->SCA);	/* SMSC地址字符串的长度	*/
	buf[0] = (char)((nLength & 1) == 0 ? nLength : nLength + 1) / 2 + 1;	/* SMSC地址信息长度 */
	buf[1] = 0x91;		/* 固定: 用国际格式号码 */
	nDstLength = gprsBytes2String(buf, pDst, 2);		/* 转换2个字节到目标PDU串 */
	nDstLength += gprsInvertNumbers(pSrc->SCA, &pDst[nDstLength], nLength);	/* 转换SMSC号码到目标PDU串 */

	/* TPDU段基本参数、目标地址等 */
	nLength = strlen(pSrc->TPA);	/* TP-DA地址字符串的长度 */
	buf[0] = 0x11;					/* 是发送短信(TP-MTI=01),TP-VP用相对格式(TP-VPF=10) */
	buf[1] = 0;						/* TP-MR=0 */
	buf[2] = (char)nLength;			/* 目标地址数字个数(TP-DA地址字符串真实长度) */
	buf[3] = 0x91;					/* 固定: 用国际格式号码 */
	nDstLength += gprsBytes2String(buf, &pDst[nDstLength], 4);		/* 转换4个字节到目标PDU串 */
	nDstLength += gprsInvertNumbers(pSrc->TPA, &pDst[nDstLength], nLength);	/* 转换TP-DA到目标PDU串 */

	/* TPDU段协议标识、编码方式、用户信息等 */
	nLength = wcslen(pSrc->TP_UD);	/* 用户信息字符串的长度 */
	buf[0] = pSrc->TP_PID;			/* 协议标识(TP-PID) */
	buf[1] = pSrc->TP_DCS;			/* 用户信息编码方式(TP-DCS) */
	buf[2] = 0;						/* 有效期(TP-VP)为5分钟 */
	if(pSrc->TP_DCS == GSM_7BIT)	
	{
		/* 7-bit编码方式 */
		buf[3] = nLength;			/* 编码前长度 */
//		nLength = gsmEncode7bit(pSrc->TP_UD, &buf[4], nLength+1) + 4;	/* 转换TP-DA到目标PDU串 */

	}
	else if(pSrc->TP_DCS == GSM_UCS2)
	{
		/* UCS2编码方式 */
		buf[3] = gprsEncodeUcs2(pSrc->TP_UD, &buf[4], nLength);	/* 转换TP-DA到目标PDU串 */
		nLength = buf[3] + 4;		/* nLength等于该段数据长度 */
	}
	else
	{
		/* 8-bit编码方式 */
//		buf[3] = gsmEncode8bit(pSrc->TP_UD, &buf[4], nLength);	/* 转换TP-DA到目标PDU串 */
		nLength = buf[3] + 4;		/* nLength等于该段数据长度 */
	}
	nDstLength += gprsBytes2String(buf, &pDst[nDstLength], nLength);		/* 转换该段数据到目标PDU串 */

	/* 返回目标字符串长度 */
	return nDstLength;
}

/*! UCS2编码 
	\param [in] pSrc - 源字符串指针 
    \param [in] nSrcLength - 源字符串长度 
	\param [out] pDst - 目标编码串指针 
	\return 目标编码串长度 
*/
DWORD CGPRSer::gprsEncodeUcs2(const TCHAR *pSrc, UCHAR *pDst, DWORD nSrcLength)
{
	/* 高低字节对调,输出 */
	for(int i=0; i < (INT)nSrcLength; i++)
	{
		*pDst++ = *pSrc >> 8;		/* 先输出高位字节 */
		*pDst++ = *pSrc++ & 0xff;		/* 后输出低位字节 */
	}

	/* 返回目标编码串长度 */
	return nSrcLength * 2;
}

/*! 打电话函数
	\param [in] str - 呼号的电话号码
	\return 拨号成功返回TRUE,失败返回FALSE
*/
BOOL CGPRSer::gprsCall(CString str)
{
	UCHAR sendbuf[256];
	CString strSend;
	strSend = "atd";
	strSend = strSend + str;
	strSend = strSend + ";\r\n";

	for (INT i=0; i < strSend.GetLength();i++)
	{
		sendbuf[i] = strSend.GetAt(i); 
	}

	m_serial.WriteComm(sendbuf, strSend.GetLength());
	
	return TRUE;
}

/*! 字符串数据转换成字符组数据函数
	\param [in] str - 待转换的字符串数据
	\return 由字符串转换成字符组数据
*/
CHAR* CGPRSer::CStringToCharArray(CString str)
{
	for (INT i = 0; i < str.GetLength(); i++)
	{
		ch[i] = str.GetAt(i);
	}
	ch[i] = '\0';
	return ch;
}

/*! 挂机函数
	\param  无
	\return 拦挂机成功返回TRUE,失败返回FALSE
*/
BOOL CGPRSer::gprsHang()
{
	m_serial.WriteComm((UCHAR*)"ath\r", 4);
	return TRUE;
}

/*! UCS2解码 
	\param [in] pSrc - 源编码串指针
	\param [in] nSrcLength -  源编码串长度
	\param [out] pDst -  目标字符串指针
	\return 目标字符串长度 
*/
DWORD CGPRSer::gprsDecodeUcs2(const UCHAR *pSrc, TCHAR *pDst, DWORD nSrcLength)
{
	/* 高低字节对调,拼成UNICODE */
	for(INT i=0; i < (INT)nSrcLength/2; i++)
	{
		*pDst = *pSrc++ << 8;	/* 先高位字节 */
		*pDst++ |= *pSrc++;		/* 后低位字节 */
	}

	/* 输出字符串加个结束符 */
	*pDst = '\0';

	/* 返回目标字符串长度 */
	return (nSrcLength/2);
}

/*! 7bit解码
	\param [in] pSrc - 源编码串指针
	\param [in] nSrcLength - 源编码串长度
	\param [out] pDst - 目标字符串指针
	\return 目标字符串长度 

⌨️ 快捷键说明

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