From 8114294bf29ac6e44822c0ae43d4b0819f11b022 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 17 Nov 2015 08:42:05 +0100 Subject: gsm: Add APN conversion functions These functions are currently part of openbsc but also needed by other projects. The function have been renamed as follows: gprs_apn_to_str -> osmo_apn_to_str gprs_str_to_apn -> osmo_apn_from_str Sponsored-by: On-Waves ehf --- src/gsm/apn.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/gsm/libosmogsm.map | 2 ++ 2 files changed, 77 insertions(+) (limited to 'src/gsm') diff --git a/src/gsm/apn.c b/src/gsm/apn.c index 413130aa..ccf36b99 100644 --- a/src/gsm/apn.c +++ b/src/gsm/apn.c @@ -36,3 +36,78 @@ char *osmo_apn_qualify_from_imsi(const char *imsi, } return osmo_apn_qualify(atoi(cbuf), atoi(nbuf), ni); } + +/** + * Convert an encoded APN into a dot-separated string. + * + * \param out_str the destination buffer (size must be >= max(app_enc_len,1)) + * \param apn_enc the encoded APN + * \param apn_enc_len the length of the encoded APN + * + * \returns out_str on success and NULL otherwise + */ +char * osmo_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t apn_enc_len) +{ + char *str = out_str; + size_t rest_chars = apn_enc_len; + + while (rest_chars > 0 && apn_enc[0]) { + size_t label_size = apn_enc[0]; + if (label_size + 1 > rest_chars) + return NULL; + + memmove(str, apn_enc + 1, label_size); + str += label_size; + rest_chars -= label_size + 1; + apn_enc += label_size + 1; + + if (rest_chars) + *(str++) = '.'; + } + str[0] = '\0'; + + return out_str; +} + +/** + * Convert a dot-separated string into an encoded APN. + * + * \param apn_enc the encoded APN + * \param max_apn_enc_len the size of the apn_enc buffer + * \param str the source string + * + * \returns out_str on success and NULL otherwise + */ +int osmo_apn_from_str(uint8_t *apn_enc, size_t max_apn_enc_len, const char *str) +{ + uint8_t *last_len_field; + int len; + + /* Can we even write the length field to the output? */ + if (max_apn_enc_len == 0) + return -1; + + /* Remember where we need to put the length once we know it */ + last_len_field = apn_enc; + len = 1; + apn_enc += 1; + + while (str[0]) { + if (len >= max_apn_enc_len) + return -1; + + if (str[0] == '.') { + *last_len_field = (apn_enc - last_len_field) - 1; + last_len_field = apn_enc; + } else { + *apn_enc = str[0]; + } + apn_enc += 1; + str += 1; + len += 1; + } + + *last_len_field = (apn_enc - last_len_field) - 1; + + return len; +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 917a77d2..7eebe7f1 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -270,6 +270,8 @@ ipa_send; osmo_apn_qualify; osmo_apn_qualify_from_imsi; +osmo_apn_to_str; +osmo_apn_from_str; local: *; }; -- cgit v1.2.3