diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-11-17 08:42:05 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2016-01-15 14:46:19 +0100 |
commit | 8114294bf29ac6e44822c0ae43d4b0819f11b022 (patch) | |
tree | 5d065eccbb2b24bc7cdf674676e2d44ff2cc43c9 /src/gsm | |
parent | 51660a6adefd59081f7f2883d76a875e8b2e89c9 (diff) |
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
Diffstat (limited to 'src/gsm')
-rw-r--r-- | src/gsm/apn.c | 75 | ||||
-rw-r--r-- | src/gsm/libosmogsm.map | 2 |
2 files changed, 77 insertions, 0 deletions
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: *; }; |