SMS短信的C语言代码1

一消息编码与解码
用C实现7-bit编码和解码的算法如下:

// 7-bit编码
// pSrc: 源字符串指针
// pDst: 目标编码串指针
// nSrcLength: 源字符串长度
// 返回: 目标编码串长度
int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
    int nSrc;        // 源字符串的计数值
    int nDst;        // 目标编码串的计数值
    int nChar;       // 当前正在处理的组内字符字节的序号,范围是0-7
    unsigned char nLeft;    // 上一字节残余的数据
   
    // 计数值初始化
    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++;
            nDst++;
        }
       
        // 修改源串的指针和计数值
        pSrc++; nSrc++;
    }
   
    // 返回目标串长度
    return nDst;
}
   
// 7-bit解码
// pSrc: 源编码串指针
// pDst: 目标字符串指针
// nSrcLength: 源编码串长度
// 返回: 目标字符串长度
int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
    int nSrc;        // 源字符串的计数值
    int nDst;        // 目标解码串的计数值
    int nByte;       // 当前正在处理的组内字节的序号,范围是0-6
    unsigned char nLeft;    // 上一字节残余的数据
   
    // 计数值初始化
    nSrc = 0;
    nDst = 0;
   
    // 组内字节序号和残余数据初始化
    nByte = 0;
    nLeft = 0;
   
    // 将源数据每7个字节分为一组,解压缩成8个字节
    // 循环该处理过程,直至源数据被处理完
    // 如果分组不到7字节,也能正确处理
    while(nSrc<nSrcLength)
    {
        // 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节
        *pDst = ((*pSrc << nByte) | nLeft) & 0x7f;
        // 将该字节剩下的左边部分,作为残余数据保存起来
        nLeft = *pSrc >> (7-nByte);
   
        // 修改目标串的指针和计数值
        pDst++;
        nDst++;
   
        // 修改字节计数值
        nByte++;
   
        // 到了一组的最后一个字节
        if(nByte == 7)
        {
            // 额外得到一个目标解码字节
            *pDst = nLeft;
   
            // 修改目标串的指针和计数值
            pDst++;
            nDst++;
   
            // 组内字节序号和残余数据初始化
            nByte = 0;
            nLeft = 0;
        }
   
        // 修改源串的指针和计数值
        pSrc++;
        nSrc++;
    }
   
    *pDst = 0;
   
    // 返回目标串长度
    return nDst;
}

需要指出的是,7-bit的字符集与ANSI标准字符集不完全一致,在0x20以下也排布了一些可打印字符,但英文字母、阿拉伯数字和常用符号的位置两者是一样的。用上面介绍的算法收发纯英文短消息,一般情况应该是够用了。如果是法语、德语、西班牙语等,含有 “?”、 “é”这一类字符,则要按上面编码的输出去查表,请参阅GSM 03.38的规定。

8-bit编码其实没有规定什么具体的算法,不需要介绍。

UCS2编码是将每个字符(1-2个字节)按照ISO/IEC10646的规定,转变为16位的Unicode宽字符。在Windows系统中,特别是在2000/XP中,可以简单地调用API 函数实现编码和解码。如果没有系统的支持,比如用单片机控制手机模块收发短消息,只好用查表法解决了。

Windows环境下,用C实现UCS2编码和解码的算法如下:

// UCS2编码
// pSrc: 源字符串指针
// pDst: 目标编码串指针
// nSrcLength: 源字符串长度
// 返回: 目标编码串长度
int gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
    int nDstLength;        // UNICODE宽字符数目
    WCHAR wchar[128];      // UNICODE串缓冲区
   
    // 字符串-->UNICODE串
    nDstLength = ::MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);
   
    // 高低字节对调,输出
    for(int i=0; i<nDstLength; i++)
    {
        // 先输出高位字节
        *pDst++ = wchar[i] >> 8;
        // 后输出低位字节
        *pDst++ = wchar[i] & 0xff;
    }
   
    // 返回目标编码串长度
    return nDstLength * 2;
}
   
// UCS2解码
// pSrc: 源编码串指针
// pDst: 目标字符串指针
// nSrcLength: 源编码串长度
// 返回: 目标字符串长度
int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
    int nDstLength;        // UNICODE宽字符数目
    WCHAR wchar[128];      // UNICODE串缓冲区
   
    // 高低字节对调,拼成UNICODE
    for(int i=0; i<nSrcLength/2; i++)
    {
        // 先高位字节
        wchar[i] = *pSrc++ << 8;
   
        // 后低位字节
        wchar[i] |= *pSrc++;
    }
   
    // UNICODE串-->字符串
    nDstLength = ::WideCharToMultiByte(CP_ACP, 0, wchar, nSrcLength/2, pDst, 160, NULL, NULL);
   
    // 输出字符串加个结束符    
    pDst[nDstLength] = '\0';   
   
    // 返回目标字符串长度
    return nDstLength;
}

用以上编码和解码模块,还不能将短消息字符串编码为 PDU串需要的格式,也不能直接将 PDU串中的用户信息解码为短消息字符串,因为还差一个在可打印字符串和字节数据之间相互转换的环节。可以循环调用sscanf和sprintf函数实现这种变换。下面提供不用这些函数的算法,它们也适用于单片机、DSP编程环境。

// 可打印字符串转换为字节数据
// 如:"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}
// pSrc: 源字符串指针
// pDst: 目标数据指针
// nSrcLength: 源字符串长度
// 返回: 目标数据长度
int gsmString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
    for(int i=0; i<nSrcLength; i+=2)
    {
        // 输出高4位
        if(*pSrc>='0' && *pSrc<='9')
        {
            *pDst = (*pSrc - '0') << 4;
        }
        else
        {
            *pDst = (*pSrc - 'A' + 10) << 4;
        }
   
        pSrc++;
   
        // 输出低4位
        if(*pSrc>='0' && *pSrc<='9')
        {
            *pDst |= *pSrc - '0';
        }
        else
        {
             *pDst |= *pSrc - 'A' + 10;
        }
        pSrc++;
        pDst++;
    }
   
    // 返回目标数据长度
    returnnSrcLength / 2;
}
   
// 字节数据转换为可打印字符串
// 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01"
// pSrc: 源数据指针
// pDst: 目标字符串指针
// nSrcLength: 源数据长度
// 返回: 目标字符串长度
int gsmBytes2String(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
    const char tab[]="0123456789ABCDEF";    // 0x0-0xf的字符查找表
   
    for(int i=0; i<nSrcLength; i++)
    {
        // 输出低4位
        *pDst++ = tab[*pSrc >> 4];
   
        // 输出高4位
        *pDst++ = tab[*pSrc & 0x0f];
   
        pSrc++;
    }
   
    // 输出字符串加个结束符
    *pDst = '\0';
   
    // 返回目标字符串长度
    return nSrcLength * 2;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用高通 QMI 架构写一个 SMS 短信主动上报的 C 语言代码,需要先了解以下几个概念: 1. QMI:Qualcomm MSM Interface 的缩写,是高通公司的一种通信协议,用于与高通芯片中的模块进行通信。 2. QMI Client:通过 QMI 协议与 QMI 服务端进行通信的应用程序。 3. QMI Service:运行在高通芯片中的服务端程序,提供 QMI 协议支持。 4. QMI Message:QMI 协议中的消息,可以用来传输数据或者进行控制。 下面是一个基于 QMI 架构的 SMS 短信主动上报的 C 语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <pthread.h> #include <termios.h> #include "qmi_client.h" #include "qmi_idl_lib.h" #include "qmi_cci_target_ext.h" #include "qmi_cci_common.h" #include "qmi_cci_target.h" #include "qmi_client_instance_defs.h" #include "qmi_client_helper.h" #include "qmi_client_notification.h" #include "qmi_cci_target_ext.h" #include "qmi_cci_common.h" #include "qmi_cci_target.h" #include "qmi_client_instance_defs.h" #include "qmi_client_helper.h" #include "qmi_client_notification.h" #include "qmi_cci_target_ext.h" #include "qmi_cci_common.h" #include "qmi_cci_target.h" #include "qmi_client_instance_defs.h" #include "qmi_client_helper.h" #include "qmi_client_notification.h" /* 定义 QMI 消息 ID */ #define QMI_SMS_IND_MSG_ID 0x002B /* 定义 QMI SMS 上报消息结构体 */ typedef struct { uint32_t message_id; uint8_t message_data[256]; } qmi_sms_ind_msg_t; /* 定义全局变量 */ static qmi_client_type qmi_sms_client; static pthread_t qmi_sms_thread; /* QMI SMS 上报消息处理函数 */ static void qmi_sms_indication_cb(qmi_client_type user_handle, unsigned int msg_id, void *ind_buf, unsigned int ind_buf_len, void *ind_cb_data) { /* 判断消息 ID */ if (msg_id != QMI_SMS_IND_MSG_ID) { return; } /* 解析消息 */ qmi_sms_ind_msg_t *sms_ind_msg = (qmi_sms_ind_msg_t *)ind_buf; uint8_t *message_data = sms_ind_msg->message_data; uint32_t message_id = sms_ind_msg->message_id; /* 处理消息 */ printf("Received SMS message with ID: %u\n", message_id); printf("Message content: %s\n", message_data); } /* QMI SMS 上报线程函数 */ static void *qmi_sms_thread_func(void *arg) { /* 注册 QMI SMS 上报消息处理函数 */ qmi_client_error_type ret = qmi_client_register_notify_cb(qmi_sms_client, qmi_sms_indication_cb, NULL); if (ret != QMI_NO_ERR) { printf("Failed to register QMI SMS indication callback\n"); return NULL; } /* 循环等待消息 */ while (1) { sleep(1); } return NULL; } /* 初始化 QMI SMS 客户端 */ static int init_qmi_sms() { /* 初始化 QMI 连接 */ qmi_client_error_type ret = QMI_NO_ERR; qmi_cci_options_type qmi_opts; qmi_client_qmux_instance_type qmi_sms_instance = QMI_CLIENT_INSTANCE_ANY; memset(&qmi_opts, 0, sizeof(qmi_opts)); qmi_opts.instance_id = qmi_sms_instance; qmi_opts.qos_valid = 1; qmi_opts.qos.flow_control = QMI_QOS_FLOW_CONTROL_DISABLED_V01; qmi_opts.qos.ul_minimum_guaranteed_rate_valid = 0; qmi_opts.qos.dl_minimum_guaranteed_rate_valid = 0; qmi_opts.qos.is_qos_valid = 1; ret = qmi_client_init(QMI_SMS_SERVICE_INSTANCE_ID, QMI_SMS_SERVICE_OBJECT_ID, qmi_sms_indication_cb, NULL, &qmi_opts, &qmi_sms_client); if (ret != QMI_NO_ERR) { printf("Failed to initialize QMI SMS client\n"); return -1; } /* 创建 QMI SMS 上报消息处理线程 */ ret = pthread_create(&qmi_sms_thread, NULL, qmi_sms_thread_func, NULL); if (ret != 0) { printf("Failed to create QMI SMS thread\n"); return -1; } return 0; } /* 发送 SMS 消息 */ static int send_sms(const char *message) { /* 构造 QMI SMS 发送消息 */ sms_send_req_msg_v01 sms_send_req; sms_send_resp_msg_v01 sms_send_resp; memset(&sms_send_req, 0, sizeof(sms_send_req)); memset(&sms_send_resp, 0, sizeof(sms_send_resp)); sms_send_req.message_format = SMS_MESSAGE_FORMAT_GW_PP_V01; sms_send_req.sms_on_ims_valid = 0; sms_send_req.sms_on_ims = 0; sms_send_req.smsc_address_valid = 0; sms_send_req.call_back_number_valid = 0; sms_send_req.call_back_number_len = 0; sms_send_req.call_back_number[0] = '\0'; sms_send_req.message_len = strlen(message); memcpy(sms_send_req.message, message, sms_send_req.message_len); /* 发送 QMI SMS 发送消息 */ qmi_client_error_type ret = qmi_client_send_msg_sync(qmi_sms_client, QMI_SMS_SEND_REQ_V01, &sms_send_req, sizeof(sms_send_req), &sms_send_resp, sizeof(sms_send_resp), 5000); if (ret != QMI_NO_ERR) { printf("Failed to send SMS message\n"); return -1; } /* 判断发送结果 */ if (sms_send_resp.resp.result != QMI_RESULT_SUCCESS_V01) { printf("Failed to send SMS message\n"); return -1; } return 0; } /* 主函数 */ int main(int argc, char **argv) { /* 初始化 QMI SMS 客户端 */ if (init_qmi_sms() != 0) { return -1; } /* 发送 SMS 消息 */ if (send_sms("Hello, world!") != 0) { return -1; } /* 等待 QMI SMS 上报线程结束 */ pthread_join(qmi_sms_thread, NULL); return 0; } ``` 注意:上述代码中的 QMI SMS 服务 ID 和对象 ID 需要根据具体设备进行修

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值