问题
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