diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2013-07-07 14:26:32 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2013-07-13 09:15:49 +0200 |
commit | b91cfa4cf9cb7af626abffd8cbd52c80b8eda2cc (patch) | |
tree | 13f53200522a08d085ffc900e04dd0f2f12301a3 /src/gsm/gsm_utils.c | |
parent | c7223231b5398a00496d01609ff92875bf6a7b1b (diff) |
Add special 7-bit encoding and decoding functions for USSD codingjolly/7bit_ussd
Handling 7-bit coding is a little different for USSD, as TS 03.38 states:
To avoid the situation where the receiving entity confuses 7 binary zero pad
bits as the @ character, the carriage return or <CR> character shall be used
for padding in this situation [...].
If <CR> is intended to be the last character and the message (including
the wanted <CR>) ends on an octet boundary, then another <CR> must be
added together with a padding bit 0. The receiving entity will perform
the carriage return function twice, but this will not result in misoperation
as the definition of <CR> [...] is identical to the definition of <CR><CR>.
The receiving entity shall remove the final <CR> character where the
message ends on an octet boundary with <CR> as the last character.
Diffstat (limited to 'src/gsm/gsm_utils.c')
-rw-r--r-- | src/gsm/gsm_utils.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c index 54b965e2..3dd15375 100644 --- a/src/gsm/gsm_utils.c +++ b/src/gsm/gsm_utils.c @@ -172,6 +172,19 @@ int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t septet_l) return gsm_7bit_decode_hdr(text, user_data, septet_l, 0); } +int gsm_7bit_decode_ussd(char *text, const uint8_t *user_data, uint8_t length) +{ + int i; + + gsm_7bit_decode_hdr(text, user_data, length, 0); + i = strlen(text); + /* remove last <CR>, if it fits up to the end of last octet */ + if (i && (user_data[gsm_get_octet_len(length) - 1] >> 1) == '\r') + text[--i] = '\0'; + + return i; +} + /* GSM 03.38 6.2.1 Prepare character packing */ int gsm_septet_encode(uint8_t *result, const char *data) { @@ -254,6 +267,24 @@ int gsm_7bit_encode(uint8_t *result, const char *data) return gsm_7bit_encode_oct(result, data, &out); } +int gsm_7bit_encode_ussd(uint8_t *result, const char *data, int *octets) +{ + int y; + + y = gsm_7bit_encode_oct(result, data, octets); + /* if last octet contains only one bit, add <CR> */ + if (((y * 7) & 7) == 1) + result[(*octets) - 1] |= ('\r' << 1); + /* if last character is <CR> and completely fills last octet, add + * another <CR>. */ + if (y && ((y * 7) & 7) == 0 && (result[(*octets) - 1] >> 1) == '\r') { + result[(*octets)++] = '\r'; + y++; + } + + return y; +} + int gsm_7bit_encode_oct(uint8_t *result, const char *data, int *octets) { int y = 0; |