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, 0, 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, 0, 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 inlen, char *outbuf, int outlen )

{

    //return code_convert("unicode","utf-8",inbuf,inlen,outbuf,outlen);

    /* 交叉编译后在,开发板中个人使用下面的,iconv_open对系统有依赖 */

    return code_convert("UTF-16", "GB2312", inbuf, inlen, outbuf, outlen);

}        

/* ----- end of function u2g ----- */

/*}}}*/

 

 

 

/*

* === FUNCTION ======================================================================

* Name: g2u

* Description: GB2312码转为UNICODE码

* =====================================================================================

*/

/*{{{*/

int g2u ( char *inbuf, int inlen, char *outbuf, int outlen )

{

    /* 交叉编译后在,开发板中个人使用下面的,iconv_open对系统有依赖 */

    /* GB2312 -> UTF-16 转换之后,前端会有多余字节 */

    return code_convert("GB2312", "UTF-16", inbuf, inlen, outbuf, outlen);

    /* GB2312 -> UCS2 主机正常,在开发板上使用时会段错误,断点在iconv_open处,可能缺少lib*/

    //return code_convert("GB2312", "UCS2", inbuf, inlen, outbuf, 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, 0, 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, 0, 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, char *des )

{

    memset(des, 0, strlen(des));

    strcpy(des, src);

    return 0;

}        

/* ----- end of function change_phone_attr ----- */

/*}}}*/

 

 

 

/*

* === FUNCTION ======================================================================

* Name: change_other_phone

* Description: 更改发送到目的手机号码 (参数改变)

* =====================================================================================

*/

/*{{{*/

int change_other_phone ( const char *src , char *des )

{

    memset(des, 0, strlen(des));

    strcat(des, "86");

    strcat(des, 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 , char *des )

{

    memset(des, 0, strlen(des));

    strcpy(des, src);

    return 0;

}        

/* ----- end of function change_fix ----- */

/*}}}*/

 

 

 

/*

* === FUNCTION ======================================================================

* Name: change_gb2312_msg

* Description: 改变要发送的实际信息内容

* =====================================================================================

*/

/*{{{*/

int change_gb2312_msg ( const char *src, char *des )

{

    memset(des, 0, strlen(des));

    strcpy(des, 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, "%X", rc/2); /* 使用(GB2312 -> UCS2)时 */

 

    /* 判断长度是否是偶数 */

    if ( strlen(nhex)%2 == 1 )

    {

        /* 奇数 前端加0 */

        strcat(nhex_even, nhex);

        memset(dest, 0, MSIZE);

        strcpy(dest, nhex_even);

    }

    else

    {

        memset(dest, 0, MSIZE);

        strcpy(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, 0, 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, 0, C_SIZE);

    n_rw = read(fd, cmd_buff, C_SIZE);

    printf("Receive %d bytes is %s/n", n_rw, cmd_buff);

 

 

    /* 第三阶段:PDU模式下发送消息密令 */

    memset(cmd_buff, 0, C_SIZE);

    sprintf(cmd_buff, "AT+CMGS=%d/r", len);

    write(fd, cmd_buff, strlen(cmd_buff));

    printf("3. Send %s/n", cmd_buff);

#ifdef SLEEP3S

    sleep(3);

#endif

    memset(cmd_buff, 0, C_SIZE);

    n_rw = read(fd, cmd_buff, C_SIZE);

    printf("Receive %d bytes is %s/n", n_rw, 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, 0, C_SIZE);

    n_rw = read(fd, cmd_buff, C_SIZE);

    printf("Receive %d bytes is %s/n", n_rw, 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, 0, C_SIZE);

        n_rw = read(fd, cmd_buff, C_SIZE);

        printf("Receive %d bytes is %s/n", n_rw, cmd_buff);

        printf("/nEnd/n");

    }

 

    return ;

}        

/* ----- end of function send_msg ----- */

/*}}}*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值