Add APN utility function to libosmogsm

The current functions are used to 'qualify' an APN from the
user-supplied APN name (name identifier) towards the fully-qualified
APN name which is used in the .grps DNS zone.
diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am
index f119a74..d8aff4a 100644
--- a/src/gsm/Makefile.am
+++ b/src/gsm/Makefile.am
@@ -20,7 +20,7 @@
 			auth_core.c auth_comp128v1.c auth_comp128v23.c \
 			auth_milenage.c milenage/aes-encblock.c \
 			milenage/aes-internal.c milenage/aes-internal-enc.c \
-			milenage/milenage.c gan.c ipa.c gsm0341.c
+			milenage/milenage.c gan.c ipa.c gsm0341.c apn.c
 
 libosmogsm_la_LDFLAGS = $(LTLDFLAGS_OSMOGSM) -version-info $(LIBVERSION) -no-undefined
 libosmogsm_la_LIBADD = $(top_builddir)/src/libosmocore.la
diff --git a/src/gsm/apn.c b/src/gsm/apn.c
new file mode 100644
index 0000000..413130a
--- /dev/null
+++ b/src/gsm/apn.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <osmocom/gsm/apn.h>
+
+#define APN_OI_GPRS_FMT	"mnc%03u.mcc%03u.gprs"
+#define APN_GPRS_FMT	"%s.mnc%03u.mcc%03u.gprs"
+
+static char apn_strbuf[APN_MAXLEN+1];
+
+char *osmo_apn_qualify(unsigned int mcc, unsigned int mnc, const char *ni)
+{
+	snprintf(apn_strbuf, sizeof(apn_strbuf)-1, APN_GPRS_FMT,
+		ni, mnc, mcc);
+	apn_strbuf[sizeof(apn_strbuf)-1] = '\0';
+
+	return apn_strbuf;
+}
+
+char *osmo_apn_qualify_from_imsi(const char *imsi,
+				 const char *ni, int have_3dig_mnc)
+{
+	char cbuf[3+1], nbuf[3+1];
+
+	strncpy(cbuf, imsi, 3);
+	cbuf[3] = '\0';
+
+	if (have_3dig_mnc) {
+		strncpy(nbuf, imsi+3, 3);
+		nbuf[3] = '\0';
+	} else {
+		strncpy(nbuf, imsi+3, 2);
+		nbuf[2] = '\0';
+	}
+	return osmo_apn_qualify(atoi(cbuf), atoi(nbuf), ni);
+}
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index b7c5158..22428a2 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -265,5 +265,8 @@
 ipa_prepend_header_ext;
 ipa_send;
 
+osmo_apn_qualify;
+osmo_apn_qualify_from_imsi;
+
 local: *;
 };