aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-06-17 08:23:04 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2014-04-06 08:58:10 +0200
commit962553c63f6935f925d0ee2576d77814a32564a7 (patch)
tree97ac19d74140769b846f718e34a5f332114e4e07
parent5996ab8592111b88deb0e9dc7361e098584cfca5 (diff)
Add test case for successful handover and unsuccessful handover
-rw-r--r--.gitignore1
-rw-r--r--configure.ac1
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/handover/Makefile.am8
-rw-r--r--tests/handover/handover_test.c277
-rw-r--r--tests/handover/handover_test.ok1
-rw-r--r--tests/testsuite.at6
7 files changed, 295 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index b9af5cf8..c5ade3a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,7 @@ tests/paging/paging_test
tests/cipher/cipher_test
tests/sysmobts/sysmobts_test
tests/bursts/bursts_test
+tests/handover/handover_test
tests/testsuite
tests/testsuite.log
diff --git a/configure.ac b/configure.ac
index 33359c13..3179260e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -86,4 +86,5 @@ AC_OUTPUT(
tests/cipher/Makefile
tests/sysmobts/Makefile
tests/bursts/Makefile
+ tests/handover/Makefile
Makefile)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2b0e2fa3..67dca694 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = paging cipher sysmobts agch bursts
+SUBDIRS = paging cipher sysmobts agch bursts handover
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
$(srcdir)/package.m4: $(top_srcdir)/configure.ac
diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am
new file mode 100644
index 00000000..a07a527d
--- /dev/null
+++ b/tests/handover/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR)
+AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS)$(LIBOSMOTRAU_CFLAGS)
+LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS)
+noinst_PROGRAMS = handover_test
+EXTRA_DIST = handover_test.ok
+
+handover_test_SOURCES = handover_test.c
+handover_test_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD)
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
new file mode 100644
index 00000000..ed4bedd0
--- /dev/null
+++ b/tests/handover/handover_test.c
@@ -0,0 +1,277 @@
+#include <stdint.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <sched.h>
+#include <sys/signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/application.h>
+#include <osmocom/vty/telnet_interface.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/core/gsmtap.h>
+#include <osmocom/core/gsmtap_util.h>
+#include <osmocom/core/bits.h>
+#include <osmocom/core/backtrace.h>
+#include <osmocom/abis/abis.h>
+
+#include <osmo-bts/gsm_data.h>
+#include <osmo-bts/logging.h>
+#include <osmo-bts/abis.h>
+#include <osmo-bts/bts.h>
+#include <osmo-bts/vty.h>
+#include <osmo-bts/bts_model.h>
+#include <osmo-bts/pcu_if.h>
+#include <osmo-bts/l1sap.h>
+#include <osmo-bts/handover.h>
+
+uint8_t phys_info[] = { 0x03, 0x03, 0x0d, 0x06, 0x2d, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b };
+
+static struct gsm_bts *bts;
+struct gsm_bts_trx *trx;
+int quit = 0;
+uint8_t abis_mac[6] = { 0, 1, 2, 3, 4, 5 };
+const int pcu_direct = 0;
+int modify_count = 0;
+
+static void expect_phys_info(struct lapdm_entity *le)
+{
+ struct osmo_phsap_prim pp;
+ int rc;
+
+ rc = lapdm_phsap_dequeue_prim(le, &pp);
+ OSMO_ASSERT(rc == 0);
+ OSMO_ASSERT(sizeof(phys_info) == pp.oph.msg->len);
+ OSMO_ASSERT(!memcmp(phys_info, pp.oph.msg->data, pp.oph.msg->len));
+ msgb_free(pp.oph.msg);
+}
+
+int main(int argc, char **argv)
+{
+ struct gsm_bts_role_bts *btsb;
+ void *tall_bts_ctx;
+ void *tall_msgb_ctx;
+ struct e1inp_line *line;
+ struct gsm_lchan *lchan;
+ struct osmo_phsap_prim nl1sap;
+ struct msgb *msg;
+ struct abis_rsl_dchan_hdr *rslh;
+ int i;
+
+ tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context");
+ tall_msgb_ctx = talloc_named_const(tall_bts_ctx, 1, "msgb");
+ msgb_set_talloc_ctx(tall_msgb_ctx);
+
+ bts_log_init(NULL);
+ osmo_stderr_target->categories[DHO].loglevel = LOGL_DEBUG;
+
+ bts = gsm_bts_alloc(tall_bts_ctx);
+ if (!bts) {
+ fprintf(stderr, "Failed to create BTS structure\n");
+ exit(1);
+ }
+ trx = gsm_bts_trx_alloc(bts);
+ if (!trx) {
+ fprintf(stderr, "Failed to TRX structure\n");
+ exit(1);
+ }
+
+ if (bts_init(bts) < 0) {
+ fprintf(stderr, "unable to to open bts\n");
+ exit(1);
+ }
+
+ btsb = bts_role_bts(bts);
+
+ libosmo_abis_init(NULL);
+
+ line = e1inp_line_create(0, "ipa");
+ OSMO_ASSERT(line);
+
+ e1inp_ts_config_sign(&line->ts[E1INP_SIGN_RSL-1], line);
+ trx->rsl_link = e1inp_sign_link_create(&line->ts[E1INP_SIGN_RSL-1], E1INP_SIGN_RSL, NULL, 0, 0);
+ OSMO_ASSERT(trx->rsl_link);
+ trx->rsl_link->trx = trx;
+
+ fprintf(stderr, "test 1: without timeout\n");
+
+ /* create two lchans for handover */
+ lchan = &trx->ts[1].lchan[0];
+ l1sap_chan_act(lchan->ts->trx, 0x09, NULL);
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ho.active = HANDOVER_ENABLED;
+ lchan->ho.ref = 23;
+ l1sap_chan_act(lchan->ts->trx, 0x0a, NULL);
+ OSMO_ASSERT(msgb_dequeue(&trx->rsl_link->tx_list));
+ OSMO_ASSERT(msgb_dequeue(&trx->rsl_link->tx_list));
+ OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list));
+
+ /* send access burst with wrong ref */
+ memset(&nl1sap, 0, sizeof(nl1sap));
+ osmo_prim_init(&nl1sap.oph, SAP_GSM_PH, PRIM_PH_RACH, PRIM_OP_INDICATION, NULL);
+ nl1sap.u.rach_ind.chan_nr = 0x0a;
+ nl1sap.u.rach_ind.ra = 42;
+ l1sap_up(trx, &nl1sap);
+
+ /* expect no action */
+ OSMO_ASSERT(modify_count == 0);
+ OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list));
+
+ /* send access burst with correct ref */
+ nl1sap.u.rach_ind.ra = 23;
+ l1sap_up(trx, &nl1sap);
+ OSMO_ASSERT(modify_count == 1);
+
+ /* expect PHYS INFO */
+ expect_phys_info(&trx->ts[2].lchan[0].lapdm_ch.lapdm_dcch);
+
+ /* expect exactly one HO.DET */
+ OSMO_ASSERT(msg = msgb_dequeue(&trx->rsl_link->tx_list));
+ rslh = msgb_l2(msg);
+ OSMO_ASSERT(rslh->c.msg_type == RSL_MT_HANDO_DET);
+ OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list));
+
+ /* expect T3105 running */
+ OSMO_ASSERT(osmo_timer_pending(&trx->ts[2].lchan[0].ho.t3105))
+
+ /* indicate frame */
+ handover_frame(&trx->ts[2].lchan[0]);
+
+ /* expect T3105 not running */
+ OSMO_ASSERT(!osmo_timer_pending(&trx->ts[2].lchan[0].ho.t3105))
+
+ fprintf(stderr, "test 2: with timeout\n");
+
+ /* enable handover again */
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ho.active = HANDOVER_ENABLED;
+ lchan->ho.ref = 23;
+ modify_count = 0;
+
+ /* send access burst with correct ref */
+ nl1sap.u.rach_ind.ra = 23;
+ l1sap_up(trx, &nl1sap);
+ OSMO_ASSERT(modify_count == 1);
+
+ /* expect PHYS INFO */
+ expect_phys_info(&trx->ts[2].lchan[0].lapdm_ch.lapdm_dcch);
+
+ /* expect exactly one HO.DET */
+ OSMO_ASSERT(msg = msgb_dequeue(&trx->rsl_link->tx_list));
+ rslh = msgb_l2(msg);
+ OSMO_ASSERT(rslh->c.msg_type == RSL_MT_HANDO_DET);
+ OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list));
+
+ for (i = 0; i < btsb->ny1 - 1; i++) {
+ /* expect T3105 running */
+ OSMO_ASSERT(osmo_timer_pending(&trx->ts[2].lchan[0].ho.t3105))
+
+ /* timeout T3105 */
+ gettimeofday(&trx->ts[2].lchan[0].ho.t3105.timeout, NULL);
+ osmo_select_main(0);
+
+ /* expect PHYS INFO */
+ expect_phys_info(&trx->ts[2].lchan[0].lapdm_ch.lapdm_dcch);
+ }
+
+ /* timeout T3105 */
+ gettimeofday(&trx->ts[2].lchan[0].ho.t3105.timeout, NULL);
+ osmo_select_main(0);
+
+ /* expect T3105 not running */
+ OSMO_ASSERT(!osmo_timer_pending(&trx->ts[2].lchan[0].ho.t3105))
+
+ /* expect exactly one CONN.FAIL */
+ OSMO_ASSERT(msg = msgb_dequeue(&trx->rsl_link->tx_list));
+ rslh = msgb_l2(msg);
+ OSMO_ASSERT(rslh->c.msg_type == RSL_MT_CONN_FAIL);
+ OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list));
+
+#if 0
+ while (!quit) {
+ log_reset_context();
+ osmo_select_main(0);
+ }
+#endif
+
+ printf("Success\n");
+
+ return 0;
+}
+
+void bts_model_abis_close(struct gsm_bts *bts)
+{
+}
+
+int bts_model_oml_estab(struct gsm_bts *bts)
+{
+ return 0;
+}
+
+int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
+{
+ int rc = 0;
+ uint8_t chan_nr;
+ uint8_t tn, ss;
+ struct gsm_lchan *lchan;
+ struct msgb *msg = l1sap->oph.msg;
+ struct osmo_phsap_prim nl1sap;
+
+ switch (OSMO_PRIM_HDR(&l1sap->oph)) {
+ case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST):
+ switch (l1sap->u.info.type) {
+ case PRIM_INFO_ACTIVATE:
+ chan_nr = l1sap->u.info.u.act_req.chan_nr;
+ tn = L1SAP_CHAN2TS(chan_nr);
+ ss = l1sap_chan2ss(chan_nr);
+ lchan = &trx->ts[tn].lchan[ss];
+
+ lchan_init_lapdm(lchan);
+
+ lchan_set_state(lchan, LCHAN_S_ACTIVE);
+
+ memset(&nl1sap, 0, sizeof(nl1sap));
+ osmo_prim_init(&nl1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, PRIM_OP_CONFIRM, NULL);
+ nl1sap.u.info.type = PRIM_INFO_ACTIVATE;
+ nl1sap.u.info.u.act_cnf.chan_nr = chan_nr;
+ return l1sap_up(trx, &nl1sap);
+ case PRIM_INFO_MODIFY:
+ modify_count++;
+ break;
+ default:
+ LOGP(DL1C, LOGL_NOTICE, "unknown MPH-INFO.req %d\n",
+ l1sap->u.info.type);
+ rc = -EINVAL;
+ goto done;
+ }
+ break;
+ default:
+ LOGP(DL1C, LOGL_NOTICE, "unknown prim %d op %d\n",
+ l1sap->oph.primitive, l1sap->oph.operation);
+ rc = -EINVAL;
+ goto done;
+ }
+
+done:
+ if (msg)
+ msgb_free(msg);
+ return rc;
+}
+
+int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, struct tlv_parsed *old_attr, struct tlv_parsed *new_attr, void *obj) { return 0; }
+int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, struct tlv_parsed *new_attr, int obj_kind, void *obj) { return 0; }
+int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) { return 0; }
+int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj, uint8_t adm_state) { return 0; }
+int bts_model_init(struct gsm_bts *bts) { return 0; }
+int bts_model_trx_deact_rf(struct gsm_bts_trx *trx) { return 0; }
+int bts_model_trx_close(struct gsm_bts_trx *trx) { return 0; }
+void trx_get_hlayer1(void) {}
diff --git a/tests/handover/handover_test.ok b/tests/handover/handover_test.ok
new file mode 100644
index 00000000..35821117
--- /dev/null
+++ b/tests/handover/handover_test.ok
@@ -0,0 +1 @@
+Success
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 9fbc356b..427a9792 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -24,3 +24,9 @@ AT_KEYWORDS([bursts])
cat $abs_srcdir/bursts/bursts_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/bursts/bursts_test], [], [expout], [ignore])
AT_CLEANUP
+
+AT_SETUP([handover])
+AT_KEYWORDS([handover])
+cat $abs_srcdir/handover/handover_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/handover/handover_test], [], [expout], [ignore])
+AT_CLEANUP