diff options
-rw-r--r-- | src/gsm/gsm48_ie.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/src/gsm/gsm48_ie.c b/src/gsm/gsm48_ie.c index 0e5f2538..ca6489a9 100644 --- a/src/gsm/gsm48_ie.c +++ b/src/gsm/gsm48_ie.c @@ -55,25 +55,9 @@ int gsm48_decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv, int h_len) { uint8_t in_len = bcd_lv[0]; - int i; - - for (i = 1 + h_len; i <= in_len; i++) { - /* lower nibble */ - output_len--; - if (output_len <= 1) - break; - *output++ = bcd_num_digits[bcd_lv[i] & 0xf]; - - /* higher nibble */ - output_len--; - if (output_len <= 1) - break; - *output++ = bcd_num_digits[bcd_lv[i] >> 4]; - } - if (output_len >= 1) - *output++ = '\0'; - - return 0; + /* Just assume the input buffer is big enough for the length byte and the following data, so pass in_len + 1 for + * the input buffer size. */ + return gsm48_decode_bcd_number2(output, output_len, bcd_lv, in_len + 1, h_len); } /*! Decode a 'called/calling/connect party BCD number' as in 10.5.4.7. @@ -90,17 +74,35 @@ int gsm48_decode_bcd_number2(char *output, size_t output_len, const uint8_t *bcd_lv, size_t input_len, size_t h_len) { - uint8_t len; + uint8_t in_len; + int i; if (output_len < 1) return -ENOSPC; *output = '\0'; if (input_len < 1) return -EIO; - len = bcd_lv[0]; + in_len = bcd_lv[0]; /* len + 1: the BCD length plus the length byte itself must fit in the input buffer. */ - if (input_len < len + 1) + if (input_len < in_len + 1) return -EIO; - return gsm48_decode_bcd_number(output, output_len, bcd_lv, h_len); + + for (i = 1 + h_len; i <= in_len; i++) { + /* lower nibble */ + output_len--; + if (output_len <= 1) + break; + *output++ = bcd_num_digits[bcd_lv[i] & 0xf]; + + /* higher nibble */ + output_len--; + if (output_len <= 1) + break; + *output++ = bcd_num_digits[bcd_lv[i] >> 4]; + } + if (output_len >= 1) + *output++ = '\0'; + + return 0; } /*! convert a single ASCII character to call-control BCD */ |