hlr: implement str2apn() to convert an apn as string into octetstring

APN are encoded by splitting each domain part by the dot and prefix
each element by a 8bit length.
E.g. internet -> \x08internet and internet.foo -> \x08internet\x03foo

Change-Id: I607969cd58110d4d5ff1b828e64cf2b5031868ac
diff --git a/hlr/HLR_Tests.ttcn b/hlr/HLR_Tests.ttcn
index 959c680..e10aae4 100644
--- a/hlr/HLR_Tests.ttcn
+++ b/hlr/HLR_Tests.ttcn
@@ -1917,6 +1917,65 @@
 	}
 }
 
+
+/* strchr similar to C's/posix strchr but returns the position of the first matching.
+ * if the char c isn't found it returns -1.
+ */
+function strchr(in charstring s, in charstring c) return integer {
+	for (var integer i := 0; i < lengthof(s); i := i+1) {
+		if (s[i] == c) {
+			return i;
+		}
+	}
+	return -1;
+}
+
+/* str2apn returns octetstring
+ * internet -> '08'O & char2oct("internet")
+ * internet.foo -> '08'O & char2oct("internet") & '03'O & char2oct("foo")
+ * internet.-> '08'O & char2oct("internet")
+ */
+function str2apn(in charstring apn) return octetstring {
+	var octetstring result := ''O;
+	var charstring remain := apn;
+	var integer pos := strchr(remain, ".");
+
+	while (pos != -1) {
+		/* ends on a dot. e.g. "internet.", we must ignore the ending dot and this is then the last element */
+		if (pos == 0) {
+			/* it's not allowed to start with a dot. */
+			return ''O;
+		}
+
+		if (pos + 1 == lengthof(remain)) {
+			/* remove the dot */
+			remain := substr(remain, 0, pos)
+			break;
+		}
+
+		result := result & int2oct(pos, 1) & char2oct(substr(remain, 0, pos));
+		remain := substr(remain, pos + 1, lengthof(remain) - pos - 1);
+		pos := strchr(remain, ".");
+	}
+	/* last element */
+	var integer len := lengthof(remain);
+	result := result & int2oct(len, 1) & char2oct(remain);
+	return result;
+}
+
+private function test_assert(boolean term) {
+	if (term == false) {
+		setverdict(fail, "Values mismatch");
+	}
+}
+
+private function test_str2apn() {
+	test_assert(str2apn("internet") == '08'O & char2oct("internet"));
+	test_assert(str2apn("internet.") == '08'O & char2oct("internet"));
+	test_assert(str2apn("internet.foo") == '08'O & char2oct("internet") & '03'O & char2oct("foo"));
+	test_assert(str2apn(".internet.foo") == ''O);
+}
+
 /* TODO:
   * UL with ISD error
   * UL with ISD timeout