📄 sms.cpp
字号:
nDstLength = tmp;
}
else if(pDst->TP_DCS == GSM_UCS2)
{
// UCS2解码
nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2); // 格式转换
nDstLength = gsmDecodeUcs2(buf, pDst->TP_UD, nDstLength); // 转换到TP-DU,将unicode码转换成汉字
}
else
{
// 8-bit解码
nDstLength = gsmString2Bytes(pSrc, buf, tmp * 2); // 格式转换
nDstLength = gsmDecode8bit(buf, pDst->TP_UD, nDstLength); // 转换到TP-DU
}
// 返回目标字符串长度
return nDstLength;
}
BOOL SendPduMessage()
{
return TRUE;
}
// 发送短消息,仅发送命令,不读取应答
// 输入: pSrc - 源PDU参数指针
int GprsSendMessage(SM_PARAM* pSrc)
{
int nPduLength; // PDU串长度
unsigned char nSmscLength; // SMSC串长度
char cmd[16]; // 命令串
char pdu[512]; // PDU串
char ans[128]; // 应答串
nPduLength = gsmEncodePdu(pSrc, pdu); // 根据PDU参数,编码PDU串
strcat(pdu, "\x01a"); // 以Ctrl-Z结束
gsmString2Bytes(pdu, &nSmscLength, 2); // 取PDU串中的SMSC信息长度
nSmscLength++; // 加上长度字节本身
// 命令中的长度,不包括SMSC信息长度,以数据字节计
sprintf(cmd, "AT+CMGS=%d\r", nPduLength / 2 - nSmscLength); // 生成命令
// TRACE("%s", cmd);
// TRACE("%s\n", pdu);
for(int i=0;i<3;i++) // 测试AT+I指令,允许重发两次,否则初始化失败,检查硬件连接
{
WriteComm(cmd, strlen(cmd)); // 先输出命令串
ReadComm(ans, 128); // 读应答数据
if (strstr(ans, ">") == NULL)// 返回ok,说明初始化成功
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
WriteComm(pdu, strlen(pdu)); // 得到肯定回答,继续输出PDU串
return 0;
}
// 读取短消息,仅发送命令,不读取应答
// 用+CMGL代替+CMGR,可一次性读出全部短消息
int gsmReadMessageList()
{
return WriteComm("AT+CMGL=0\r", 10);
}
// 删除短消息,仅发送命令,不读取应答
// 输入: index - 短消息序号,1-255
int gsmDeleteMessage(int index)
{
char cmd[16]; // 命令串
sprintf(cmd, "AT+CMGD=%d\r", index); // 生成命令
// 输出命令串
return WriteComm(cmd, strlen(cmd));
}
// 读取GSM MODEM的应答,可能是一部分
// 输出: pBuff - 接收应答缓冲区
// 返回: GSM MODEM的应答状态, GSM_WAIT/GSM_OK/GSM_ERR
// 备注: 可能需要多次调用才能完成读取一次应答,首次调用时应将pBuff初始化
int gsmGetResponse(SM_BUFF* pBuff)
{
int nLength; // 串口收到的数据长度
int nState;
// 从串口读数据,追加到缓冲区尾部
nLength = ReadComm(&pBuff->data[pBuff->len], 128);
pBuff->len += nLength;
// 确定GSM MODEM的应答状态
nState = GSM_WAIT;
if ((nLength > 0) && (pBuff->len >= 4))
{
if (strncmp(&pBuff->data[pBuff->len - 4], "OK\r\n", 4) == 0) nState = GSM_OK;
else if (strstr(pBuff->data, "ERROR") != NULL) nState = GSM_ERR;
}
return nState;
}
// 从列表中解析出全部短消息
// 输入: pBuff - 短消息列表缓冲区
// 输出: pMsg - 短消息缓冲区
// 返回: 短消息条数
int gsmParseMessageList(SM_PARAM* pMsg, SM_BUFF* pBuff)
{
int nMsg; // 短消息计数值
char* ptr; // 内部用的数据指针
nMsg = 0;
ptr = pBuff->data;
// 循环读取每一条短消息, 以"+CMGL:"开头
while((ptr = strstr(ptr, "+CMGL:")) != NULL)
{
ptr += 6; // 跳过"+CMGL:", 定位到序号
sscanf(ptr, "%d", &pMsg->index); // 读取序号,此序号在ptr内容的第一个字节保存
// TRACE(" index=%d\n",pMsg->index);
ptr = strstr(ptr, "\r\n"); // 找下一行
if (ptr != NULL)
{
ptr += 2; // 跳过"\r\n", 定位到PDU
gsmDecodePdu(ptr, pMsg); // PDU串解码
pMsg++; // 准备读下一条短消息
nMsg++; // 短消息计数加1
}
}
return nMsg;
}
// 初始化Gprs
// 返回: TRUE 初始化成功 FALSE 初始化失败
BOOL InitGprs()
{
char ans[30];
char buffer[30];
for(int i=0;i<3;i++) // 测试AT+I指令,允许重发两次,否则初始化失败,检查硬件连接
{
WriteComm("AT+I\r",5);
ReadComm(ans,20);
if (strstr(ans, "I/OK") == NULL)// 返回ok,说明初始化成功
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
for(i=0;i<3;i++) // 测试AT+IMCM指令,进入手机模块AT命令直传状态
{
WriteComm("AT+IMCM\r",8);
ReadComm(ans,20);
if (strstr(ans, "I/OK") == NULL)
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
for(i=0;i<3;i++) // 设置短消息中心号码,其格式为AT+CMGF="+8613800451500"
{
int length = sprintf(buffer,"AT+CSCA=%c+8613800451500%c\r",34,34);
WriteComm(buffer,length);
ReadComm(ans,30);
if (strstr(ans, "OK") == NULL) // 返回OK,说明设置成功
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
return TRUE;
}
// 设置短消息发送格式
// 格式:state,为0表示Text方式,不能发送汉字,为1表示PDU格式,可以发送汉字
// 返回: TRUE设置成功 FALSE 设置失败
BOOL SetMessageType(int state)
{
char ans[30];
for(int i=0;i<3;i++) // 测试AT+CMGF=1指令,设置短消息发送方式
{
if(state==0) WriteComm("AT+CMGF=1\r",25); // Text发送
else if(state==1) WriteComm("AT+CMGF=0\r",25); // PDU发送
ReadComm(ans,30);
if (strstr(ans, "OK") == NULL)
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
return TRUE;
}
// 切换AT指令和ATI指令
// type:指令类型,为真为ATI指令集,为假则为AT指令集
BOOL ChangeCommandType(BOOL type)
{
char ans[60];
if (type)
{
for(int i=0;i<3;i++) // 测试AT+IMCM指令,进入手机模块AT命令直传状态
{
WriteComm("AT+I\r",8);
ReadComm(ans,20);
if (strstr(ans, "I/OK") == NULL)
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
}
else
{
for(int i=0;i<3;i++) // 测试AT+IMCM指令,进入手机模块AT命令直传状态
{
WriteComm("AT+IMCM\r",8);
ReadComm(ans,20);
if (strstr(ans, "I/OK") == NULL)
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
}
return TRUE;
}
// 以Text方式发送短消息
// number:对方手机号码
// content:短信内容
// 返回:TRUE 发送成功,FALSE 发送失败
BOOL SendTextMessage(CString number,CString content)
{
char ans[60];
char buffer[30];
int length;
for(int i=0;i<3;i++) // 发送目标手机号
{
length = sprintf(buffer,"AT+CMGS=%c+86%s%c\r",34,number,34);
WriteComm(buffer,length);
ReadComm(ans,30);
if (strstr(ans, ">") == NULL)
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
for(i=0;i<3;i++) // 发送短消息内容
{
length = sprintf(buffer,"%s%c",content,26);
WriteComm(buffer,length);
Sleep(2000);
ReadComm(ans,140);
if (strstr(ans, "OK") == NULL)
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
return TRUE;
}
// 打开并建立一个SOCKET连接
// 输入: pSocket 需要建立的pSocket连接的参数
// 仅发送命令,不接收应答
// 指令:AT+ISTCP:xxx.xxx.xxx.xxx,<Port Number> <CR>句柄,此指令返回socket句柄
BOOL ConnectSocket(SOCKET_PARAM* pSocket)
{
char ans[60];
for(int i=0;i<3;i++) // 切换到AT+I指令
{
WriteComm("AT+I\r",5);
ReadComm(ans,30);
if (strstr(ans, "OK") == NULL)
{
if(i==2)
{
return FALSE;
}
Sleep(500);
}
else
{
break;
}
}
char buffer[40];
int length = sprintf(buffer,"AT+ISTCP:%s,%s\r",pSocket->IP_ADDRESS,pSocket->PORT_NUMBER);
WriteComm(buffer,length);
return TRUE;
}
// 关闭一个SOCKET连接
// 输入: pSocket 需要建立的pSocket连接的参数
// 仅发送命令,不接收应答
// 指令:AT+ISCLS:000<CR>,句柄000为socket等待返回I/DONE
void CloseSocket(SOCKET_PARAM* pSocket)
{
char buffer[20];
int length = sprintf(buffer,"AT+ISCLS:%s\r",pSocket->SOCKET_HANDLE);
WriteComm(buffer,length);
}
// 通过指定socket发送数据
// 输入: pSocket 需要发送的数据以及相应的socket信息
// 仅发送命令,不接收应答
// 指令:AT+ISSND%:xxx,<string Length>:<CR>
void SocketSendData(SOCKETDATA_PARAM* pSocket)
{
char buffer[5000]; // 长度以后需要指定
int length = sprintf(buffer,"AT+ISSND%c:%s,%d:%s\r",37,pSocket->SOCKET_HANDLE,strlen(pSocket->SEND_DATA),pSocket->SEND_DATA);
WriteComm(buffer,length);
}
// 从缓冲区数据列表中解析出数据包
// 输入: pBuff - 数据列表缓冲区
// 输入: pSocket - 当前的socket信息
// 输出: pData - 数据包缓冲区
// 返回: 数据包个数
int SocketParseMessageList(SOCKET_PARAM* pSocket,SOCKETDATA_PARAM* pData, SOCKET_BUFF* pBuff)
{
int nMsg = 0; // 数据包计数值
char *ptr;
int length; // 记录缓冲区中字节数据长度
ptr = strstr(pBuff->data,"I/");
ptr +=2;
sscanf(ptr,"%d",&length);
if(length>0)
{
ptr = strstr(ptr,":");
ptr += 1;
strcpy(pData->SEND_DATA,ptr);
strcpy(pData->IP_ADDRESS,pSocket->IP_ADDRESS);
strcpy(pData->PORT_NUMBER,pSocket->PORT_NUMBER);
strcpy(pData->SOCKET_HANDLE,pSocket->SOCKET_HANDLE);
nMsg = 1;
}
return nMsg;
}
// 读取缓冲区中的数据,仅发送命令,不读取应答
// 一次性的读出缓冲区中的所有数据
// 指令AT+ISRCV:xxx<CR>
void SocketReadDataList(SOCKET_PARAM* pSocket)
{
CString str;
str.Format("AT+ISRCV:%s\r",pSocket->SOCKET_HANDLE);
WriteComm(str.GetBuffer(15),str.GetLength());
}
// 读取Socket通讯时应答
// 输出: pBuff - 接收应答缓冲区
// 备注: 可能需要多次调用才能完成读取一次应答,首次调用时应将pBuff初始化
void SocketGetResponse(SOCKET_BUFF* pBuff)
{
int nLength; // 串口收到的数据长度
// 从串口读数据,追加到缓冲区尾部
nLength = ReadComm(&pBuff->data[pBuff->len], 128);
pBuff->len += nLength;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -