tc351i  发送短信息 代码

通过串口,内置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 这三者间的关系!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值