⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sms.cpp

📁 短信猫完整开发例子,里面包含全部的字节流码
💻 CPP
字号:
#include "sms.h"
#include <Dialogs.hpp>
/*
AT命令:每个指令以AT开头,以回车结尾。每个命令执行成功与否都有相应的返回。其
他一些非预期的信息(如有人拨号进来、线路无信号等),模块将有对应的一些信息提
示,接收端可做相应的处理。其控制符有如下两个:
结束符(<CR>)十六进制的0x0D, 十进制值:13,char表示值为:'\n'
发送符(<Ctrl/Z>)十六进制的0x1A,十进制值:26;
*/

//---------------------------------------------------------------------------

phone_type __stdcall get_phone_type(char *p)
{
    if (p[0] == '0')
        return _wi;  //如果电话首位是0,说明是小灵通。
    else
        return _mp;  //否则统一认为是手机号码。
}

//---------------------------------------------------------------------------

void __stdcall encode_unicode(char *_dest, char *_src
    , unsigned short *_len, unsigned short *_code_len)
{
    unsigned short len = 0;

    len  = MultiByteToWideChar(CP_ACP, 0, _src, -1, NULL, 0);
    wchar_t *cur = new wchar_t[len];
    try
    {
        MultiByteToWideChar(CP_ACP, 0, _src, -1, cur, len);

        for (unsigned int i = 0; i < wcslen(cur); i++)               
        {
            strcat(_dest, IntToHex(*(cur + i), 4).c_str());
        }

        *_len = strlen(_dest) / 2;
        *_code_len = *_len;
    }
    __finally
    {
        delete[] cur;
    }
}

void __stdcall decode_unicode(char *_dest, char *_src)
{
    unsigned short os = 0, len = 0;
    wchar_t *src = new wchar_t[(strlen(_src) / 4) + 1];
    wchar_t src_bit[5] = {'\0'};

    try
    {
        for (size_t i = 0; i < strlen(_src); i = i + 4)
        {
            *src_bit = *(_src + i);
            *(src_bit + 1) = *(_src + (i + 1));
            *(src_bit + 2) = *(_src + (i + 2));
            *(src_bit + 3) = *(_src + (i + 3));
            *(src + os) = wcstol(src_bit, NULL, 16);
            os++;
        }
        *(src + os) = '\0';

        len = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
        WideCharToMultiByte(CP_ACP, 0, src, -1, _dest, len, NULL, NULL);

    }
    __finally
    {
        delete[] src;
    }
}

void __stdcall encode_bit7(char *_dest, char *_src
    , unsigned short *_len, unsigned short *_code_len)
{
    unsigned short n = 0, os = 0, cur = 0;  //n:位数;os:目标下标位。cur:临时变量

    *_len = strlen(_src);    //字节个数

    for(int i = 0; i < *_len; i++)
    {
        if   (i < (*_len - 1))
            cur = (((unsigned char)(*(_src + i))) >> n)
                | ((((unsigned char)(*(_src + (i + 1)))) << (7 - n)) & 0XFF);
        else
            cur = (((unsigned char)(*(_src + i))) >> n) & 0X7F;

        strcpy(_dest + os, IntToHex(cur, 2).c_str());

        os += 2;

        n = (n + 1) % 7;
        if (n == 0)  //第八个字节要跳过,8个字节压缩到7个字节中存储。
            i++;
    }
    *_code_len = strlen(_dest) / 2;  //编码长度。
}


void __stdcall decode_bit7(char *_dest, char *_src)
{
    unsigned short n = 0, rud = 0, os = 0; //n:位数;rud:遗留字节值;os:指针下移位数。\
    
    unsigned char *src = new unsigned char[(strlen(_src) / 2) + 1];
        
    char src_bit[3] = {'\0'};

    try
    {
        for (size_t i = 0; i < strlen(_src); i = i + 2)
        {
            *src_bit = *(_src + i);
            *(src_bit + 1) = *(_src + (i + 1));
            *(src + os) = strtol(src_bit, NULL, 16);
            os++;
        }
        *(src + os) = '\0';

        os = 0;
        for (size_t i = 0; i < strlen(src); i++)
        {
            *(_dest + os) = (((*(src + i)) << n) | rud) & 0X7F;

            rud = (*(src + i)) >> (7 - n);
            n++;
            os++;

            if (n == 7)
            {
                *(_dest + os) = rud;
                
                rud = 0;
                n = 0;
                os++;
            }
        }
    }
    __finally
    {
        delete[] src;
    }
}

void __stdcall encode_bit8(char *_dest, char *_src
    , unsigned short *_len, unsigned short *_code_len)
{
    *_len = strlen(_src);
    unsigned char cur = 0;

    for (unsigned short i = 0; i < *_len; i++)
    {
        cur = *(_src + i);
        strcat(_dest, IntToHex(cur, 2).c_str());
    }
    *_code_len = strlen(_dest) / 2;  //编码长度。 
}

void __stdcall decode_bit8(char *_dest, char *_src)
{
    char src_bit[3] = {'\0'};
    unsigned short os = 0;
    
    for (size_t i = 0; i < strlen(_src); i = i + 2)
    {
        *src_bit = *(_src + i);
        *(src_bit + 1) = *(_src + (i + 1));

        *(_dest + os) = strtol(src_bit, NULL, 16);
        os++;
    }
}

//---------------------------------------------------------------------------

void __stdcall encode_phone(char *_dest, char *_src, unsigned char *_len)
{
    char _tmp = 0;

    if (get_phone_type(_src) == _wi) //说明是小灵通。
        strcpy(_dest, "106");
    else
         strcpy(_dest, "86");

    strcat(_dest, _src);
    *_len = strlen(_dest);

    if ( (*_len % 2) != 0 )  //如果位数为奇数位,则在最后加F补成偶数位。
        strcat(_dest, "F");

    for (unsigned int i = 0; i < strlen(_dest); i+=2)
    {
        _tmp = _dest[i];
        _dest[i] = _dest[i + 1];
        _dest[i + 1] = _tmp;
    }  //进奇偶位校验,奇偶位互换。
}

void __stdcall encode_head(char *_head, char *_phone, char *_code, unsigned short *_len)
{
    //头文件格式如下:
    //00 SMSC长度:此处省略SMSC。
    //11:FO
    //00:TP-MR
    //00: 电话号码长度,这里先置为0,后面的代码会进行修改。
    //91,81:地址类型,91是手机,81是小灵通。
    //106,86:国际区号:86中国国际区号,指手机,106是中国人自己搞的小灵通。
    //<手机号码编码> 接下来就是手机的编码号。
    //00: PID
    //08: 编码类型:08为Unicode编码,00为Bit 7编码,15为Bit 8编码。
    //A7: 有效期。

    char _tmp = 0;

    if (get_phone_type(_phone) == _wi) //说明是小灵通。
        strcpy(_head, "0011000081106");
    else
        strcpy(_head, "001100009186");

    strcat(_head, _phone);
    *_len = strlen(_head + 10);

    *(_head + 6) = IntToHex(*_len, 2).c_str()[0];
    *(_head + 7) = IntToHex(*_len, 2).c_str()[1];

    if ( (*_len % 2) != 0 )  //如果位数为奇数位,则在最后加F补成偶数位。
        strcat(_head + 10, "F");

    for (unsigned int i = 0; i < strlen(_head + 10); i+=2)
    {
        _tmp = *(_head + (10 + i));
        *(_head + (10 + i)) = *(_head + (10 + i + 1));
        *(_head + (10 + i + 1)) = _tmp;
    }  //进奇偶位校验,奇偶位互换。

    strcat(_head, "00");  //PID;
    strcat(_head, _code); //编码类型。
    strcat(_head, "01");  //有效期。

    *_len = strlen(_head) / 2;
}

//---------------------------------------------------------------------------

AnsiString __stdcall SendEncode(char *_phone, char *_code, char *_message)
{
    char head[50] = {'\0'};
    char info[512] = {'\0'};
    unsigned short head_len = 0, info_len = 0, code_len = 0;

    //编码PDU头。
    encode_head(head, _phone, _code, &head_len);
    //编码PDU内容。

    if (strcmp(_code, _ud.c_str()) == 0)        //Unicode编码模式。
    {
        //这里可以处理相应的代码:
        
        encode_unicode(info, _message, &info_len, &code_len);
    }
    else if (strcmp(_code, _b7.c_str()) == 0)   //Bit 7编码模式。
    {
        encode_bit7(info, _message, &info_len, &code_len);
    }
    else                                        //Bit 8编码模式。
    {
        encode_bit8(info, _message, &info_len, &code_len);
    }

    ShowMessage("AT+CMGS="
        + FormatFloat("000", (head_len + code_len)) + "\r"
        + head
        + IntToHex(info_len, 2)
        + info + char(26) + "\r\n");
    //十进制编码。
    return "AT+CMGS="
        + FormatFloat("000", (head_len + code_len)) //+ "\r"
        + head
        + IntToHex(info_len, 2)
        + info + char(26) + "\r\n";
}

//---------------------------------------------------------------------------












⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -