summaryrefslogtreecommitdiffstats
path: root/src/gsm
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-11-17 08:42:05 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-01-15 14:46:19 +0100
commit8114294bf29ac6e44822c0ae43d4b0819f11b022 (patch)
tree5d065eccbb2b24bc7cdf674676e2d44ff2cc43c9 /src/gsm
parent51660a6adefd59081f7f2883d76a875e8b2e89c9 (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.c75
-rw-r--r--src/gsm/libosmogsm.map2
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: *;
};