?? gprser.cpp
字號:
/*! \file GGPRSer.cpp
\brief GPRS類實現(xiàn)文件
\author 陳華毅
\version 1.0
通過實現(xiàn)CGPRSer類,應(yīng)用程序可以通過CGPRSer類的實體來實現(xiàn)對GPRS模塊操作。
\defgroup GPRSER_IMPLEMENT CGPRSDer類實現(xiàn)說明
*/
#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構(gòu)造函數(shù),構(gòu)造時打開串口
\param 無
\return 無
*/
CGPRSer::CGPRSer()
{
m_serial.OpenComm();
}
/*! CGPRS析構(gòu)函數(shù),析構(gòu)時關(guān)閉串口
\param 無
\return 無
*/
CGPRSer::~CGPRSer()
{
m_serial.CloseComm();
}
/*! 初始化GSM狀態(tài)
\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;
/*設(shè)置回顯:(此步驟為了測試方便)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);
/*設(shè)置GPRS新消息提示方式 */
// m_serial.WriteComm((UCHAR*)"AT+CMGS=2,1,0,0,1\r", 20);
// m_serial.ReadComm((UCHAR*)ans, 128);
return TRUE;
}
/*! 發(fā)送短消息,僅發(fā)送命令,不讀取應(yīng)答
\param [in] strNum - 發(fā)送消息手機(jī)號
\param [in] strCon - 短消息內(nèi)容
\return 成功返回TRUE,失敗返回FALSE。
*/
BOOL CGPRSer::gprsSendMessage(CString strNum, CString strCon)
{
CHAR ans[128] = {0}; /* 應(yīng)答串 */
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("提取短消息中心號碼失敗!請重新設(shè)置短消息中心號碼!"));
}
}else{
AfxMessageBox(_T("提取短消息中心號碼失敗!請重新設(shè)置短消息中心號碼!"));
}
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;
/* 填充短消息結(jié)構(gòu) */
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; /* 串口收到的數(shù)據(jù)長度 */
char cmd[16]; /* 命令串 */
char pdu[512]; /* PDU串 */
nPduLength = gprsEncodePdu(&SmParam, pdu); /* 根據(jù)PDU參數(shù),編碼PDU串 */
strcat(pdu, "\x01a"); /* 以Ctrl-Z結(jié)束 strcat---字符串拼接函數(shù) */
gprsString2Bytes(pdu, &nSmscLength, 2); /* 取PDU串中的SMSC信息長度 */
nSmscLength++; /* 加上長度字節(jié)本身 */
/* 命令中的長度,不包括SMSC信息長度,以數(shù)據(jù)字節(jié)計 */
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); /* 讀應(yīng)答數(shù)據(jù) */
/* 根據(jù)能否找到"+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編碼,用于編制、發(fā)送短消息
\param [in] pSrc - 源PDU參數(shù)指針
\param [in] pDst - 目標(biāo)PDU串指針
\return 目標(biāo)PDU串長度
*/
DWORD CGPRSer::gprsEncodePdu(const SM_PARAM *pSrc, CHAR *pDst)
{
DWORD nLength; /* 內(nèi)部用的串長度 */
DWORD nDstLength; /* 目標(biāo)PDU串長度 */
UCHAR buf[256]; /* 內(nèi)部用的緩沖區(qū) */
/* 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); /* 轉(zhuǎn)換2個字節(jié)到目標(biāo)PDU串 */
nDstLength += gprsInvertNumbers(pSrc->SCA, &pDst[nDstLength], nLength); /* 轉(zhuǎn)換SMSC號碼到目標(biāo)PDU串 */
/* TPDU段基本參數(shù)、目標(biāo)地址等 */
nLength = strlen(pSrc->TPA); /* TP-DA地址字符串的長度 */
buf[0] = 0x11; /* 是發(fā)送短信(TP-MTI=01),TP-VP用相對格式(TP-VPF=10) */
buf[1] = 0; /* TP-MR=0 */
buf[2] = (char)nLength; /* 目標(biāo)地址數(shù)字個數(shù)(TP-DA地址字符串真實長度) */
buf[3] = 0x91; /* 固定: 用國際格式號碼 */
nDstLength += gprsBytes2String(buf, &pDst[nDstLength], 4); /* 轉(zhuǎn)換4個字節(jié)到目標(biāo)PDU串 */
nDstLength += gprsInvertNumbers(pSrc->TPA, &pDst[nDstLength], nLength); /* 轉(zhuǎn)換TP-DA到目標(biāo)PDU串 */
/* TPDU段協(xié)議標(biāo)識、編碼方式、用戶信息等 */
nLength = wcslen(pSrc->TP_UD); /* 用戶信息字符串的長度 */
buf[0] = pSrc->TP_PID; /* 協(xié)議標(biāo)識(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; /* 轉(zhuǎn)換TP-DA到目標(biāo)PDU串 */
}
else if(pSrc->TP_DCS == GSM_UCS2)
{
/* UCS2編碼方式 */
buf[3] = gprsEncodeUcs2(pSrc->TP_UD, &buf[4], nLength); /* 轉(zhuǎn)換TP-DA到目標(biāo)PDU串 */
nLength = buf[3] + 4; /* nLength等于該段數(shù)據(jù)長度 */
}
else
{
/* 8-bit編碼方式 */
// buf[3] = gsmEncode8bit(pSrc->TP_UD, &buf[4], nLength); /* 轉(zhuǎn)換TP-DA到目標(biāo)PDU串 */
nLength = buf[3] + 4; /* nLength等于該段數(shù)據(jù)長度 */
}
nDstLength += gprsBytes2String(buf, &pDst[nDstLength], nLength); /* 轉(zhuǎn)換該段數(shù)據(jù)到目標(biāo)PDU串 */
/* 返回目標(biāo)字符串長度 */
return nDstLength;
}
/*! UCS2編碼
\param [in] pSrc - 源字符串指針
\param [in] nSrcLength - 源字符串長度
\param [out] pDst - 目標(biāo)編碼串指針
\return 目標(biāo)編碼串長度
*/
DWORD CGPRSer::gprsEncodeUcs2(const TCHAR *pSrc, UCHAR *pDst, DWORD nSrcLength)
{
/* 高低字節(jié)對調(diào),輸出 */
for(int i=0; i < (INT)nSrcLength; i++)
{
*pDst++ = *pSrc >> 8; /* 先輸出高位字節(jié) */
*pDst++ = *pSrc++ & 0xff; /* 后輸出低位字節(jié) */
}
/* 返回目標(biāo)編碼串長度 */
return nSrcLength * 2;
}
/*! 打電話函數(shù)
\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;
}
/*! 字符串?dāng)?shù)據(jù)轉(zhuǎn)換成字符組數(shù)據(jù)函數(shù)
\param [in] str - 待轉(zhuǎn)換的字符串?dāng)?shù)據(jù)
\return 由字符串轉(zhuǎn)換成字符組數(shù)據(jù)
*/
CHAR* CGPRSer::CStringToCharArray(CString str)
{
for (INT i = 0; i < str.GetLength(); i++)
{
ch[i] = str.GetAt(i);
}
ch[i] = '\0';
return ch;
}
/*! 掛機(jī)函數(shù)
\param 無
\return 攔掛機(jī)成功返回TRUE,失敗返回FALSE
*/
BOOL CGPRSer::gprsHang()
{
m_serial.WriteComm((UCHAR*)"ath\r", 4);
return TRUE;
}
/*! UCS2解碼
\param [in] pSrc - 源編碼串指針
\param [in] nSrcLength - 源編碼串長度
\param [out] pDst - 目標(biāo)字符串指針
\return 目標(biāo)字符串長度
*/
DWORD CGPRSer::gprsDecodeUcs2(const UCHAR *pSrc, TCHAR *pDst, DWORD nSrcLength)
{
/* 高低字節(jié)對調(diào),拼成UNICODE */
for(INT i=0; i < (INT)nSrcLength/2; i++)
{
*pDst = *pSrc++ << 8; /* 先高位字節(jié) */
*pDst++ |= *pSrc++; /* 后低位字節(jié) */
}
/* 輸出字符串加個結(jié)束符 */
*pDst = '\0';
/* 返回目標(biāo)字符串長度 */
return (nSrcLength/2);
}
/*! 7bit解碼
\param [in] pSrc - 源編碼串指針
\param [in] nSrcLength - 源編碼串長度
\param [out] pDst - 目標(biāo)字符串指針
\return 目標(biāo)字符串長度
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -