Fix gsm_7bit_{en,de}code function and sms user_data calculations

With the 7bit alphabet the user_data_len field needs to be in
septets (characters) and not in octets occupied.
This commit is contained in:
Daniel Willmann 2009-08-12 21:17:06 +02:00 committed by Harald Welte (local)
parent 7984d5c260
commit 6b1e822611
2 changed files with 38 additions and 31 deletions

View File

@ -315,8 +315,13 @@ static int gsm340_gen_tpdu(struct msgb *msg, struct gsm_sms *sms)
*smsp = sms->user_data_len;
/* generate TP-UD */
smsp = msgb_put(msg, sms->user_data_len);
memcpy(smsp, sms->user_data, sms->user_data_len);
/* FIXME: Handle DSC of UCS2 or 8/bit default */
if (gsm338_get_sms_alphabet(sms->data_coding_scheme) == DCS_7BIT_DEFAULT) {
/* Warning, user_data_len indicates the amount of septets
* (characters), we need amount of octets occupied */
smsp = msgb_put(msg, ceil(sms->user_data_len*7/8.0));
memcpy(smsp, sms->user_data, ceil(sms->user_data_len*7/8.0));
}
return msg->len - old_msg_len;
}

View File

@ -30,48 +30,50 @@
/* GSM 03.38 6.2.1 Charachter packing */
int gsm_7bit_decode(char *text, const u_int8_t *user_data, u_int8_t length)
{
u_int8_t d_off = 0, b_off = 0;
u_int8_t i;
int i = 0;
int l = 0;
for (i=0;i<length;i++) {
text[i] = ((user_data[d_off] + (user_data[d_off+1]<<8)) & (0x7f<<b_off))>>b_off;
b_off += 7;
if (b_off >= 8) {
d_off += 1;
b_off -= 8;
}
}
text[i] = '\0';
return 0;
/* FIXME: We need to account for user data headers here */
i += l;
for (; i < length; i ++)
*(text ++) =
((user_data[(i * 7 + 7) >> 3] <<
(7 - ((i * 7 + 7) & 7))) |
(user_data[(i * 7) >> 3] >>
((i * 7) & 7))) & 0x7f;
*text = '\0';
return i - l;
}
/* GSM 03.38 6.2.1 Charachter packing */
int gsm_7bit_encode(u_int8_t *result, const char *data)
{
int i;
u_int8_t d_off = 0, b_off = 0;
const int length = strlen(data);
int out_length = (length * 8)/7;
int i,j = 0;
unsigned char ch1, ch2;
int shift = 0;
memset(result, 0, out_length);
for ( i=0; i<strlen(data); i++ ) {
for (i = 0; i < length; ++i) {
u_int8_t first = (data[i] & 0x7f) << b_off;
u_int8_t second = (data[i] & 0x7f) >> (8 - b_off);
result[d_off] |= first;
if (second != 0)
result[d_off + 1] = second;
ch1 = data[i] & 0x7F;
ch1 = ch1 >> shift;
ch2 = data[(i+1)] & 0x7F;
ch2 = ch2 << (7-shift);
b_off += 7;
ch1 = ch1 | ch2;
if (b_off >= 8) {
d_off += 1;
b_off -= 8;
result[j++] = ch1;
shift++;
if ((shift == 7) && (i+1<strlen(data))) {
shift = 0;
i++;
}
}
return out_length;
return i;
}
/* determine power control level for given dBm value, as indicated