SMS PDU Encoding for characters like “é, è, à, @”

一世执手 提交于 2020-01-25 06:51:26

问题


I am working on SMS PDU encoding in C. I am able to convert 7-bit ASCII characters into 8 bit PDU. But when I try to use characters like "é, à, è, @" it doesn't show it's correct value. How can I encode these characters? I am using GSM 7 bit encoding. I am attaching the code. what changes should I do to convert these characters?

    #include <stdio.h>
    #include <string.h>
    #include <time.h>

    enum { SMS_MAX_PDU_LENGTH  = 256 };
enum {
BITMASK_7BITS = 0x7F,
BITMASK_8BITS = 0xFF,
BITMASK_HIGH_4BITS = 0xF0,
BITMASK_LOW_4BITS = 0x0F,

TYPE_OF_ADDRESS_INTERNATIONAL_PHONE = 0x91,
TYPE_OF_ADDRESS_NATIONAL_SUBSCRIBER = 0xC8,

SMS_DELIVER_ONE_MESSAGE = 0x04,
SMS_SUBMIT              = 0x11,

SMS_MAX_7BIT_TEXT_LENGTH  = 160,
};

static int
EncodePDUMessage(const char* sms_text, int sms_text_length, unsigned char* output_buffer, int 
buffer_size)
{

if ((sms_text_length * 7 + 7) / 8 > buffer_size)
    return -1;

int output_buffer_length = 0;
int carry_on_bits = 1;
int i = 0;

for (; i < sms_text_length - 1; ++i) {
    output_buffer[output_buffer_length++] =
        ((sms_text[i] & BITMASK_7BITS) >> (carry_on_bits - 1)) |
        ((sms_text[i + 1] & BITMASK_7BITS) << (8 - carry_on_bits));
    carry_on_bits++;
    if (carry_on_bits == 8) {
        carry_on_bits = 1;
        ++i;
    }
}


if (i < sms_text_length)
    output_buffer[output_buffer_length++] = (sms_text[i] & BITMASK_7BITS) >> (carry_on_bits - 1);

    //printf("hex value = %c", sms_text_length);
                    printf("hex value for message = ");
    for(int a=0; a < output_buffer_length+1; a++)
    {
      printf("%x", output_buffer[a]);
    }

return output_buffer_length;
}

// Encode a digit based phone number for SMS based format.
static int
EncodePhoneNumber(const char* phone_number, unsigned char* output_buffer, int buffer_size)
{
int output_buffer_length = 0;  
const int phone_number_length = strlen(phone_number);

// Check if the output buffer is big enough.
if ((phone_number_length + 1) / 2 > buffer_size)
    return -1;

int i = 0;
for (; i < phone_number_length; ++i) {

    if (phone_number[i] < '0' && phone_number[i] > '9')
        return -1;

    if (i % 2 == 0) {
        output_buffer[output_buffer_length++] = BITMASK_HIGH_4BITS | (phone_number[i] - '0');
    }

            else {
        output_buffer[output_buffer_length - 1] =
            (output_buffer[output_buffer_length - 1] & BITMASK_LOW_4BITS) |
            ((phone_number[i] - '0') << 4); 
    }

}


                   printf("hex value for ph = ");
    for(int b=0; b < output_buffer_length; b++)
    {
      printf("%02x", output_buffer[b]);
    }

return output_buffer_length;
}



// Encode a SMS message to PDU
int
pdu_encode(const char* service_center_number, const char* phone_number, const char* sms_text,
   unsigned char* output_buffer, int buffer_size)
{   
if (buffer_size < 2)
    return -1;

int output_buffer_length = 0;

// 1. Set SMS center number.
int length = 0;
if (service_center_number && strlen(service_center_number) > 0) {
    output_buffer[1] = TYPE_OF_ADDRESS_INTERNATIONAL_PHONE;
    length = EncodePhoneNumber(service_center_number,
                   output_buffer + 2, buffer_size - 2);
    if (length < 0 && length >= 254)
        return -1;
    length++;  // Add type of address.
}
output_buffer[0] = length;
output_buffer_length = length + 1;
if (output_buffer_length + 4 > buffer_size)
    return -1;  // Check if it has space for four more bytes.

// 2. Set type of message.
output_buffer[output_buffer_length++] = SMS_SUBMIT;
output_buffer[output_buffer_length++] = 0x00;  // Message reference.

// 3. Set phone number.
output_buffer[output_buffer_length] = strlen(phone_number);
output_buffer[output_buffer_length + 1] = TYPE_OF_ADDRESS_INTERNATIONAL_PHONE;
length = EncodePhoneNumber(phone_number,
               output_buffer + output_buffer_length + 2,
               buffer_size - output_buffer_length - 2);
output_buffer_length += length + 2;
if (output_buffer_length + 4 > buffer_size)
    return -1;  // Check if it has space for four more bytes.


// 4. Protocol identifiers.
output_buffer[output_buffer_length++] = 0x00;  // TP-PID: Protocol identifier.
output_buffer[output_buffer_length++] = 0x00;  // TP-DCS: Data coding scheme.
output_buffer[output_buffer_length++] = 0xB0;  // TP-VP: Validity: 10 days

// 5. SMS message.
const int sms_text_length = strlen(sms_text);
if (sms_text_length > SMS_MAX_7BIT_TEXT_LENGTH)
    return -1;
output_buffer[output_buffer_length++] = sms_text_length;
length = EncodePDUMessage(sms_text, sms_text_length,
              output_buffer + output_buffer_length, 
              buffer_size - output_buffer_length);
if (length < 0)
    return -1;
output_buffer_length += length;

return output_buffer_length;
}

int main()
{
int len;
const char* service_center_number = "44004400440";
const char* phone_number = "12345678901";
const char* text = "@, é, è, à";
        unsigned char buf[SMS_MAX_PDU_LENGTH];
    len = pdu_encode(service_center_number, phone_number, text, buf, SMS_MAX_PDU_LENGTH);
    printf("length = %d\n", len);
    printf("hex value = ");
    for(int t=0; t < len; t++)
    {
      printf("%02X", buf[t]);
    }


return 0;
}

来源:https://stackoverflow.com/questions/59089873/sms-pdu-encoding-for-characters-like-%c3%a9-%c3%a8-%c3%a0

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!