qt ok6410 gprs模块发送中文短信
2013-08-26 18:17
211 查看
ok6410自带的模块没有发送中文短信的测试程序,里面的测试程序时text模式的只能发送英文短信,由于工作中用到这个模块,而且需要发送中文短信,经过一段时间的调试,而且在网上找了很多的资料,终于调试通过了,现在把代码贴出来,记录一下。
发送中文短信,其实只有几步,使用串口发送AT+cmGF=0 回车,at+cmgs=发送的长度 然后就是pnone+unicode的短信内容了。代码如下:
#include <QtGui/QApplication>
#include "QtSMS.h"
#include <iconv.h>
#include "codeconvertor.h"
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// QTextCodec::setCodecForTr(QTextCodec::codecForName("unicode"));
QtSMS w;
w.OpenCom("/dev/ttySAC1",115200);
w.SendSms("123abc,,//?????/?//】【[]{}[jj』『』『、、|||、、||\\\"、、、////```````098jjsk爱!","13062669576");
// w.show();
// qDebug() << CodeConvertor::_tuf8ToUnicode("工作愉快!").data();
// qDebug()<<"\"5DE54F5C61095FEBFF01\"";
return a.exec();
}
#include "QtSMS.h"
#include "ui_QtSMS.h"
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <termio.h>
#include "codeconvertor.h"
QtSMS::QtSMS(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::QtSMS)
{
ui->setupUi(this);
// OpenCom("ttySAC1",115200);
// SendSms("您好!","13062669576");
iDelNum=1;
isAllDel = false;
iTotalSms=50;
// DelAllSms();
// sendAT(7);
// qDebug()<<unicodeToString("0500034902015C0A656C768452A8611F57305E265BA26237FF0C52A8611F57305E2654C1724C8FFD6C42201C65F65C1A3001597D73A9300163A27D22201D30025F53524D5E106237603B4F59989D4E3A0039002E003400315143FF0C51764E2D672C6708901A75284F59989D4E3A0039002E003400315143300256DE590D0031003100314E8689E34F59989D");
}
QtSMS::~QtSMS()
{
myCom->close();
delete ui;
}
int QtSMS::openSerialPort()
{
int fd = -1;
fd = ::open("/dev/ttySAC1", O_RDWR|O_NONBLOCK);
if (fd < 0) {
return -1;
}
termios serialAttr;
memset(&serialAttr, 0, sizeof serialAttr);
cfsetispeed(&serialAttr,B115200);
cfsetospeed(&serialAttr,B115200);
serialAttr.c_cflag &= ~CSIZE;
serialAttr.c_cflag |= CS8;
serialAttr.c_iflag = IGNPAR;
if (tcsetattr(fd, TCSANOW, &serialAttr) != 0) {
return -1;
}
return fd;
}
int QtSMS::OpenCom(const char* pStrPort,int iBaudRate)
{
#if 1
this->myCom = new QextSerialPort(pStrPort, QextSerialPort::EventDriven);
switch(iBaudRate) {
case 9600:
myCom->setBaudRate(BAUD9600);
break;
case 115200:
myCom->setBaudRate(BAUD115200);
break;
default:
myCom->setBaudRate(BAUD9600);
break;
}
myCom->setFlowControl(FLOW_OFF);
myCom->setParity(PAR_NONE);
myCom->setDataBits(DATA_8);
myCom->setStopBits(STOP_1);
if (myCom->open(QIODevice::ReadWrite) == true) {
connect(myCom, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(myCom, SIGNAL(dsrChanged(bool)), this, SLOT(onDsrChanged(bool)));
if (!(myCom->lineStatus() & LS_DSR))
qDebug() << "warning: device is not turned on";
qDebug() << "listening for data on" << myCom->portName();
}
else {
qDebug() << "device failed to open:" << myCom->errorString();
}
// connect(myCom,SIGNAL(readyRead()),this,SLOT(slotReadMesg()));
#else
my_fd=this->openSerialPort();
#endif
return 1;
}
void QtSMS::onReadyRead()
{
QByteArray bytes;
int a = myCom->bytesAvailable();
bytes.resize(a);
myCom->read(bytes.data(), bytes.size());
qDebug() << "bytes read:" << bytes.size();
qDebug() << "bytes:" << bytes;
}
void QtSMS::onDsrChanged(bool status)
{
if (status)
qDebug() << "device was turned on";
else
qDebug() << "device was turned off";
}
void QtSMS::SendSms(QString qStrSend,QString qStrNum)
{
sendAT(1);
convertPhone(qStrNum);
convertMesg(qStrSend);
sleep(2);
sendAT(2);
sleep(2);
sendAT(3);
sleep(3);
}
void QtSMS::DelAllSms()
{
isAllDel = true;
iDelNum=1;
sendAT(6);
}
SmsInfo QtSMS::GetSms()
{
while(m_SmsList.size()!=0)
{
QString qStrSms = m_SmsList.back(); //读取最后一个
int iSms;
char *ptr = (char*)qStrSms.toStdString().c_str();
sscanf(ptr,"%d",&iSms);
cout<<"iSms ===="<<iSms<<endl;
ptr=strstr(ptr,",");
ptr++;
m_SmsList.pop_back(); //去掉最后一个
DecodePdu(ptr);
// iDelNum = iSms;
// sendAT(6);
// isAllDel = false;
}
SmsInfo sms;
return sms;
}
void QtSMS::sendAT(int iOrder)
{
QString qStrCmd;
switch(iOrder)
{
case 1:
{
//设置短信格式
qStrCmd= "AT+CMGF=0\r";
myCom->write(qStrCmd.toAscii());
//#endif
break;
}
case 2:
{
//发送短信长度指令
int iLength=strlen(m_SendCont.toStdString().c_str())/2;
qDebug()<<"sms======len:"<<iLength;
qStrCmd=QString("%1%2\r").arg("AT+CMGS=").arg(iLength-9);
myCom->write(qStrCmd.toAscii());
break;
}
case 3:
{
//发送短信内容指令
// myCom->write("0011000D91683166051461F70008011600680065006C006C006F00204F60597D0021000D000A\x01a");
qDebug()<<"sms======cont:"<<m_SendCont;
myCom->write((m_SendCont+"\x01a").toStdString().c_str());
break;
}
case 4:
{
//短信容量查询指令
qStrCmd = "AT+CPMS?\r";
myCom->write(qStrCmd.toAscii());
break;
}
case 5:
{
//设置新短信通知指令
qStrCmd="AT+CNMI=2,1\r";
myCom->write(qStrCmd.toAscii());
break;
}
case 6:
{
//短信删除指令
qStrCmd= tr("AT+CMGD=%1\r").arg(iDelNum);
qDebug()<<qStrCmd;
myCom->write(qStrCmd.toAscii());
break;
}
case 7:
{
//读取未读短信
qStrCmd= "AT+CMGL=0\r";
qDebug()<<qStrCmd;
myCom->write(qStrCmd.toAscii());
break;
}
default:
break;
}
}
QString QtSMS::stringToUnicode(QString str)
{
// 这里传来的字符串一定要加tr,main函数里可以加 QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
// 例如:str=tr("你好");
const QChar *q;
QChar qtmp;
QString str0, strout;
int num;
q=str.unicode();
int len=str.count();
for(int i=0;i<len;i++)
{
qtmp =(QChar)*q++;
num= qtmp.unicode();
// if(num<255)
// strout+="00"; //英文或数字前加"00"
str0=str0.setNum(num,16);//变成十六进制数
strout+=str0;
}
return strout;
}
QString QtSMS::unicodeToString(QString str)
{
//例如 str="4F60597D";
// qDebug()<<str;
int temp[400];
QChar qchar[100];
QString strOut;
bool ok;
int count=str.count();
int len=count/4;
for(int i=0;i<count;i+=4)
{
temp[i]=str.mid(i,4).toInt(&ok,16);//每四位转化为16进制整型
qchar[i/4]=temp[i];
QString str0(qchar, len);
strOut=str0;
}
qDebug()<<"wyz=========smsInfo:"<<strOut<<endl;
return strOut;
}
int QtSMS::convertMesg(QString qStrMesg)
{
qStrMesg=CodeConvertor::tuf8ToUnicode(qStrMesg);
qDebug()<<"unicode is:"<<qStrMesg;
int i=qStrMesg.length()/2; //内容长度
QString sHex;
sHex.setNum(i,16);
if(sHex.length()==1)
{
sHex="0"+sHex;
}
QString qStrMesgs;
qStrMesgs = QString("%1%2").arg(sHex).arg(qStrMesg);
m_SendCont+=qStrMesgs;
return qStrMesgs.length();
}
int QtSMS::convertPhone(QString qStrPhone)
{
int i=qStrPhone.length()+2; //长度包括86
QString sHex;
sHex.setNum(i,16); //转成十六进制
if(sHex.length()==1)
{
sHex="0"+sHex;
}
if(qStrPhone.length()%2 !=0) //为奇数位后面加F
{
qStrPhone+="F";
}
qDebug()<<"phone num is:"<<qStrPhone;
//奇数位偶数位交换
QString qStrTemp2;
for(int i=0; i<qStrPhone.length(); i+=2)
{
qStrTemp2 +=qStrPhone.mid(i+1,1)+qStrPhone.mid(i,1);
}
qDebug()<<"phone num is:"<<qStrTemp2;
//1100:固定,sHex:手机号码的长度,不算+号,十六进制表示,91:发送到手机为91,发送到小灵通为81
qStrTemp2="0891683108200105F01100"+sHex+"9168" +qStrTemp2+"000800";
m_SendCont=qStrTemp2;
return qStrTemp2.length();
}
int QtSMS::smsString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
for(int i=0; i<nSrcLength; i+=2)
{
// 输出高4位
if(*pSrc>='0' && *pSrc<='9')
{
*pDst = (*pSrc - '0') << 4;
}
else
{
*pDst = (*pSrc - 'A' + 10) << 4;
}
pSrc++;
// 输出低4位
if(*pSrc>='0' && *pSrc<='9')
{
*pDst |= *pSrc - '0';
}
else
{
*pDst |= *pSrc - 'A' + 10;
}
pSrc++;
pDst++;
}
// 返回目标数据长度
return nSrcLength / 2;
}
QString QtSMS::smsSerializeNumbers(const char* pSrc, int nSrcLength)
{
QString qStrTemp1(pSrc);
QString qStrTemp2;
for(int i=0; i<nSrcLength; i+=2)
{
qStrTemp2 +=qStrTemp1.mid(i+1,1)+qStrTemp1.mid(i,1);
}
if(qStrTemp2[nSrcLength-1] =='F') //字符F去掉
{
qStrTemp2.chop(1);
}
return qStrTemp2;
}
SmsInfo QtSMS::DecodePdu(char * pStrSms)
{
unsigned char tmp; // 内部用的临时字节变量
smsString2Bytes(pStrSms, &tmp, 2); // 取长度
tmp = (tmp - 1) * 2; // SMSC号码串长度(中心号码)
pStrSms+=4+tmp+2; //指针后移
// 包含回复地址,取回复地址信息
smsString2Bytes(pStrSms, &tmp, 2); // 取长度
if(tmp & 1) tmp += 1; // 调整奇偶性
pStrSms += 4; // 指针后移
SmsInfo smsInfo;
smsInfo.strPhoneNum=smsSerializeNumbers(pStrSms, tmp); // 取TP-RA号码(对方号码)
pStrSms += tmp+4; // 指针后移
smsInfo.strTime=convertTime(smsSerializeNumbers(pStrSms, 14)); // 服务时间戳字符串(短信时间)
pStrSms += 16; // 指针后移
smsInfo.strSms=unicodeToString(pStrSms);
qDebug()<<smsInfo.strPhoneNum<<" "<<smsInfo.strTime<<" "<< smsInfo.strSms<<endl;
return smsInfo;
}
QString QtSMS::convertTime(QString qStrTime)
{
QString qStrTemp="20"; //时间格式2012-07-12 18:56:04
qStrTemp += qStrTime.mid(0,2)+"-"+qStrTime.mid(2,2)+"-"+qStrTime.mid(4,2)+" "+qStrTime.mid(6,2)+":"+qStrTime.mid(8,2)+":"+qStrTime.mid(10,2);
return qStrTemp;
}
#include "codeconvertor.h"
#include <QDebug>
CodeConvertor::CodeConvertor()
{
}
QString CodeConvertor::tuf8ToUnicode(const QString &in)
{
QString outstr;
QByteArray byteArr = in.toLatin1();
for (int i = 0;i < byteArr.length();) {
if ((byteArr[i] & 0x80) == 0x00)//是英文
{//0x0xxxxxx 只占一个字节
if (!(byteArr[i] & 0xf0)) {
outstr += "0";
}
outstr+="00";
outstr += QString::number((uint)byteArr[i] & 0x000000ff,16);
++i;
}
else
{
if ((byteArr[i] & 0xe0) == 0xc0)
{//0x110xxxxx 0x10xxxxxx 占两个字节
char t1 = byteArr[i] & 0x1f;//第一个字节的后五位 1
char t2 = byteArr[++i] & 0x3f;//第而个字节的后六位 2
char t3 = t2 | ((t1 & 0x03) << 6);//2
char t4 = (t1 >> 2) & 07;//1
if (!(t4 & 0xf0)) {
outstr += "0";
}
outstr += QString::number((uint)t4 & 0x000000ff,16);
if (!(t3 & 0xf0)) {
outstr += "0";
}
outstr += QString::number((uint)t3 & 0x000000ff,16);
++i;
}
else
{
if ((byteArr[i] & 0xf0) == 0xe0)
{//占3个字节
char t1 = byteArr[i] & 0x0f;//1
char t2 = byteArr[++i] & 0x3f;//2
char t3 = byteArr[++i] & 0x3f;//3
char t4 = t3 | ((t2 & 0x03) << 6);//3
char t5 = ((t2 >> 2) & 0x0f) | ((t1 << 4) & 0xf0) ;//2
if (!(t5 & 0xf0)) {
outstr += "0";
}
outstr += QString::number((uint)t5 & 0x000000ff,16);
if (!(t4 & 0xf0)) {
outstr += "0";
}
outstr += QString::number((uint)t4 & 0x000000ff,16);
++i;
}
}
}
}
return outstr;
}
std::string CodeConvertor::_tuf8ToUnicode(const std::string &in)
{
std::string outstr;
char buf[3];
for (int i = 0;i < in.length();) {
if ((in[i] & 0x80) == 0x00)
{//0x0xxxxxx 只占一个字节
CodeConvertor::charTo2Hex(in[i],buf);
outstr += buf;
++i;
}
else
{
if ((in[i] & 0xe0) == 0xc0)
{//0x110xxxxx 0x10xxxxxx 占两个字节
char t1 = in[i] & 0x1f;//第一个字节的后五位 1
char t2 = in[++i] & 0x3f;//第而个字节的后六位 2
char t3 = t2 | ((t1 & 0x03) << 6);//2
char t4 = (t1 >> 2) & 07;//1
CodeConvertor::charTo2Hex(t4,buf);
outstr += buf;
CodeConvertor::charTo2Hex(t3,buf);
outstr += buf;
++i;
}
else
{
if ((in[i] & 0xf0) == 0xe0)
{//占3个字节
char t1 = in[i] & 0x0f;//1
char t2 = in[++i] & 0x3f;//2
char t3 = in[++i] & 0x3f;//3
char t4 = t3 | ((t2 & 0x03) << 6);//3
char t5 = ((t2 >> 2) & 0x0f) | ((t1 << 4) & 0xf0) ;//2
CodeConvertor::charTo2Hex(t5,buf);
outstr += buf;
CodeConvertor::charTo2Hex(t4,buf);
outstr += buf;
++i;
}
}
}
}
return outstr;
}
void CodeConvertor::charTo2Hex(char in, char *out)
{
char l = in & 0x0f;
char h = (in & 0xf0) >> 4;
int hh = h % 16;
if (hh < 10) {
out[0] = '0' + hh;
} else {
out[0] = hh - 10 + 'A';
}
int ll = l % 16;
if (ll < 10) {
out[1] = '0' + ll;
} else {
out[1] = ll - 10 + 'A';
}
out[2] = '\0';
}
#ifndef CODECONVERTOR_H
#define CODECONVERTOR_H
#include <QString>
#include <string>
class CodeConvertor
{
public:
static QString tuf8ToUnicode(const QString &in);
static std::string _tuf8ToUnicode(const std::string &in);
static void charTo2Hex(char in,char *out);
private:
CodeConvertor();
};
#endif // CODECONVERTOR_H
#ifndef QTSMS_H
#define QTSMS_H
#include <QMainWindow>
#include "qextserialport.h"
#include <QDebug>
#include <QTextCodec>
#include <iostream>
#include <list>
using namespace std;
namespace Ui {
class QtSMS;
}
struct SmsInfo{
QString strPhoneNum;
QString strTime;
QString strSms;
};
class QtSMS : public QMainWindow
{
Q_OBJECT
public:
explicit QtSMS(QWidget *parent = 0);
~QtSMS();
void sendAT(int iOrder); //发送指令
int convertMesg(QString); //转换字符串信息变成PDU格式
int convertPhone(QString); //电话号码两两颠倒
QString convertTime(QString); //短信时间转换成常用时间格式
SmsInfo GetSms(); //获取短信
void SendSms(QString qStrSend,QString qStrNum); //发送短信
void DelAllSms(); //删除短信
QString stringToUnicode(QString str); //字符串转为unicode
QString unicodeToString(QString str); //unicode转为字符串
SmsInfo DecodePdu(char *); //解码接收短信内容
int smsString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength); //// 可打印字符串转换为字节数据
QString smsSerializeNumbers(const char* pSrc, int nSrcLength); //// 两两颠倒的字符串转换为正常顺序的字符串
int OpenCom(const char* pStrPort,int iBaudRate); //打开串口
int openSerialPort();
private:
int my_fd;
QextSerialPort *myCom; //第三方串口
void chineseStrTo16Str(const QString& srcStr, QString& destStr);
int Utf82Unicode(char* out, int outsize , char* in,int insize);
private:
Ui::QtSMS *ui;
QString m_qStrInfo; //串口接收的信息
QString m_SendCont; //整理好的短信发送内容
list<QString> m_SmsList; //收集短信
int iDelNum; // 删除短信条数
int iUsedSms; //用过的短信条数
int iTotalSms; //总的短信条数
bool isAllDel; //是否全删除标志
private slots:
// void slotReadMesg();
void onReadyRead();
void onDsrChanged(bool status);
};
#endif // QTSMS_H
有些代码是我从网上找的,但是都修改了一下,然后调试通过了。可以发送英文字符+中文汉字,比如1111aaa爱你!!这样子的,因为发送的编码必须是unicode所以必须转换,linux+qt使用的都是utf-8 所以必须转换为unicode才能发送成功。
发送中文短信,其实只有几步,使用串口发送AT+cmGF=0 回车,at+cmgs=发送的长度 然后就是pnone+unicode的短信内容了。代码如下:
#include <QtGui/QApplication>
#include "QtSMS.h"
#include <iconv.h>
#include "codeconvertor.h"
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// QTextCodec::setCodecForTr(QTextCodec::codecForName("unicode"));
QtSMS w;
w.OpenCom("/dev/ttySAC1",115200);
w.SendSms("123abc,,//?????/?//】【[]{}[jj』『』『、、|||、、||\\\"、、、////```````098jjsk爱!","13062669576");
// w.show();
// qDebug() << CodeConvertor::_tuf8ToUnicode("工作愉快!").data();
// qDebug()<<"\"5DE54F5C61095FEBFF01\"";
return a.exec();
}
#include "QtSMS.h"
#include "ui_QtSMS.h"
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <termio.h>
#include "codeconvertor.h"
QtSMS::QtSMS(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::QtSMS)
{
ui->setupUi(this);
// OpenCom("ttySAC1",115200);
// SendSms("您好!","13062669576");
iDelNum=1;
isAllDel = false;
iTotalSms=50;
// DelAllSms();
// sendAT(7);
// qDebug()<<unicodeToString("0500034902015C0A656C768452A8611F57305E265BA26237FF0C52A8611F57305E2654C1724C8FFD6C42201C65F65C1A3001597D73A9300163A27D22201D30025F53524D5E106237603B4F59989D4E3A0039002E003400315143FF0C51764E2D672C6708901A75284F59989D4E3A0039002E003400315143300256DE590D0031003100314E8689E34F59989D");
}
QtSMS::~QtSMS()
{
myCom->close();
delete ui;
}
int QtSMS::openSerialPort()
{
int fd = -1;
fd = ::open("/dev/ttySAC1", O_RDWR|O_NONBLOCK);
if (fd < 0) {
return -1;
}
termios serialAttr;
memset(&serialAttr, 0, sizeof serialAttr);
cfsetispeed(&serialAttr,B115200);
cfsetospeed(&serialAttr,B115200);
serialAttr.c_cflag &= ~CSIZE;
serialAttr.c_cflag |= CS8;
serialAttr.c_iflag = IGNPAR;
if (tcsetattr(fd, TCSANOW, &serialAttr) != 0) {
return -1;
}
return fd;
}
int QtSMS::OpenCom(const char* pStrPort,int iBaudRate)
{
#if 1
this->myCom = new QextSerialPort(pStrPort, QextSerialPort::EventDriven);
switch(iBaudRate) {
case 9600:
myCom->setBaudRate(BAUD9600);
break;
case 115200:
myCom->setBaudRate(BAUD115200);
break;
default:
myCom->setBaudRate(BAUD9600);
break;
}
myCom->setFlowControl(FLOW_OFF);
myCom->setParity(PAR_NONE);
myCom->setDataBits(DATA_8);
myCom->setStopBits(STOP_1);
if (myCom->open(QIODevice::ReadWrite) == true) {
connect(myCom, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(myCom, SIGNAL(dsrChanged(bool)), this, SLOT(onDsrChanged(bool)));
if (!(myCom->lineStatus() & LS_DSR))
qDebug() << "warning: device is not turned on";
qDebug() << "listening for data on" << myCom->portName();
}
else {
qDebug() << "device failed to open:" << myCom->errorString();
}
// connect(myCom,SIGNAL(readyRead()),this,SLOT(slotReadMesg()));
#else
my_fd=this->openSerialPort();
#endif
return 1;
}
void QtSMS::onReadyRead()
{
QByteArray bytes;
int a = myCom->bytesAvailable();
bytes.resize(a);
myCom->read(bytes.data(), bytes.size());
qDebug() << "bytes read:" << bytes.size();
qDebug() << "bytes:" << bytes;
}
void QtSMS::onDsrChanged(bool status)
{
if (status)
qDebug() << "device was turned on";
else
qDebug() << "device was turned off";
}
void QtSMS::SendSms(QString qStrSend,QString qStrNum)
{
sendAT(1);
convertPhone(qStrNum);
convertMesg(qStrSend);
sleep(2);
sendAT(2);
sleep(2);
sendAT(3);
sleep(3);
}
void QtSMS::DelAllSms()
{
isAllDel = true;
iDelNum=1;
sendAT(6);
}
SmsInfo QtSMS::GetSms()
{
while(m_SmsList.size()!=0)
{
QString qStrSms = m_SmsList.back(); //读取最后一个
int iSms;
char *ptr = (char*)qStrSms.toStdString().c_str();
sscanf(ptr,"%d",&iSms);
cout<<"iSms ===="<<iSms<<endl;
ptr=strstr(ptr,",");
ptr++;
m_SmsList.pop_back(); //去掉最后一个
DecodePdu(ptr);
// iDelNum = iSms;
// sendAT(6);
// isAllDel = false;
}
SmsInfo sms;
return sms;
}
void QtSMS::sendAT(int iOrder)
{
QString qStrCmd;
switch(iOrder)
{
case 1:
{
//设置短信格式
qStrCmd= "AT+CMGF=0\r";
myCom->write(qStrCmd.toAscii());
//#endif
break;
}
case 2:
{
//发送短信长度指令
int iLength=strlen(m_SendCont.toStdString().c_str())/2;
qDebug()<<"sms======len:"<<iLength;
qStrCmd=QString("%1%2\r").arg("AT+CMGS=").arg(iLength-9);
myCom->write(qStrCmd.toAscii());
break;
}
case 3:
{
//发送短信内容指令
// myCom->write("0011000D91683166051461F70008011600680065006C006C006F00204F60597D0021000D000A\x01a");
qDebug()<<"sms======cont:"<<m_SendCont;
myCom->write((m_SendCont+"\x01a").toStdString().c_str());
break;
}
case 4:
{
//短信容量查询指令
qStrCmd = "AT+CPMS?\r";
myCom->write(qStrCmd.toAscii());
break;
}
case 5:
{
//设置新短信通知指令
qStrCmd="AT+CNMI=2,1\r";
myCom->write(qStrCmd.toAscii());
break;
}
case 6:
{
//短信删除指令
qStrCmd= tr("AT+CMGD=%1\r").arg(iDelNum);
qDebug()<<qStrCmd;
myCom->write(qStrCmd.toAscii());
break;
}
case 7:
{
//读取未读短信
qStrCmd= "AT+CMGL=0\r";
qDebug()<<qStrCmd;
myCom->write(qStrCmd.toAscii());
break;
}
default:
break;
}
}
QString QtSMS::stringToUnicode(QString str)
{
// 这里传来的字符串一定要加tr,main函数里可以加 QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
// 例如:str=tr("你好");
const QChar *q;
QChar qtmp;
QString str0, strout;
int num;
q=str.unicode();
int len=str.count();
for(int i=0;i<len;i++)
{
qtmp =(QChar)*q++;
num= qtmp.unicode();
// if(num<255)
// strout+="00"; //英文或数字前加"00"
str0=str0.setNum(num,16);//变成十六进制数
strout+=str0;
}
return strout;
}
QString QtSMS::unicodeToString(QString str)
{
//例如 str="4F60597D";
// qDebug()<<str;
int temp[400];
QChar qchar[100];
QString strOut;
bool ok;
int count=str.count();
int len=count/4;
for(int i=0;i<count;i+=4)
{
temp[i]=str.mid(i,4).toInt(&ok,16);//每四位转化为16进制整型
qchar[i/4]=temp[i];
QString str0(qchar, len);
strOut=str0;
}
qDebug()<<"wyz=========smsInfo:"<<strOut<<endl;
return strOut;
}
int QtSMS::convertMesg(QString qStrMesg)
{
qStrMesg=CodeConvertor::tuf8ToUnicode(qStrMesg);
qDebug()<<"unicode is:"<<qStrMesg;
int i=qStrMesg.length()/2; //内容长度
QString sHex;
sHex.setNum(i,16);
if(sHex.length()==1)
{
sHex="0"+sHex;
}
QString qStrMesgs;
qStrMesgs = QString("%1%2").arg(sHex).arg(qStrMesg);
m_SendCont+=qStrMesgs;
return qStrMesgs.length();
}
int QtSMS::convertPhone(QString qStrPhone)
{
int i=qStrPhone.length()+2; //长度包括86
QString sHex;
sHex.setNum(i,16); //转成十六进制
if(sHex.length()==1)
{
sHex="0"+sHex;
}
if(qStrPhone.length()%2 !=0) //为奇数位后面加F
{
qStrPhone+="F";
}
qDebug()<<"phone num is:"<<qStrPhone;
//奇数位偶数位交换
QString qStrTemp2;
for(int i=0; i<qStrPhone.length(); i+=2)
{
qStrTemp2 +=qStrPhone.mid(i+1,1)+qStrPhone.mid(i,1);
}
qDebug()<<"phone num is:"<<qStrTemp2;
//1100:固定,sHex:手机号码的长度,不算+号,十六进制表示,91:发送到手机为91,发送到小灵通为81
qStrTemp2="0891683108200105F01100"+sHex+"9168" +qStrTemp2+"000800";
m_SendCont=qStrTemp2;
return qStrTemp2.length();
}
int QtSMS::smsString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
for(int i=0; i<nSrcLength; i+=2)
{
// 输出高4位
if(*pSrc>='0' && *pSrc<='9')
{
*pDst = (*pSrc - '0') << 4;
}
else
{
*pDst = (*pSrc - 'A' + 10) << 4;
}
pSrc++;
// 输出低4位
if(*pSrc>='0' && *pSrc<='9')
{
*pDst |= *pSrc - '0';
}
else
{
*pDst |= *pSrc - 'A' + 10;
}
pSrc++;
pDst++;
}
// 返回目标数据长度
return nSrcLength / 2;
}
QString QtSMS::smsSerializeNumbers(const char* pSrc, int nSrcLength)
{
QString qStrTemp1(pSrc);
QString qStrTemp2;
for(int i=0; i<nSrcLength; i+=2)
{
qStrTemp2 +=qStrTemp1.mid(i+1,1)+qStrTemp1.mid(i,1);
}
if(qStrTemp2[nSrcLength-1] =='F') //字符F去掉
{
qStrTemp2.chop(1);
}
return qStrTemp2;
}
SmsInfo QtSMS::DecodePdu(char * pStrSms)
{
unsigned char tmp; // 内部用的临时字节变量
smsString2Bytes(pStrSms, &tmp, 2); // 取长度
tmp = (tmp - 1) * 2; // SMSC号码串长度(中心号码)
pStrSms+=4+tmp+2; //指针后移
// 包含回复地址,取回复地址信息
smsString2Bytes(pStrSms, &tmp, 2); // 取长度
if(tmp & 1) tmp += 1; // 调整奇偶性
pStrSms += 4; // 指针后移
SmsInfo smsInfo;
smsInfo.strPhoneNum=smsSerializeNumbers(pStrSms, tmp); // 取TP-RA号码(对方号码)
pStrSms += tmp+4; // 指针后移
smsInfo.strTime=convertTime(smsSerializeNumbers(pStrSms, 14)); // 服务时间戳字符串(短信时间)
pStrSms += 16; // 指针后移
smsInfo.strSms=unicodeToString(pStrSms);
qDebug()<<smsInfo.strPhoneNum<<" "<<smsInfo.strTime<<" "<< smsInfo.strSms<<endl;
return smsInfo;
}
QString QtSMS::convertTime(QString qStrTime)
{
QString qStrTemp="20"; //时间格式2012-07-12 18:56:04
qStrTemp += qStrTime.mid(0,2)+"-"+qStrTime.mid(2,2)+"-"+qStrTime.mid(4,2)+" "+qStrTime.mid(6,2)+":"+qStrTime.mid(8,2)+":"+qStrTime.mid(10,2);
return qStrTemp;
}
#include "codeconvertor.h"
#include <QDebug>
CodeConvertor::CodeConvertor()
{
}
QString CodeConvertor::tuf8ToUnicode(const QString &in)
{
QString outstr;
QByteArray byteArr = in.toLatin1();
for (int i = 0;i < byteArr.length();) {
if ((byteArr[i] & 0x80) == 0x00)//是英文
{//0x0xxxxxx 只占一个字节
if (!(byteArr[i] & 0xf0)) {
outstr += "0";
}
outstr+="00";
outstr += QString::number((uint)byteArr[i] & 0x000000ff,16);
++i;
}
else
{
if ((byteArr[i] & 0xe0) == 0xc0)
{//0x110xxxxx 0x10xxxxxx 占两个字节
char t1 = byteArr[i] & 0x1f;//第一个字节的后五位 1
char t2 = byteArr[++i] & 0x3f;//第而个字节的后六位 2
char t3 = t2 | ((t1 & 0x03) << 6);//2
char t4 = (t1 >> 2) & 07;//1
if (!(t4 & 0xf0)) {
outstr += "0";
}
outstr += QString::number((uint)t4 & 0x000000ff,16);
if (!(t3 & 0xf0)) {
outstr += "0";
}
outstr += QString::number((uint)t3 & 0x000000ff,16);
++i;
}
else
{
if ((byteArr[i] & 0xf0) == 0xe0)
{//占3个字节
char t1 = byteArr[i] & 0x0f;//1
char t2 = byteArr[++i] & 0x3f;//2
char t3 = byteArr[++i] & 0x3f;//3
char t4 = t3 | ((t2 & 0x03) << 6);//3
char t5 = ((t2 >> 2) & 0x0f) | ((t1 << 4) & 0xf0) ;//2
if (!(t5 & 0xf0)) {
outstr += "0";
}
outstr += QString::number((uint)t5 & 0x000000ff,16);
if (!(t4 & 0xf0)) {
outstr += "0";
}
outstr += QString::number((uint)t4 & 0x000000ff,16);
++i;
}
}
}
}
return outstr;
}
std::string CodeConvertor::_tuf8ToUnicode(const std::string &in)
{
std::string outstr;
char buf[3];
for (int i = 0;i < in.length();) {
if ((in[i] & 0x80) == 0x00)
{//0x0xxxxxx 只占一个字节
CodeConvertor::charTo2Hex(in[i],buf);
outstr += buf;
++i;
}
else
{
if ((in[i] & 0xe0) == 0xc0)
{//0x110xxxxx 0x10xxxxxx 占两个字节
char t1 = in[i] & 0x1f;//第一个字节的后五位 1
char t2 = in[++i] & 0x3f;//第而个字节的后六位 2
char t3 = t2 | ((t1 & 0x03) << 6);//2
char t4 = (t1 >> 2) & 07;//1
CodeConvertor::charTo2Hex(t4,buf);
outstr += buf;
CodeConvertor::charTo2Hex(t3,buf);
outstr += buf;
++i;
}
else
{
if ((in[i] & 0xf0) == 0xe0)
{//占3个字节
char t1 = in[i] & 0x0f;//1
char t2 = in[++i] & 0x3f;//2
char t3 = in[++i] & 0x3f;//3
char t4 = t3 | ((t2 & 0x03) << 6);//3
char t5 = ((t2 >> 2) & 0x0f) | ((t1 << 4) & 0xf0) ;//2
CodeConvertor::charTo2Hex(t5,buf);
outstr += buf;
CodeConvertor::charTo2Hex(t4,buf);
outstr += buf;
++i;
}
}
}
}
return outstr;
}
void CodeConvertor::charTo2Hex(char in, char *out)
{
char l = in & 0x0f;
char h = (in & 0xf0) >> 4;
int hh = h % 16;
if (hh < 10) {
out[0] = '0' + hh;
} else {
out[0] = hh - 10 + 'A';
}
int ll = l % 16;
if (ll < 10) {
out[1] = '0' + ll;
} else {
out[1] = ll - 10 + 'A';
}
out[2] = '\0';
}
#ifndef CODECONVERTOR_H
#define CODECONVERTOR_H
#include <QString>
#include <string>
class CodeConvertor
{
public:
static QString tuf8ToUnicode(const QString &in);
static std::string _tuf8ToUnicode(const std::string &in);
static void charTo2Hex(char in,char *out);
private:
CodeConvertor();
};
#endif // CODECONVERTOR_H
#ifndef QTSMS_H
#define QTSMS_H
#include <QMainWindow>
#include "qextserialport.h"
#include <QDebug>
#include <QTextCodec>
#include <iostream>
#include <list>
using namespace std;
namespace Ui {
class QtSMS;
}
struct SmsInfo{
QString strPhoneNum;
QString strTime;
QString strSms;
};
class QtSMS : public QMainWindow
{
Q_OBJECT
public:
explicit QtSMS(QWidget *parent = 0);
~QtSMS();
void sendAT(int iOrder); //发送指令
int convertMesg(QString); //转换字符串信息变成PDU格式
int convertPhone(QString); //电话号码两两颠倒
QString convertTime(QString); //短信时间转换成常用时间格式
SmsInfo GetSms(); //获取短信
void SendSms(QString qStrSend,QString qStrNum); //发送短信
void DelAllSms(); //删除短信
QString stringToUnicode(QString str); //字符串转为unicode
QString unicodeToString(QString str); //unicode转为字符串
SmsInfo DecodePdu(char *); //解码接收短信内容
int smsString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength); //// 可打印字符串转换为字节数据
QString smsSerializeNumbers(const char* pSrc, int nSrcLength); //// 两两颠倒的字符串转换为正常顺序的字符串
int OpenCom(const char* pStrPort,int iBaudRate); //打开串口
int openSerialPort();
private:
int my_fd;
QextSerialPort *myCom; //第三方串口
void chineseStrTo16Str(const QString& srcStr, QString& destStr);
int Utf82Unicode(char* out, int outsize , char* in,int insize);
private:
Ui::QtSMS *ui;
QString m_qStrInfo; //串口接收的信息
QString m_SendCont; //整理好的短信发送内容
list<QString> m_SmsList; //收集短信
int iDelNum; // 删除短信条数
int iUsedSms; //用过的短信条数
int iTotalSms; //总的短信条数
bool isAllDel; //是否全删除标志
private slots:
// void slotReadMesg();
void onReadyRead();
void onDsrChanged(bool status);
};
#endif // QTSMS_H
有些代码是我从网上找的,但是都修改了一下,然后调试通过了。可以发送英文字符+中文汉字,比如1111aaa爱你!!这样子的,因为发送的编码必须是unicode所以必须转换,linux+qt使用的都是utf-8 所以必须转换为unicode才能发送成功。
相关文章推荐
- 通过GPRS模块用Text模式发送中文短信的问题
- OK6410 解决Qt移植后触摸屏不能使用、鼠标无法移动问题
- 嵌入式成长轨迹34 【嵌入式学习阶段】【ARM环境调试】【QT 移植环境及简单程序示例】---补充《ok6410 Qt移植百科全书》
- 用python for s60发送中文短信
- 编译OK6410-A 的qt-everywhere-opensource-src-4.7.1出错 解决办法
- Android发送接收短信的代码示例(本人验证OK)
- Linux-C实现GPRS模块发送短信 作者:冯建
- Linux-C实现GPRS模块发送短信
- qt在linux与ok6410上的安装移植(2)——tslib和开发板上qt的编译
- 最新andriod发送中文短信方法
- AT指令发送PDU中文短信——使用串口…
- 在OK6410上运行QT程序找不到libQtGui.so.4的解决
- OK6410之Qt移植全过程记录
- GPRS模块发送短信
- AT指令发送PDU中文短信——使用串口…
- 常用GPRS模块短信发送例程(转载)
- 摄像头在liunx上的QT显示和OK6410 ARM开发板上的使用
- 【zz】ok6410上 使用DirecetFB支持Qt4.7.0
- TC35发送中文短信调试笔记
- 发送中文短信