PDU-7Bit转码

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

/*#include <sys/types.h>
#include <fcntl.h>
*/
#include <iconv.h>

#include "sw_cell_type.h"
#include "cellular_err.h"
#include "cellular_net.h"
#include "cellular_msg.h"
#include "cellular_sms.h"
#include "cellular_atcmd.h"


#ifndef ICONV_CONST
# define ICONV_CONST const
#endif

#define SMS_LIST_SIZE  135*1024

int g_mem_type;
sms_t list_head;
char sms_center[PH_NUM_LEN]="";


int gsmEncode7bit(unsigned char* pDst,const char* pSrc)
{
	int nSrc;        // 源字符串的计数值
	int nDst;        // 目标编码串的计数值
	int nChar;       // 当前正在处理的组内字符字节的序号,范围是0-7
	unsigned char nLeft;    // 上一字节残余的数据
	int nSrcLength=strlen(pSrc);



	// 计数值初始化
	nSrc = 0;
	nDst = 0;

	// 将源串每8个字节分为一组,压缩成7个字节
	// 循环该处理过程,直至源串被处理完
	// 如果分组不到8字节,也能正确处理
	while(nSrc<nSrcLength)
	{
		// 取源字符串的计数值的最低3位
		nChar = nSrc & 7;

		// 处理源串的每个字节
		if(nChar == 0)
		{
			// 组内第一个字节,只是保存起来,待处理下一个字节时使用
			nLeft = *pSrc;
		}
		else
		{
			// 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节
			*pDst = (*pSrc << (8-nChar)) + nLeft;

			// 将该字节剩下的左边部分,作为残余数据保存起来
			nLeft = *pSrc >> nChar;
			// 修改目标串的指针和计数值 pDst++;
			//printf("%c",*pDst);
			pDst++;  nDst++;

		}
		// 修改源串的指针和计数值
		pSrc++; nSrc++;
	}

	//Nleft还有剩余,需要一个自己保留。
	nChar = nSrc & 7;
	if(nChar != 0)
	{
		*pDst=nLeft;
		nDst++; 
		pDst++;
	}
	*pDst='\0';

	// 返回目标串长度
	return nDst;
}


int sms_mem_type( int mem_type)
{
    if( mem_type == SMS_ON_MEM)
    {
        send_cmd( AT_SMS_ON_MEM, NULL, 0);
        return 0;
    }
    else if( mem_type == SMS_ON_SIM)
    {
        send_cmd( AT_SMS_ON_SIM, NULL, 0);
        return 0;
    }
    else
    {
        return -1;
    }
}

sms_t *find_lsms_head( sms_t *sms, sms_t *head)
{
    while( head != NULL)
    {
        if( head->lsms_mark == sms->lsms_mark)
        {
            return head;
        }
        head = head->next;
    }

    return head;
}

int add_to_list( sms_t *sms)
{
    sms_t *head = list_head.next;
    sms_t *last = &list_head;
    sms_t *temp = NULL;

    if( sms == NULL)
    {
        return -1;
    }   

    temp = ( sms_t *)malloc( sizeof(sms_t));
    if( temp == NULL)
    {
        return -1;
    }
    memset( temp , 0, sizeof( sms_t));
    memcpy( temp, sms, sizeof( sms_t));
    
    //printf("sms_mark = %d, ser_num = %d\n", sms->lsms_mark, sms->lsms_sernum);
    //printf("temp_mark = %d, temp_num = %d\n", temp->lsms_mark, temp->lsms_sernum);

    if( temp->lsms_mark != 0)
    {
        //printf("mark = %d \n", sms->lsms_mark);
        head = find_lsms_head( sms, head);
        /*if( head == NULL)
        {
            temp->next = list_head.next;
            list_head.next = temp;
            return 0;
        }
        */
        if( head != NULL)
        {
            while( head != NULL && head->lsms_mark == temp->lsms_mark)
            {
                if( head->lsms_sernum > temp->lsms_sernum)
                {
                    break;
                }
                last = head;
                head = head->next;
            }
            temp->next = last->next;
            last->next = temp;
            return 0;
        }
    }
    
    head = list_head.next;
    last = &list_head;
    while( head != NULL)
    {
        if( strcmp( temp->date_time, head->date_time) > 0)
        {
            break;
        }
        last = head;
        head = head->next;
    }
    last->next = temp;
    temp->next = head;
    

    return 0;
    
}

/*!
 * 对字符串进行语言编码转换
 * param from  原始编码,比如"GB2312",的按照iconv支持的写
 * param to      转换的目的编码
 * param save  转换后的数据保存到这个指针里,需要在外部分配内存
 * param savelen 存储转换后数据的内存大小
 * param src      原始需要转换的字符串
 * param srclen    原始字符串长度
 * */
int convert(const char *from, const char *to, char* save, int savelen, char *src, int srclen)
{
    iconv_t cd;
    char   *inbuf = src;
    size_t inbufsize = srclen;
    char *outbuf = save;
    size_t outbufsize = savelen;
    int status = 0;
    //size_t  savesize = 0;
    /*const char* inptr = inbuf;
    size_t      insize = inbufsize;
    char* outptr = outbuf;
    size_t outsize = outbufsize;
    */
    int ret;

    cd = iconv_open(to, from);
    iconv(cd,NULL,NULL,NULL,NULL);
    if (inbufsize == 0) {
        status = -1;
        return -1;
    }
	printf("cover---------------------------%din,: %s, in size = %d,\n\n", __LINE__, inbuf, inbufsize);
    ret = iconv( cd, &inbuf, (size_t)&inbufsize, &outbuf, &outbufsize);

    iconv_close(cd);
	printf("cover---------------------------%din,: %s, in size = %d, outbuf:%s, outsize = %d\n\n", __LINE__, inbuf, inbufsize, outbuf,outbufsize);
    return status;

}


int char_swap( char *data, int len)
{
    char temp;
    int i;

    for( i=0; i<len; i++)
    {
        temp = *data;
        *data = *(data+1);
        *(data+1) = temp;
        data += 2;
    }
    return 0;
}

int deal_pud_sms( char *pud_sms)
{
    sms_t sms;
    int pud_len = 0;
    int sms_center_len = 0;
    int ph_num_len = 0;
    int num_type = 0;
    int pud_type = 0;
    int code_type = 0;
    int pts[PTS_LEN]={0};
    int i;
    int text_len = 0;
    char *pud_data = NULL;

    memset( &sms, 0, sizeof(sms_t));

    memset( sms.ph_num, 0, PH_NUM_LEN);
    sscanf( pud_sms, "%*[^:]: %d,%d,,%d\n%02x", &sms.index, &sms.stat, &pud_len, &sms_center_len);
    //printf("index = %d stat = %d , pud_len = %d, sms_center_len = %d\n", 
    //     sms.index, sms.stat, pud_len, sms_center_len);

    //pud_data = strchr( pud_sms, '\n') + 1;
    pud_data = strchr( pud_sms, '\n') ;
    pud_data = strchr( pud_data, '0') ;

    sscanf( pud_data, "%02x %02x", &sms_center_len, &num_type);
    //printf("sms_center_len = %d\n", sms_center_len);
    memcpy( sms_center, pud_data+2, (sms_center_len + sms_center_len%2)*2);
    //printf("sms_center = %s\n", sms_center);
   // printf("copy sms_center end\n");

    pud_data += ( sms_center_len + sms_center_len%2) * 2 + 2;
    sscanf( pud_data, "%02x", &pud_type);
    //printf("pud_type = %x, %2.2s \n", pud_type, pud_data);
    pud_data += 2;
    sscanf( pud_data, "%02x %02x", &ph_num_len, &num_type);
    //printf( "num_len = %d num_type = %d\n", ph_num_len, num_type);
    pud_data += 4;
    char_swap( pud_data, (ph_num_len + ph_num_len%2)/2);
    if( num_type == 0x91)
    {
        sms.ph_num[0] = '+';
    }
    strncat( sms.ph_num, pud_data, ph_num_len);
    //printf("form: %s\n", sms.ph_num);
    
    pud_data += ph_num_len + ph_num_len%2 + 2;
    sscanf( pud_data, "%02x", &code_type);
    //printf("type=%d %2.2s\n", code_type, pud_data);

    pud_data += 2;
    char_swap( pud_data, PTS_LEN - 1);
    //printf("data = %6.6s\n", pud_data);
    for( i=0; i<PTS_LEN; i++)
    {
        sscanf( pud_data, "%02d", &pts[i]);
        pud_data += 2;
        //printf("%02d ", pts[i]);
    }
    //printf("\n");
    sprintf( sms.date_time, "20%02d-%02d-%02dT%02d:%02d:%02d +00:00",
            pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
    //printf("Date: %s\n", sms.date_time);
    
    char text_buf[TEXT_LEN];

    sscanf( pud_data, "%02x", &text_len);
    pud_data += 2;
    memset( sms.text, 0, TEXT_LEN);
    memset( text_buf, 0, TEXT_LEN);
    if( pud_type & 0x40)
    {
        int head_len;

        sscanf( pud_data, "%02x", &head_len);
        //printf("head_len = %d\n", head_len);
        pud_data += 6;
        if( head_len == 5)
        {
            sscanf( pud_data, "%02x %02x %02x", &sms.lsms_mark, &sms.lsms_total, &sms.lsms_sernum);
            //printf("mark = %d total = %d sernum = %d \n", sms.lsms_mark, sms.lsms_total, sms.lsms_sernum);
            pud_data += 6;
        } 
        else if( head_len == 6)
        {
            sscanf( pud_data, "%04x %02x %02x", &sms.lsms_mark, &sms.lsms_total, &sms.lsms_sernum);
            pud_data += 8;
        }
        text_len -= head_len + 1;
    }
    int temp;
    for( i=0; i<text_len; i++)
    {
        sscanf( pud_data, "%02x", &temp);
        text_buf[i] = (char)temp;
        //printf("%02x ", temp);
        pud_data += 2;
    }
    if( code_type && 0x08)
    {
        convert( "UCS-2", "UTF-8", sms.text, TEXT_LEN, text_buf, text_len);
    } else 
    {
      strcpy( sms.text, text_buf);  
    }
    //printf("\n");
    //printf( "text = *%s* \n", sms.text);

    add_to_list( &sms);



    return 0;
}

int deal_sms_list( char *sms_list)
{
    //char *local = sms_list;
    //printf("%s\n", sms_list);
    /*for(; *sms_list != '\0';)
    {
        deal_pud_sms( sms_list);
        sms_list = strchr( sms_list, '\n');
        if( sms_list == NULL)
        {
            return 0;
        }
        sms_list++;
        sms_list = strchr( sms_list, '\n');
        if( sms_list == NULL)
        {
            return 0;
        }
        sms_list++;
        if( *sms_list == '\0')
        {
            return 0;
        }

    }*/

    sms_list = strstr( sms_list, "+CMGL");
    while( sms_list != NULL)
    {
        printf("pud_data:*%20.20s*\n", sms_list);
        deal_pud_sms( sms_list);
        sms_list = strchr( sms_list, '\n');
        sms_list = strstr( sms_list+1, "+CMGL");
    }
    return 0;
}

int sms_list_print()
{
    sms_t *head = list_head.next;
    sms_t *last = &list_head;

    printf("start print sms list\n");

    while( head != NULL)
    {
        printf("index =  %d\n", head->index);
        printf("Date: %s\nFrom: %s\nText:%s", head->date_time, head->ph_num, head->text);
        last = head;
        head = head->next;

        /*while( head != NULL && head->lsms_mark != 0 && last->lsms_mark == head->lsms_mark)
        {   
            //printf("Mark = %d num = %d\n", head->lsms_mark, head->lsms_sernum);
            printf("%s", head->text);
            last = head;
            head = head->next;
        }
        */
        printf("\n\n");
    }

    return 0;
}

int free_sms_list()
{
    sms_t *head = list_head.next;
    sms_t *last = &list_head;
    int i = 0;

    while( head != NULL)
    {
        last = head;
        head = head->next;
        free(last);
        i++;
    }

    list_head.next = NULL;

    //printf(" i = %d freed %d bytes\n", i, i*sizeof(sms_t));
    return 0;

}

/*int sms_to_db()
{
    sms_t *head = list_head.next;

    while( head != NULL)
    {
        insert_sms_db( head);
        head = head->next;
    }

    return 0;
}
*/
sms_t *get_sms_list( int mem_type)
{
    static char sms_list[SMS_LIST_SIZE] = "";
    int sms_size = SMS_LIST_SIZE;
    int ret = 0;

    memset( sms_list, 0, SMS_LIST_SIZE);

    free_sms_list();

    /*if( SMS_ON_MEM == mem_type)
    {
        printf("SMS_ON_MEM\n");
        get_sms_table();
    }
    else if( SMS_ON_SIM == mem_type)
    {
        printf("SMS_ON_SIM\n");
        ret = send_cmd( AT_SMS_LIST, sms_list, sms_size);
        //printf("%s\n", sms_list);
        deal_sms_list( sms_list);
    }
    else
    {
        //printf("SMS_ON_UNKNOW\n");
        return NULL;
    }
    //sms_list_print();
    //printf("%s", sms_list);
    */
    ret = sms_mem_type( mem_type);
    if( ret != 0)
    {
        return NULL;
    }
    ret = send_cmd( AT_SMS_LIST, sms_list, sms_size);
    //printf("%s\n", sms_list);
    deal_sms_list( sms_list);
    //ret = sms_mem_type( g_mem_type);

    return list_head.next;
}

int sms_delete( int mem_type, int index)
{
    char cmd[127] = "";
    int ret;

    /*if( mem_type == SMS_ON_MEM)
    {
        ret = sms_db_del( index);
    }
    else if( mem_type == SMS_ON_SIM)
    {
        if( index == -1)
        {
            sprintf( cmd, "AT+CMGD=0,4");
        }
        else
        {
            sprintf( cmd, "AT+CMGD=%d", index);
        }
        ret = send_cmd( cmd, NULL, 0);
    }
    */
    ret = sms_mem_type( mem_type);
    if( ret != 0)
    {
        return -1;
    }
    if( index == -1)
    {
        sprintf( cmd, "AT+CMGD=0,4\n");
    }
    else
    {
        sprintf( cmd, "AT+CMGD=%d\n", index);
    }
    ret = send_cmd( cmd, NULL, 0);

    return ret;
}

int send_text_sms( char *ph_num, char *text)
{
    int ret = 0;
    char cmd[255]="";
    printf("num = %s, text=%s\n", ph_num, text);
    ret = send_cmd( AT_SMS_TYPE_TEXT, NULL, 0);

    sprintf( cmd, "AT+CMGS=\"%s\"\r", ph_num);
    ret = send_cmd( cmd, NULL, 0);
    memset( cmd, 0, 255);
    sprintf( cmd, "%s\26", text);
    ret = send_cmd( cmd, NULL, 0);
    return ret;
}

int send_pdu_sms( char *ph_num, char *text)
{
	printf("num === %s, txt ==== %s\n", ph_num, text);
    int ret = 0;
    char *cp = text;
    char sms_type = 0;
    char cmd[512] = "";
    int num_len=0;
    //char text_buf[200] = "";
    char *text_buf = NULL;
    //char pdu_text_buf[400] = "";
    char *pdu_text_buf = NULL;
    int text_len = 0;
    char msg_buf[200] = "";
    int msg_len = 0;
    int code_type = 0;
    char ph_num_buf[20]="";
    int num_type = 0x81;
	char center_getnum[64] = {0};
	char center_num[64] = {0};//中心号码

    for(; *cp != '\0'; cp++)
    {
        sms_type |= *cp;
    }
    if( sms_type < 0)
    {
        code_type = 8;
    }
    
    strcpy( ph_num_buf, ph_num);
    ph_num = ph_num_buf;
    printf("num = %s, text=%s\n", ph_num, text);
    ret = send_cmd( AT_SMS_TYPE_PDU, NULL, 0);

	//获取中心号码
	sw_cell_get_center_num(center_getnum);
	int sms_center_len = strlen(center_getnum);
    if( sms_center_len%2 != 0)
    {
        strcat( center_getnum, "F");
        char_swap( center_getnum, sms_center_len + 1);
    }
    else
    {
        char_swap( center_getnum, sms_center_len);
    }
	sprintf(center_num, "91%s", center_getnum);//转换后的中心号码
	//sms_center_len = strlen(sms_center);//中心号码长度
	sms_center_len = strlen(center_num);//中心号码长度
	printf("sms centerd:%s, sms len:%d\n",center_num, sms_center_len);
//	printf("ret =  %d\n", ret);
#if 0
	memset( cmd, 0, 512);
	sprintf( cmd, "AT+CMGS=?\r");
	ret = send_cmd( cmd, NULL, 0);
	if( ret != AT_OK)
	{   
		printf( "semd cmd :%s failed\n", cmd);
		//return -1;
	}
#endif
    if( *ph_num == '+')
    {
        ph_num++;
        num_type = 0x91;
    }

    num_len = strlen(ph_num);
    if( num_len%2 != 0)
    {
        strcat( ph_num, "F");
        char_swap( ph_num, num_len + 1);
    }
    else
    {
        char_swap( ph_num, num_len);
    }

    text_len = strlen( text);
	int actrue_len = text_len;
    int text_buf_size = text_len * 2;
    int pdu_text_buf_size = text_len * 4;

    text_buf = (char *)malloc( text_buf_size);
    pdu_text_buf = (char *)malloc( pdu_text_buf_size);
    if( text_buf == NULL || pdu_text_buf == NULL)
    {
        if( text_buf != NULL)
        {
            free( text_buf);
        }
        if( pdu_text_buf != NULL)
        {
            free( pdu_text_buf);
        }

        return -1;
    }
    memset( text_buf, 0, text_len * 2);
    if( code_type == 8)
    {
        ret = convert( "UTF-8", "UTF-16", text_buf, text_buf_size, text, text_len);
        printf("codec ret = %d\n", ret);
        text_len = strlen( text_buf);
    }  
    else
    {
        strcpy( text_buf, text);
    }

	printf("text buf ==== %s\n",text_buf);
    text = text_buf;
	printf("text ==== %s\n",text);
    char *pdu_text = pdu_text_buf;
    int i;
    memset( pdu_text, 0, pdu_text_buf_size);
	int len = gsmEncode7bit( pdu_text, text);

	for(i=0;i<len;i++)
	{
		printf("%02x ", pdu_text[i]);
	}
#if 0
    for( i=0; i<text_len; i++)
    {
        unsigned char temp;
        temp = *text;
        sprintf( pdu_text, "%02x", temp);
        text++;
        pdu_text += 2;
    }
#endif
	printf("pdu_text === %s\n", pdu_text_buf);
    text_len = strlen(pdu_text_buf);

    if( text_len > 140)
    {
        int msg_type = 0x40;
        int mark = 0;
        int total = 0;
        int l_num = 0;
        char long_sms_buff[300] = "";
        char *pdu_text_buf_p = pdu_text_buf;
            
        total = text_len/280;
        if( (text_len%280) != 0)
        {
            total++;
        }
        for( i=0; i<total; i++)
        {
            memset( cmd, 0, 512);
            memset( long_sms_buff, 0, 300);
            strncpy( long_sms_buff, pdu_text_buf_p, 280);
            pdu_text_buf_p += 280;
            text_len = strlen( pdu_text_buf_p) / 2 + 6;
            sprintf( msg_buf, "%02x%02x%s%02x%02x%02x%02x05000300%02x%02x%s", 
                    num_len, num_type, ph_num, msg_type, code_type, 0xff, text_len, total, i + 1,pdu_text_buf);
            msg_len = strlen( msg_buf) / 2 + 2;
            sprintf( cmd, "AT+CMGS=%d%c", msg_len, '\n');
            
            ret = send_cmd( cmd, NULL, 0);
            if( ret != AT_OK)
            {   
                //printf( "semd cmd :%s failed\n", cmd);
                //return -1;
            }
            memset( cmd, 0, 512);
            sprintf( cmd, "1100%s%c",  msg_buf, 0x1a);
            ret = send_cmd( cmd, NULL, 0);
        }
    }
    else
    {
        sprintf( msg_buf, "%02x%02x%s%02x%02x%02x%02x%s", num_len, num_type, ph_num, 0, code_type, 0xAA,text_len/2, pdu_text_buf);
        msg_len = strlen( msg_buf) / 2 + 2;
		printf("message len = %d\n", msg_len);
		//sprintf( cmd, "AT+CSCA?\r");
		// sprintf( cmd, "AT+CMGS=19\r07919761989901F011000B919762103144F60000AA05E8329BFD06%c",0x1a);
		//sprintf( cmd, "AT+CMGS=%d\r1100%s%c", msg_len, msg_buf, 0x1a);
		printf("center ===== %s\n",center_num);
		sprintf( cmd, "AT+CMGS=%d\r%02x%s1100%s%c", msg_len, sms_center_len/2, center_num, msg_buf, 0x1a);
		printf("message = %s\n", cmd);
	//	sprintf( cmd, "AT+CMGR=0\r");
      //  ret = send_cmd( cmd, NULL, 0);
        if( ret != AT_OK)
        {   
            printf( "semd cmd :%s failed\n", cmd);
            return -1;
        }
#if  0 
        memset( cmd, 0, 512);
        //sprintf( cmd, "1100%02x%s%s%c", strlen(sms_center)/2, sms_center, msg_buf, 0x1a);
        sprintf( cmd, "1100%s%c",  msg_buf, 0x1a);
        //sprintf( cmd, "0011000D91683117604419F30008A70A66fe5baa950b60a8597d%c", 0x1a);

	printf("12---------------------------%d meesage == %s\n", __LINE__, cmd);
        ret = send_cmd( cmd, NULL, 0);
        if( ret != AT_OK)
        {   
            printf( "semd cmd :%s failed\n", cmd);
            return -1;
        }
#endif
    }

    free( text_buf);
    free( pdu_text_buf);
    return ret;
}
int sms_pack_send( char *ph_num, char *text)
{
    int ret = 0;

    /*for(; *cp != '\0'; cp++)
    {
        sms_type |= *cp;
    }*/

    /*if( sms_type >= 0)
    {
        ret = send_text_sms( ph_num, text);
    }
    else
    {*/
        ret = send_pdu_sms( ph_num, text);
    //}

    return ret;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值