Code Segment about PDU
/* * ===================================================================================== * * Filename: gmesg.c * * ===================================================================================== */
/* 头文件开始 1.编码转换需要iconv.h 2.对消息内容特殊转换需要gmesg.h */ /*{{{*/ #include
#include
#include
#include
#include
#include
#include
#include
#include
#include "gmesg.h" #include "gport.h"
#define SLEEP3S 0 /*}}}*/ /* 头文件结束 1.编码转换需要iconv.h 2.对消息内容特殊转换需要gmesg.h */
/* * === FUNCTION ====================================================================== * Name: init_gprs_pdu * Description: 从数据库中读出默认设置的pdu数据 * ===================================================================================== */ /*{{{*/ int init_gprs_pdu ( struct gprs_pdu **gpdu,char *signal ) { sqlite3 *db = NULL; int rc,i; char *dbname = "gprsPdu.db"; char *ErrMsg = NULL; char **dbResult = NULL; char sql_select[MSIZE] = { 0 }; int nrow,ncolumn;
if ( NULL == signal ) { strcpy(sql_select,"select * from gprs_pdu where id=1"); } else { sprintf(sql_select,"select * from gprs_pdu where status = /'%s/'",signal); }
rc = sqlite3_open(dbname,&db); if ( SQLITE_OK != rc ) { fprintf(stderr,"Cannot open database :%s/n",sqlite3_errmsg(db)); sqlite3_close(db); return -1; }
rc = sqlite3_get_table (db,sql_select,&dbResult,&nrow,&ncolumn,&ErrMsg);
i = ncolumn + 1; /* 去掉id字段 */ (*gpdu) = (struct gprs_pdu *) malloc (sizeof(struct gprs_pdu));
memset(*gpdu,sizeof(struct gprs_pdu)); strcpy( (*gpdu)->sim_attr,dbResult[i] ); i++; strcpy( (*gpdu)->sim_center,dbResult[i] ); i++; strcpy( (*gpdu)->phone_attr,dbResult[i] ); i++; strcpy( (*gpdu)->phone,dbResult[i] ); i++; strcpy( (*gpdu)->fix,dbResult[i] ); i++; strcpy( (*gpdu)->gb2312_msg,dbResult[i] ); i++; sqlite3_free_table( dbResult ); sqlite3_close(db); return 0; } /* ----- end of function init_gprs_pdu ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: clear_gprs_pdu * Description: 清除结构体struct gprs_pdu * ===================================================================================== */ /*{{{*/ int clear_gprs_pdu ( struct gprs_pdu *gpdu ) { free(gpdu); return 0; } /* ----- end of function clear_gprs_pdu ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: code_convert * Description: 代码转换:从一种编码转为另一种编码 * ===================================================================================== */ /*{{{*/ int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen ) { iconv_t cd; /* 字符集转换描述符 */ char **pin = &inbuf; /* 被转换的编码 */ char **pout = &outbuf; /* 转换后的编码 */
/* iconv_open 申请编码转换描述符,对系统有依赖,可以使用iconv --list查看 */ cd = iconv_open(to_charset,from_charset); if ( cd == 0 ) { return -1; }
memset(outbuf,outlen);
/* iconv 实现编码转换 */ if ( iconv(cd,pin,&inlen,pout,&outlen) == -1 ) { return -1; }
/* 关闭编码转换描述符 */ iconv_close(cd);
return 0; } /* ----- end of function code_convert ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: u2g * Description: UNICODE码转为GB2312码 * ===================================================================================== */ /*{{{*/ int u2g ( char *inbuf,int outlen ) { //return code_convert("unicode","utf-8",inbuf,inlen,outbuf,outlen); /* 交叉编译后在,开发板中个人使用下面的,iconv_open对系统有依赖 */ return code_convert("UTF-16","GB2312",outlen); } /* ----- end of function u2g ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: g2u * Description: GB2312码转为UNICODE码 * ===================================================================================== */ /*{{{*/ int g2u ( char *inbuf,int outlen ) { /* 交叉编译后在,开发板中个人使用下面的,iconv_open对系统有依赖 */ /* GB2312 -> UTF-16 转换之后,前端会有多余字节 */ return code_convert("GB2312","UTF-16",outlen); /* GB2312 -> UCS2 主机正常,在开发板上使用时会段错误,断点在iconv_open处,可能缺少lib*/ //return code_convert("GB2312","UCS2",outlen); } /* ----- end of function g2u ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: bytes2string * Description: 将字节流转换成字符串,为了PDU编码作准备 * ===================================================================================== */ /*{{{*/ int bytes2string ( const unsigned char *pSrc,char *pDst,int nSrcLength ) { const char tab[] = "0123456789ABCDEF"; int i;
for ( i=0; i
{ *pDst++ = tab[*pSrc >> 4]; /* 取出高4位 */ *pDst++ = tab[*pSrc & 0x0f]; /* 取出底4位 */ pSrc++; }
/* 加上结束标志 */ *pDst = '/0';
/* 返回字符串长度,将一个字节分成两个字符,所以长度乘以2 */ return nSrcLength*2; } /* ----- end of function bytes2string ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: switch_byte1 * Description: 实现字符串中相邻的字符交换,为了PDU编码作准备,电话号码相邻数字交换。 * ===================================================================================== */ /*{{{*/ int switch_byte1 ( char *src,int len ) { int i; char tch;
for ( i=0; i
{ tch = *(src + i + 1); *(src + i + 1) = *(src + i); *(src + i) = tch; }
return len; } /* ----- end of function switch_byte1 ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: switch_byte2 * Description: 与编码有关的函数,经过iconv转换(GB2312 -> UTF-16)的编码,再经字节流转变成字符串后,字符串 * 中的十六进制字符,顺序双对换,根据系统的不同,决定该函数是否需要调用.例如: * 在宿主机上(Unbuntu)上需要调用,目标板(s3c2410)不需要. * ===================================================================================== */ /*{{{*/ int switch_byte2 ( char *src,int len ) { int i; char tch;
for ( i=0; i
{ /* 将第1个字符与第3个字符交换 */ tch = *(src + i + 2); *(src + i + 2) = *(src + i); *(src + i) = tch;
/* 将第2个字符与第4个字符交换 */ tch = *(src + i + 3); *(src + i + 3) = *(src + i + 1); *(src + i + 1) = tch;
/* eg. "1234" ---> "3412" */ } return len; } /* ----- end of function switch_byte2 ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: change_sim_attr * Description: 更改短信息中心地址长度和号码类型 * ===================================================================================== */ /*{{{*/ int change_sim_attr ( const char *src,char *des ) { printf ( "/nsrc : %s/n",src ); memset(des,strlen(des)); strcpy(des,src); return 0; } /* ----- end of function make_sim_attr ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: change_sim_center * Description: 更改短信息中心服务号码 (参数改变) * ===================================================================================== */ /*{{{*/ int change_sim_center ( const char *src,char *des ) { memset(des,strlen(des)); strcat(des,"86"); strcat(des,src); if( strlen(des)%2 != 0 ) { strcat(des,"F"); } return 0; } /* ----- end of function change_sim_center ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: change_phone_attr * Description: 更改发送到目的地址(手机)的属性 * ===================================================================================== */ /*{{{*/ int change_phone_attr ( const char *src,src); return 0; } /* ----- end of function change_phone_attr ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: change_other_phone * Description: 更改发送到目的手机号码 (参数改变) * ===================================================================================== */ /*{{{*/ int change_other_phone ( const char *src,src); if ( strlen(des)%2 != 0 ) { strcat(des,"F"); } return 0; } /* ----- end of function change_other_phone ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: change_fix * Description: 改变固定格式,详细请参考其他(没有不变的东西) * ===================================================================================== */ /*{{{*/ int change_fix ( const char *src,src); return 0; } /* ----- end of function change_fix ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: change_gb2312_msg * Description: 改变要发送的实际信息内容 * ===================================================================================== */ /*{{{*/ int change_gb2312_msg ( const char *src,src); return 0; } /* ----- end of function change_gb2312_msg ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: make_mesg * Description: 该函数是该文件的'主'函数,它调动上面的函数来实现短信消息的内容合成。 * ===================================================================================== */ /*{{{*/ int make_mesg ( char *src,char *dest,int src_len,int des_len ) { int rc; char b2s[MSIZE]; /* 字节流转换字符串 */ char nhex[6]; /* 计算消息的内容长度(十六进制表示)*/ char nhex_even[4] = {'0'}; /* PDU规则,长度为奇数前加0 */ g2u(src,src_len,dest,des_len); /* 将GB2312流转换成UTF-16 */ rc = bytes2string(dest,b2s,strlen(dest));
/* 开发板中不需要switch_byte2,主机上需要. 让我伤心的地方 */ //rc = switch_byte2(b2s,rc); /* GB2312 -> UTF-16 转换之后,再经过字节流转换成字符串,前端多了4个字符. */ sprintf(nhex,"%X",(rc-4)/2); /* (GB2312 -> UTF-16)除以2是得到的汉字字符个数,在格式化输出十六进制 */ //sprintf(nhex,rc/2); /* 使用(GB2312 -> UCS2)时 */
/* 判断长度是否是偶数 */ if ( strlen(nhex)%2 == 1 ) { /* 奇数 前端加0 */ strcat(nhex_even,nhex); memset(dest,MSIZE); strcpy(dest,nhex_even); } else { memset(dest,nhex); } strcat(dest,b2s+4); /* (GB2312 -> UTF-16)前面的4个字节是没用的 */ //strcat(dest,b2s); /* 使用(GB2312 -> UCS2)时 */ return strlen(dest); } /* ----- end of function make_mesg ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: make_content * Description: 将不同部分的内容组合成完整PDU编码内容 * ===================================================================================== */ /*{{{*/ int make_content(struct gprs_pdu *gpdu,char *content) { int nsim = 0; /* SIM用户识别卡所占字节(转换为十六进制)*/ char unicode_msg[MSIZE]; /* 1. 先将消息内容进行编码转换 */ make_mesg(gpdu->gb2312_msg,unicode_msg,strlen(gpdu->gb2312_msg),MSIZE); /* 2. 短信消息中心号码数字奇偶转换 */ switch_byte1(gpdu->sim_center,strlen(gpdu->sim_center)); /* 3. 接受方手机号码数字奇偶转换 */ switch_byte1(gpdu->phone,strlen(gpdu->phone)); /* 4. 将短消息中心地址长度(16/2)和号码类型拼接到content数组中 */ strcat(content,gpdu->sim_attr); /* 5. 将短信息中心号码拼接到content数组中 */ strcat(content,gpdu->sim_center); /* 6. 计算SMSC(Short Message Server Center)相关内容的长度, */ nsim = strlen(content); /* 7. 将接收方的手机号属性拼接到content数组中 */ strcat(content,gpdu->phone_attr); /* 8. 将接受方的手机号拼接到content数组中 */ strcat(content,gpdu->phone); /* 9. 将手机号后面的固定格式拼接到content数组中 */ strcat(content,gpdu->fix); /* 10.将消息的实际内容拼接到content数组中 */ strcat(content,unicode_msg); /* 11.返回:PDU总长度减去SIM用户识别卡所占字节*/ return (strlen(content) - nsim) ; } /* ----- end of function make_content ----- */ /*}}}*/
/* * === FUNCTION ====================================================================== * Name: send_msg * Description: 功能:发送信息 * ===================================================================================== */ /*{{{*/ void send_msg ( int fd,char *content,int len,char *dail ) { char cmd_buff[C_SIZE]; char call_buff[C_SIZE] = "ATD"; /* 拨号功能 */ int n_rw = 0;
printf("Start:/n");
/* 第一阶段:先发送 "AT" 命令,测试ARM与GPRS是否建立通信 */ write(fd,"AT/r",3); printf("1. Send AT/n"); #ifdef SLEEP3S sleep(3); #endif memset(cmd_buff,C_SIZE); n_rw = read(fd,cmd_buff,C_SIZE); printf("Receive %d bytes is %s/n",n_rw,cmd_buff);
/* 第二阶段:设置信息的模式 0:PDU,1:Plain */ write(fd,"AT+CMGF=0/r",10); printf("2. Send AT+CMGF=0/n"); #ifdef SLEEP3S sleep(3); #endif memset(cmd_buff,cmd_buff);
/* 第三阶段:PDU模式下发送消息密令 */ memset(cmd_buff,C_SIZE); sprintf(cmd_buff,"AT+CMGS=%d/r",len); write(fd,strlen(cmd_buff)); printf("3. Send %s/n",cmd_buff); #ifdef SLEEP3S sleep(3); #endif memset(cmd_buff,cmd_buff);
/* 第四阶段:发送消息内容,以0x1A结尾 */ strcat(content,"/x1a"); n_rw = write(fd,content,strlen(content)); printf("4. Send %d Message /n",n_rw); #ifdef SLEEP3S sleep(3); #endif memset(cmd_buff,cmd_buff);
/* 第五阶段:实现拨号 */ if ( NULL != dail ) { sleep(10); strncat(call_buff,dail,11); printf("call_buff :%s/n",call_buff); strcat(call_buff,";/r"); write(fd,call_buff,strlen(call_buff)); printf("Call some one!/n"); memset(cmd_buff,cmd_buff); printf("/nEnd/n"); }
return ; } /* ----- end of function send_msg ----- */ /*}}}*/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |