#pragma once
#include "SIM_Card.h"
class SIM_SendMessage: public SIM_Card
{
public:
SIM_SendMessage(void);
SIM_SendMessage(Comm* pC);
~SIM_SendMessage(void);
// 用ASCII编码发送短消息,仅发送命令,不读取应答
// 输入: strSmsc - 短信服务中心号码(16个字节以内)
// strNumber - 目标手机号码(16个字节以内)
// strContent - 发送的短信内容(160个字节以内)
// 输出: ans - 流水号串
// 返回: GSM MODEM的应答状态, GSM_WAIT/GSM_OK/GSM_ERR
int gsmSendMessageASCII(string strNumber, string strContent,string strSmsc = "+8613800200500", string* ans = NULL);
// 用PDU编码发送短消息,仅发送命令,不读取应答
// 输入: strSmsc - 短信服务中心号码(16个字节以内)
// strNumber - 目标手机号码(16个字节以内)
// strContent - 发送的短信内容(160个字节以内)
// 输出: ans - 流水号串
// 返回: GSM MODEM的应答状态, GSM_WAIT/GSM_OK/GSM_ERR
int gsmSendMessagePDU(string strNumber, string strContent,string strSmsc = "8613800200500",string* ans = NULL);
protected:
// 获得待发短信的数据包
// 输入: strSmsc - 短信服务中心号码(16个字节以内,需86开头)
// strNumber - 目标手机号码(16个字节以内,需86开头)
// strContent - 发送的短信内容(160个字节以内)
// 返回: SM_PARAM* - 待发短信的数据包的指针(用后需释放)
SM_PARAM* GetNoteStruct(string strNumber, string strContent, string strSmsc);
};
#include "StdAfx.h"
#include "SIM_SendMessage.h"
SIM_SendMessage::SIM_SendMessage(void)
{
}
SIM_SendMessage::SIM_SendMessage(Comm* pC):SIM_Card(pC)
{
}
SIM_SendMessage::~SIM_SendMessage(void)
{
}
// 用ASCII编码发送短消息,仅发送命令,不读取应答
// 输入: strSmsc - 短信服务中心号码(16个字节以内)
// strNumber - 目标手机号码(16个字节以内)
// strContent - 发送的短信内容(160个字节以内)
// 输出: ans - 流水号串
// 返回: GSM MODEM的应答状态, GSM_WAIT/GSM_OK/GSM_ERR
int SIM_SendMessage::gsmSendMessageASCII(string strNumber, string strContent, string strSmsc, string* ans)
{
int k;
SM_BUFF Buff;
//清空缓冲区
pComm->ClearBuff();
if( strcmp(strNumber.substr(0,1).c_str(),"86") == 0)
{//不需86开头
strNumber.erase(0,1);
}
if( strcmp(strSmsc.substr(0,2).c_str(),"+86") != 0)
{//需+86开头
strSmsc.insert(0,"+86");
}
//发送短信
string strS = "AT+CSCA="; //设置短信服务中心号码
strS += strSmsc;
strS += "/r";
pComm->WriteComm((void*)strS.c_str(),strS.size());
k = gsmGetResponse(&Buff,10, "OK","ERROR");
if( GSM_OK == k)
{
char* cmd = "AT+CMGF=1/r"; //设置ASCII编码
pComm->WriteComm(cmd,20);
k = gsmGetResponse(&Buff,10, "OK","ERROR");
if( GSM_OK == k)
{
string Set_Num = "AT+CMGS="; //设置目标手机号
Set_Num += strNumber;
Set_Num += "/r";
pComm->WriteComm((void*)Set_Num.c_str(),Set_Num.size());
gsmGetResponse(&Buff,10, "/r/n> ","ERROR");
// 根据能否找到"/r/n> "决定成功与否
if(strstr(Buff.data, "/r/n> ") != NULL)
{
strContent += (char)26;
strContent += '/0';
pComm->WriteComm((void*)strContent.c_str(),strContent.size()); //发送短信
// 注意: ASCII编码的回复和PDU编码的回复不一样
// ASCII码回复两次, 第一次回复发送内容, 第二次才回复流水号
// PDU编码回复一次,直接回复流水号
k = gsmGetResponse(&Buff,5, strContent.c_str(),"ERROR");
k = gsmGetResponse(&Buff, 5, "+CMGS","ERROR");
if( GSM_OK == k)
{
*ans = Buff.data;
return GSM_OK;
}
}
}
}
return k;
}
// 获得待发短信的数据包
// 输入: strSmsc - 短信服务中心号码(16个字节以内)
// strNumber - 目标手机号码(16个字节以内)
// strContent - 发送的短信内容(160个字节以内)
// 返回: SM_PARAM* - 待发短信的数据包的指针(用后需释放)
SM_PARAM* SIM_SendMessage::GetNoteStruct(string strNumber, string strContent, string strSmsc)
{
SM_PARAM* pSmParam = new SM_PARAM();
memset(pSmParam, 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(pSmParam->SCA, strSmsc.c_str());
strcpy(pSmParam->TPA, strNumber.c_str());
strcpy(pSmParam->TP_UD, strContent.c_str());
pSmParam->TP_PID = 0;
pSmParam->TP_DCS = GSM_UCS2;
return pSmParam;
}
// 用PDU编码发送短消息,仅发送命令,不读取应答
// 输入: strSmsc - 短信服务中心号码(16个字节以内)
// strNumber - 目标手机号码(16个字节以内)
// strContent - 发送的短信内容(160个字节以内)
// 输出: ans - 流水号串
// 返回: GSM MODEM的应答状态, GSM_WAIT/GSM_OK/GSM_ERR
int SIM_SendMessage::gsmSendMessagePDU(string strNumber, string strContent,string strSmsc, string* ans)
{
int k = -1;
SM_BUFF Buff;
//清空缓冲区
pComm->ClearBuff();
if( strcmp(strNumber.substr(0,1).c_str(),"86") != 0)
{//需86开头
strNumber.insert(0,"86");
}
if( strcmp(strSmsc.substr(0,1).c_str(),"86") != 0)
{//需86开头
strSmsc.insert(0,"86");
}
//读写
char* cmdU = "AT+CMGF=0/r"; //设置U编码
pComm->WriteComm(cmdU,20);
k = gsmGetResponse(&Buff,10, "OK","ERROR");
if( GSM_OK == k)
{
SM_PARAM* pSmParam = GetNoteStruct(strNumber, strContent, strSmsc);
int nPduLength; // PDU串长度
unsigned char nSmscLength; // SMSC串长度
char cmd[16]; // 命令串
char pdu[512]; // PDU串
nPduLength = gsmEncodePdu(pSmParam, 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); // 生成命令
pComm->WriteComm(cmd, strlen(cmd)); // 先输出命令串
k = gsmGetResponse(&Buff,10, "/r/n> ","ERROR");
// 根据能否找到"/r/n> "决定成功与否
if(strstr(Buff.data, "/r/n> ") != NULL)
{
pComm->WriteComm(pdu, strlen(pdu)); // 得到肯定回答,继续输出PDU串
// 注意: ASCII编码的回复和PDU编码的回复不一样
// ASCII码回复两次, 第一次回复发送内容, 第二次才回复流水号
// PDU编码回复一次,直接回复流水号
k = gsmGetResponse(&Buff,5, "+CMGS", "ERROR");
if( GSM_OK == k)
{
*ans = Buff.data;
if( NULL != pSmParam)
{
delete pSmParam;
pSmParam = NULL;
}
return GSM_OK;
}
}
if( NULL != pSmParam)
{
delete pSmParam;
pSmParam = NULL;
}
}
return k;
}