diff options
-rw-r--r-- | include/Makefile.am | 1 | ||||
-rw-r--r-- | include/osmocom/gsm/protocol/gsm_03_40.h | 32 | ||||
-rw-r--r-- | src/gsm/gsm0411_utils.c | 30 | ||||
-rw-r--r-- | tests/sms/sms_test.c | 44 | ||||
-rw-r--r-- | tests/sms/sms_test.ok | 6 |
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 |