summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/Makefile.am1
-rw-r--r--include/osmocom/gsm/protocol/gsm_03_40.h32
-rw-r--r--src/gsm/gsm0411_utils.c30
-rw-r--r--tests/sms/sms_test.c44
-rw-r--r--tests/sms/sms_test.ok6
5 files changed, 103 insertions, 10 deletions
diff --git a/include/Makefile.am b/include/Makefile.am
index b1a818d2..42a2dc2b 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -59,6 +59,7 @@ nobase_include_HEADERS = \
osmocom/gsm/mncc.h \
osmocom/gsm/prim.h \
osmocom/gsm/l1sap.h \
+ osmocom/gsm/protocol/gsm_03_40.h \
osmocom/gsm/protocol/gsm_03_41.h \
osmocom/gsm/protocol/gsm_04_08.h \
osmocom/gsm/protocol/gsm_04_11.h \
diff --git a/include/osmocom/gsm/protocol/gsm_03_40.h b/include/osmocom/gsm/protocol/gsm_03_40.h
new file mode 100644
index 00000000..32d5c2c2
--- /dev/null
+++ b/include/osmocom/gsm/protocol/gsm_03_40.h
@@ -0,0 +1,32 @@
+#pragma once
+
+/* GSM TS 03.40 */
+
+/**
+ * 9.1.2.5 Type Of Number
+ */
+enum {
+ GSM340_TYPE_UNKNOWN = 0,
+ GSM340_TYPE_INTERNATIONAL = 1,
+ GSM340_TYPE_NATIONAL = 2,
+ GSM340_TYPE_NETWORK = 3,
+ GSM340_TYPE_SUBSCRIBER = 4,
+ GSM340_TYPE_ALPHA_NUMERIC = 5,
+ GSM340_TYPE_ABBREVIATED = 6,
+ GSM340_TYPE_RESERVED = 7,
+};
+
+/**
+ * 9.1.2.5 Type of Numbering plan.
+ * Applies for numbering plans (Unknown, International, National)
+ */
+enum {
+ GSM340_PLAN_UNKNOWN = 0,
+ GSM340_PLAN_ISDN = 1,
+ GSM340_PLAN_DATA = 3,
+ GSM340_PLAN_TELEX = 4,
+ GSM340_PLAN_NATIONAL = 8,
+ GSM340_PLAN_PRIVATE = 9,
+ GSM340_PLAN_ERMES = 10,
+ GSM340_PLAN_RESERVED = 15,
+};
diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c
index fe69bf41..a8ba810d 100644
--- a/src/gsm/gsm0411_utils.c
+++ b/src/gsm/gsm0411_utils.c
@@ -4,7 +4,7 @@
/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010 by On-Waves
* (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
*
@@ -33,6 +33,8 @@
#include <osmocom/core/logging.h>
#include <osmocom/gsm/gsm48.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/protocol/gsm_03_40.h>
#include <osmocom/gsm/protocol/gsm_04_11.h>
#define GSM411_ALLOC_SIZE 1024
@@ -269,16 +271,26 @@ int gsm340_gen_oa(uint8_t *oa, unsigned int oa_len, uint8_t type,
{
int len_in_bytes;
- /* prevent buffer overflows */
- if (strlen(number) > 20)
- number = "";
-
oa[1] = 0x80 | (type << 4) | plan;
- len_in_bytes = gsm48_encode_bcd_number(oa, oa_len, 1, number);
-
- /* GSM 03.40 tells us the length is in 'useful semi-octets' */
- oa[0] = strlen(number) & 0xff;
+ if (type == GSM340_TYPE_ALPHA_NUMERIC) {
+ /*
+ * TODO/FIXME: what is the 'useful semi-octets' excluding any
+ * semi octet containing only fill bits.
+ * The current code picks the number of bytes written by the
+ * 7bit encoding routines and multiplies it by two.
+ */
+ gsm_7bit_encode_n(&oa[2], oa_len - 2, number, &len_in_bytes);
+ oa[0] = len_in_bytes * 2;
+ len_in_bytes += 2;
+ } else {
+ /* prevent buffer overflows */
+ if (strlen(number) > 20)
+ number = "";
+ len_in_bytes = gsm48_encode_bcd_number(oa, oa_len, 1, number);
+ /* GSM 03.40 tells us the length is in 'useful semi-octets' */
+ oa[0] = strlen(number) & 0xff;
+ }
return len_in_bytes;
}
diff --git a/tests/sms/sms_test.c b/tests/sms/sms_test.c
index 3188a187..a79d4547 100644
--- a/tests/sms/sms_test.c
+++ b/tests/sms/sms_test.c
@@ -22,8 +22,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <osmocom/core/msgb.h>
+
+#include <osmocom/gsm/protocol/gsm_03_40.h>
+
#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/gsm0411_utils.h>
+
+#include <osmocom/core/msgb.h>
#include <osmocom/core/utils.h>
struct test_case {
@@ -222,6 +227,42 @@ static void test_octet_return()
printf("Done\n");
}
+static void test_gen_oa(void)
+{
+ uint8_t oa[12];
+ int len;
+
+ printf("Testing gsm340_gen_oa\n");
+
+ /* first try... */
+ len = gsm340_gen_oa(oa, ARRAY_SIZE(oa), GSM340_TYPE_UNKNOWN,
+ GSM340_PLAN_ISDN, "12345678901234567891");
+ OSMO_ASSERT(len == 12);
+ printf("Result: len(%d) data(%s)\n", len, osmo_hexdump(oa, len));
+ len = gsm340_gen_oa(oa, ARRAY_SIZE(oa), GSM340_TYPE_NATIONAL,
+ GSM340_PLAN_ISDN, "12345678901234567891");
+ OSMO_ASSERT(len == 12);
+ printf("Result: len(%d) data(%s)\n", len, osmo_hexdump(oa, len));
+
+ /* long input.. will fail and just prints the header*/
+ len = gsm340_gen_oa(oa, ARRAY_SIZE(oa), GSM340_TYPE_INTERNATIONAL,
+ GSM340_PLAN_ISDN, "123456789123456789120");
+ OSMO_ASSERT(len == 2);
+ printf("Result: len(%d) data(%s)\n", len, osmo_hexdump(oa, len));
+
+ /* try the alpha numeric encoding */
+ len = gsm340_gen_oa(oa, ARRAY_SIZE(oa), GSM340_TYPE_ALPHA_NUMERIC,
+ GSM340_PLAN_UNKNOWN, "OpenBSC");
+ OSMO_ASSERT(len == 9);
+ printf("Result: len(%d) data(%s)\n", len, osmo_hexdump(oa, len));
+
+ /* long alpha numeric text */
+ len = gsm340_gen_oa(oa, ARRAY_SIZE(oa), GSM340_TYPE_ALPHA_NUMERIC,
+ GSM340_PLAN_UNKNOWN, "OpenBSCabcdefghijklm");
+ OSMO_ASSERT(len == 12);
+ printf("Result: len(%d) data(%s)\n", len, osmo_hexdump(oa, len));
+}
+
int main(int argc, char** argv)
{
printf("SMS testing\n");
@@ -344,6 +385,7 @@ int main(int argc, char** argv)
}
test_octet_return();
+ test_gen_oa();
printf("OK\n");
return 0;
diff --git a/tests/sms/sms_test.ok b/tests/sms/sms_test.ok
index 915a59c8..a71567de 100644
--- a/tests/sms/sms_test.ok
+++ b/tests/sms/sms_test.ok
@@ -12,4 +12,10 @@ Decode case 5: return value 40 (expected 40)
Encoding some tests and printing number of septets/octets
SEPTETS: 8 OCTETS: 7
Done
+Testing gsm340_gen_oa
+Result: len(12) data(14 81 21 43 65 87 09 21 43 65 87 19 )
+Result: len(12) data(14 a1 21 43 65 87 09 21 43 65 87 19 )
+Result: len(2) data(00 91 )
+Result: len(9) data(0e d0 4f 78 d9 2d 9c 0e 01 )
+Result: len(12) data(14 d0 4f 78 d9 2d 9c 0e c3 e2 31 19 )
OK