通过串口,内置utf-8转码unsicode函数。 只要串口fd,短信中心,要发送的号码,短信内容就可以发送了。
程序有点乱不过目前没问题!
/*
* gsm.cpp
*
* Created on: 2012-4-24
* Author: xy
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>
static int UTF8toUnicode(unsigned char *ch, unsigned short int * const unicode)
{
unsigned char *p = NULL;
int e = 0, n = 0;
if ((p = ch) && unicode) {
if (*p >= 0xe0) {
/*3:<11100000>*/
e = (p[0] & 0x0f) << 12;
e |= (p[1] & 0x3f) << 6;
e |= (p[2] & 0x3f);
n = 3;
} else if (*p >= 0xc0) {
/*2:<11000000>*/
e = (p[0] & 0x1f) << 6;
e |= (p[1] & 0x3f);
n = 2;
} else {
e = p[0];
n = 1;
}
*unicode = e;
}
return n;
}
static int u2g(char *u_sms,unsigned short int *g_sms) { //把utf-8的字符串变成gsm用的unsined 字符串 return 转换后的unicode的长度
int tmp, tmp1=0;
printf("ok\n");
char *p=u_sms;
int tmp3=strlen(p);
unsigned short int *p1=(unsigned short int *)g_sms;
int tmp4=0;//转换的utf-8字符的数量,一个unicode字符占两个字节!!(本文中是这样),所以unicode所占的字节数就是tmp4的两倍
while(1) {
tmp4++;
tmp=0;
tmp=UTF8toUnicode((unsigned char *)p,p1);
printf("tmp=%d,*p=%#04X\n",tmp,*p1);
tmp1=tmp1+tmp; //tmp1
p=p+tmp;
p1=p1+1;
if(tmp1>=tmp3)
break;
}
printf("debug!!:%d\n",p1-g_sms);
#if 0
/****************/
int d1;
unsigned char *d2=(unsigned char *)g_sms;
for(d1=0; d1<tmp4*2; d1++)
printf("%02x",*(d2+d1));
printf("\n");
/**************/
printf("size unicode=%d\n",tmp4);
unsigned char *p3=(unsigned char *)g_sms;
unsigned char tmp5;
for(tmp=0; tmp<tmp4; tmp++){
tmp5=*(p3+2*tmp);
*(p3+2*tmp)=*(p3+2*tmp+1);
*(p3+2*tmp+1)=tmp5;
}
#endif
return tmp4;
}
int init_gsm(int fd,char *p)
{
char test_buf[] = "AT\r\n";
int nsend,nrecv;
char abc[100];
memset(abc, 0, 100);
nsend = write(fd, test_buf, strlen(test_buf));
if(nsend!=strlen(test_buf)){
perror("init_gsm write error\n");
return -1;
}
int tmp;
for (tmp = 0; tmp < 3; tmp++) {
memset(abc, 0, sizeof(abc));
nrecv = read(fd, abc, 100);
if ((nrecv == 9) && (memcmp(abc, "AT", 2) == 0)) {
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
break;
}
if (tmp == 2)
return -1; //程序没有收到AT\n OK说明线没连好,或者gsm没工作
}
char test_buf1[] = "AT+CSCA?\r\n"; //得到短信中心
nsend = write(fd, test_buf1, strlen(test_buf1));
if(nsend!=strlen(test_buf)){
perror("init_gsm write error\n");
return -1;
}
for (tmp = 0; tmp < 3; tmp++) {
memset(abc, 0, sizeof(abc));
nrecv = read(fd, abc, 100);
if ((nrecv == 9) && (memcmp(abc, "AT", 2) == 0)) {
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
break;
}
if (tmp == 2)
return -1; //程序没有收到AT\n OK说明线没连好,或者gsm没工作
}
}
int send_sms(int fd, char *tel_num, char *sms_cen, char *sms) {
//短信中心处理可能会出错
//要发送信息的号码和短信中心号码都必须是11位
//char d1[]="客厅报警";
unsigned short int d2[100];//处理成unicode码后存放在此处
memset(d2, 0, sizeof(d2));
int d3=u2g(sms/*d1*/,d2); //处理函数,返回unicode的个数,一个unicode占两个字节
char d5[10]={0}; //unicode 码长度16进制值 的字符地串 以后会 用到
sprintf(d5, "%02X",d3*2);
#if 1 //打印出处理后的unicode码
char d7[1000]={0}; //一个unicode占四个字节,所以1000可以放250个字
char *d8=d7;
printf("size unicode str :d5:%s\n",d5);
int d4;
for(d4=0; d4<d3; d4++){
printf("%04X",d2[d4]);
sprintf(d8,"%04X",d2[d4]);
d8=d8+4;
}
printf("\n");
#endif
char str1[] = "AT+CMGF=0\r\n"; //设置gsm发短信模式
char str2[20] = "AT+CMGS=";// 26\r\n";
char str3[200];
char str4 = 0x1a;
memset(str3, 0,sizeof(str3));
char abc[100];
memset(abc, 0, 100);
int nsend, nrecv;
char this_cen[30]={0}; //处理信息中心,使之变成能发送的格式
memcpy(this_cen, sms_cen, strlen(sms_cen));
if(strlen(this_cen)%2==1)//是奇数,要加"F"
strcat(this_cen, "F");
char tmp;
int n;
for(n=0; n<strlen(this_cen)/2; n++){ //把奇数,偶数换换
tmp=this_cen[2*n];
this_cen[2*n]=this_cen[2*n+1];
this_cen[2*n+1]=tmp;
}
char this_num[30] = { 0 }; //处理信息中心,使之变成能发送的格式
memcpy(this_num, tel_num, strlen(tel_num));
if (strlen(this_num) % 2 == 1) //是奇数,要加"F"
strcat(this_num, "F");
for (n = 0; n < strlen(this_num) / 2; n++) { //把奇数,偶数换换
tmp = this_num[2 * n];
this_num[2 * n] = this_num[2 * n + 1];
this_num[2 * n + 1] = tmp;
}
char sms_buf[300]={0};
memcpy(sms_buf, "089168", strlen("089168")); //加前缀
strcat(sms_buf, this_cen ); //加信息中心
strcat(sms_buf, "11000B81");//要发送的手机号码前缀 4
strcat(sms_buf, this_num);//要发送的手机号码 6
strcat(sms_buf, "0008A7");// 下面长12也就是十六进制的c 3
strcat(sms_buf, d5); //把短信unicode码的长度加进去 1
strncat(sms_buf, d7, d3*4); //把短信内容的unicode码加进去 d3*4
char d6[20]={0};
sprintf(d6,"%d",4+6+3+1+d3*2);//AT+CMGS= 后面的值
strcat(str2,d6);
strcat(str2,"\r\n");
printf("debug:send:%s\n",sms_buf);
nsend = write(fd, str1, strlen(str1));
printf("1nsend=%d\n", nsend);
usleep(200 * 1000);
memset(abc, 0, 100);
nrecv = read(fd, abc, 100);
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
nsend = write(fd, str2, strlen(str2));
printf("2nsend=%d\n", nsend);
usleep(200 * 1000);
memset(abc, 0, 100);
nrecv = read(fd, abc, 100);
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
nsend = write(fd, sms_buf, strlen(sms_buf));
printf("3nsend=%d\n", nsend);
memset(abc, 0, 100);
usleep(200 * 1000);
memset(abc, 0, 100);
nrecv = read(fd, abc, 100);
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
nsend = write(fd, &str4, 1);
printf("4nsend=%d\n", nsend);
int ttt;
for (ttt=0; ttt<2; ttt++) {
sleep(1);
memset(abc, 0, 100);
nrecv = read(fd, abc, 100);
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
}
return 0;
#if 0
char str1[] = "AT+CMGF=0\r\n"; //设置gsm发短信模式
char str2[] = "AT+CMGS=26\r\n";
char str3[200];
char str4 = 0x1a;
memset(str3, 0,sizeof(str3));
char abc[100];
memset(abc, 0, 100);
int nsend, nrecv;
char this_cen[30]={0};//处理信息中心,使之变成能发送的格式
memcpy(this_cen, sms_cen, strlen(sms_cen));
if(strlen(this_cen)%2==1)//是奇数,要加"F"
strcat(this_cen, "F");
char tmp;
int n;
for(n=0; n<strlen(this_cen)/2; n++){ //把奇数,偶数换换
tmp=this_cen[2*n];
this_cen[2*n]=this_cen[2*n+1];
this_cen[2*n+1]=tmp;
}
char this_num[30] = { 0 }; //处理信息中心,使之变成能发送的格式
memcpy(this_num, tel_num, strlen(tel_num));
if (strlen(this_num) % 2 == 1) //是奇数,要加"F"
strcat(this_num, "F");
for (n = 0; n < strlen(this_num) / 2; n++) { //把奇数,偶数换换
tmp = this_num[2 * n];
this_num[2 * n] = this_num[2 * n + 1];
this_num[2 * n + 1] = tmp;
}
char sms_buf[300]={0};
memcpy(sms_buf, "089168", strlen("089168")); //加前缀
strcat(sms_buf, this_cen ); //加信息中心
strcat(sms_buf, "11000B81");//要发送的手机号码前缀 4
strcat(sms_buf, this_num);//要发送的手机号码 6
strcat(sms_buf, "0008A70C");// 下面长12也就是十六进制的c 4
char bb1[]="901A90530031670962A58B66";//通道1有报警 12
char bb2[]="901A90530032670962A58B66";//通道2有报警
char bb3[]="901A90530033670962A58B66";//通道3有报警
char bb4[]="901A90530034670962A58B66";//通道4有报警
strcat(sms_buf, bb4);
printf("debug:send:%s\n",sms_buf);
nsend = write(fd, str1, strlen(str1));
printf("1nsend=%d\n", nsend);
usleep(200 * 1000);
memset(abc, 0, 100);
nrecv = read(fd, abc, 100);
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
nsend = write(fd, str2, strlen(str2));
printf("2nsend=%d\n", nsend);
usleep(200 * 1000);
memset(abc, 0, 100);
nrecv = read(fd, abc, 100);
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
nsend = write(fd, sms_buf, strlen(sms_buf));
printf("3nsend=%d\n", nsend);
memset(abc, 0, 100);
usleep(200 * 1000);
memset(abc, 0, 100);
nrecv = read(fd, abc, 100);
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
nsend = write(fd, &str4, 1);
printf("4nsend=%d\n", nsend);
int ttt;
for (ttt=0; ttt<2; ttt++) {
sleep(1);
memset(abc, 0, 100);
nrecv = read(fd, abc, 100);
printf("recv:nrecv=%d\n,str=%s\n", nrecv, abc);
}
#endif
}
extern int send_sms(int fd, char *tel_num, char *sms_cen, char *sms);
/* 参数:fd 串口,tel_num电话号码,sms_cen短信中心,m几路报警 ps:字符串一定要以\0结束!!!
* 返回:
* ps:
*短信中心处理可能会出错
*要发送信息的号码和短信中心号码都必须是11位
*/
extern int init_gsm(int fd,char *p); //并没有实现
/*fd 串口 *p返回短信中心
* 测试gsm是不是工作,短信中心等
* -1没工作或没连接 -2没连网(不能得到短信中心)
*/
调用方法:
//char num[]="1383839XXXX"; //发送的号码
char cen[]="13800371500"; //短信中心
send_sms(fd, num, cen, "客厅报警abc");
ps:写这些程序一定要注意\r\n \r \n 这三者间的关系!!