From f97cd9672d2234fcfa25a691bf8e9291eea97885 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 23 Jan 2021 21:52:25 +0100 Subject: [PATCH] charset: Fix padding of USSD messages in 7bit GSM alphabet USSD messages are sent in pages of 82 bytes, and there is no way to indicate a shorter payload length inside the page. Hence, we always must pad up to the end of the page, using characters. Change-Id: I9950431e920579e6c3a0d12348573f51d21739ec --- src/charset.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/charset.c b/src/charset.c index 444743b..efaff8e 100644 --- a/src/charset.c +++ b/src/charset.c @@ -26,13 +26,40 @@ #include "charset.h" +/* pad the entire "remainder" of a buffer with repeated instances of the given pad character */ +static void pad_with_septets(uint8_t *buf, size_t buf_len, int num_septets, char pad_char) +{ + unsigned int bit_offset; + + for (bit_offset = num_septets * 7; bit_offset + 7 <= buf_len * 8; bit_offset += 7) { + unsigned int byte_offset = bit_offset / 8; + unsigned int bits = bit_offset % 8; + + /* put one more septet */ + buf[byte_offset] |= ((pad_char << bits) & 0xff); + if (bits > 1) + buf[byte_offset+1] = (pad_char) >> (8-bits); + } +} + + /* return number of output bytes written */ int charset_utf8_to_gsm7(uint8_t *out, size_t out_len, const char *in, size_t in_len) { - int octets; + int octets, num_septets, num_bits, num_bytes_used; + /* FIXME: implement this for 'escape' characters outside 7bit alphabet */ - gsm_7bit_encode_n_ussd(out, out_len, in, &octets); - return octets; + num_septets = gsm_7bit_encode_n(out, out_len, in, &octets); + num_bits = num_septets * 7; + + /* we need to pad the entire remainder of the message with */ + pad_with_septets(out, out_len, num_septets, '\r'); + + /* return actual number of output octets used, excluding any padding */ + num_bytes_used = num_bits/8; + if (num_bits % 8) + num_bytes_used++; + return num_bytes_used; } /* return number of output bytes written */