aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-05-14 18:14:15 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-07-28 12:18:23 +0200
commit31f525e7560ad13e32cfc5e0b5f1862c0efcb991 (patch)
tree305b224d3e555eb69798d09e0edb269c32699418 /tests
parent596c402835bab2a01fba7d7233512009eb4142f5 (diff)
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs: - timeslot_fsm: handle dynamic timeslots and OML+RSL availability. - lchan_fsm: handle an individual lchan activation, RTP stream and release, signal the appropriate calling FSMs on success, failure, release. - mgw_endpoint_fsm: handle one entire endpoint with several CI. - assignment_fsm: BSSMAP Assignment Request. - handover_fsm: all of intra, inter-MO and inter-MT handover. Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing the maximum amount events (32), and it is more logical to treat assignment, handover and MGW procedures in separate FSMs. - Add logging macros for each FSM type: - LOG_TS() - LOG_LCHAN() - LOG_MGWEP(), LOG_CI() - LOG_ASSIGNMENT() - LOG_HO() These log with the osmo_fsm_inst where present. New style decision: logging without a final newline char is awkward, especially for gsmtap logging and when other logs interleave LOGPC() calls; we have various cases where the final \n goes missing, and also this invokes the log category checking N times instead of once. So I decided to make these macros *always* append a newline, but only if there is no final newline yet. I hope that the compiler optimizes the strlen() of the constant format strings away. Thus I can log with or without typing "\n" and always get an \n termination anyway. General: - replace osmo_timers, state enums and program-wide osmo_signal_dispatch() with dedicated FSM timeouts, states and events. - introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def. These can be used (with some macro magic) to define a state's timeout once, and not make mistakes for each osmo_fsm_inst_state_chg(). Details: bsc_subscr_conn_fsm.c: - move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and mgw_endpoint_fsm. - There is exactly one state for an ongoing Assignment, with all details handled in conn->assignment.fi. The state relies on the assignment_fsm's timeout. - There is one state for an ongoing Handover; except for an incoming Handover from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn are both established. - move bssmap_add_lcls_status() to osmo_bsc_lcls.c abis_rsl.c: - move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in abis_rsl.c - reduce some rsl functions to merely send a message, rename to "_tx_". - rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function. - move all timers and error/release handling away into various FSMs. - tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an lchan passed, but just mode,type that they require. Rename to ipacc_speech_mode*() and ipacc_payload_type(). - add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR message received during BSSMAP Handover Command. - move various logging to LOG_LCHAN() in order to log with the lchan FSM instance. One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging from DRR to DRSL. It might actually make sense to combine those categories. - lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance. - handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's correct). - gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS. assignment_fsm.c: - the Chan Mode Modify in case of re-using the same lchan is not implemented yet, because this was also missing in the previous implementation (OS#3357). osmo_bsc_api.c: - simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv twice, once by member assignment and then again with a memcpy.) - During handover, we used to copy the MR config from the old lchan. Since we may handover between FR and HR, rather set the MR Config anew every time, so that FR rates are always available on FR lchans, and never on HR lchans. Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore), I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore) Change-Id: I82e3f918295daa83274a4cf803f046979f284366
Diffstat (limited to 'tests')
-rw-r--r--tests/abis/abis_test.c1
-rw-r--r--tests/bsc/Makefile.am13
-rw-r--r--tests/bsc/bsc_test.c4
-rw-r--r--tests/codec_pref/codec_pref_test.c4
-rw-r--r--tests/codec_pref/codec_pref_test.ok12
-rw-r--r--tests/gsm0408/gsm0408_test.c2
-rw-r--r--tests/handover/Makefile.am15
-rw-r--r--tests/handover/handover_test.c186
-rw-r--r--tests/handover/neighbor_ident_test.c8
-rw-r--r--tests/nanobts_omlattr/nanobts_omlattr_test.c2
10 files changed, 149 insertions, 98 deletions
diff --git a/tests/abis/abis_test.c b/tests/abis/abis_test.c
index c6f29f577..5102aea6b 100644
--- a/tests/abis/abis_test.c
+++ b/tests/abis/abis_test.c
@@ -188,3 +188,4 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *ne
}
bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts) { return true; }
+void ts_fsm_alloc(struct gsm_bts_trx_ts *ts) {}
diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am
index ce973be19..c8ad0e40a 100644
--- a/tests/bsc/Makefile.am
+++ b/tests/bsc/Makefile.am
@@ -11,6 +11,8 @@ AM_CFLAGS = \
$(LIBOSMOABIS_CFLAGS) \
$(LIBOSMOLEGACYMGCP_CFLAGS) \
$(LIBOSMOSIGTRAN_CFLAGS) \
+ $(LIBOSMOMGCPCLIENT_CFLAGS) \
+ $(LIBOSMOSIGTRAN_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(NULL)
@@ -32,26 +34,15 @@ bsc_test_SOURCES = \
bsc_test_LDADD = \
$(top_builddir)/src/osmo-bsc/abis_nm.o \
- $(top_builddir)/src/osmo-bsc/abis_rsl.o \
$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
- $(top_builddir)/src/osmo-bsc/bsc_api.o \
- $(top_builddir)/src/osmo-bsc/bsc_dyn_ts.o \
$(top_builddir)/src/osmo-bsc/osmo_bsc_filter.o \
- $(top_builddir)/src/osmo-bsc/bsc_rll.o \
$(top_builddir)/src/osmo-bsc/bsc_subscriber.o \
- $(top_builddir)/src/osmo-bsc/chan_alloc.o \
- $(top_builddir)/src/osmo-bsc/gsm_04_08_rr.o \
- $(top_builddir)/src/osmo-bsc/gsm_04_80_utils.o \
$(top_builddir)/src/osmo-bsc/gsm_data.o \
$(top_builddir)/src/osmo-bsc/gsm_timers.o \
$(top_builddir)/src/osmo-bsc/handover_cfg.o \
$(top_builddir)/src/osmo-bsc/handover_logic.o \
$(top_builddir)/src/osmo-bsc/neighbor_ident.o \
$(top_builddir)/src/osmo-bsc/net_init.o \
- $(top_builddir)/src/osmo-bsc/paging.o \
- $(top_builddir)/src/osmo-bsc/pcu_sock.o \
- $(top_builddir)/src/osmo-bsc/rest_octets.o \
- $(top_builddir)/src/osmo-bsc/system_information.o \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOVTY_LIBS) \
diff --git a/tests/bsc/bsc_test.c b/tests/bsc/bsc_test.c
index e4a5ed587..8e88ba82f 100644
--- a/tests/bsc/bsc_test.c
+++ b/tests/bsc/bsc_test.c
@@ -248,7 +248,7 @@ int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
void bsc_cm_update(struct gsm_subscriber_connection *conn,
const uint8_t *cm2, uint8_t cm2_len,
const uint8_t *cm3, uint8_t cm3_len) {}
-void bsc_mr_config(struct gsm_subscriber_connection *conn, struct gsm_lchan *lchan, int full_rate) {}
void gscon_submit_rsl_dtap(struct gsm_subscriber_connection *conn,
struct msgb *msg, int link_id, int allow_sacch) {}
-void gscon_dtap_queue_flush(struct gsm_subscriber_connection *conn, int send) {}
+void ts_fsm_alloc(struct gsm_bts_trx_ts *ts) {}
+void lchan_activate(struct gsm_lchan *lchan, void *info) {}
diff --git a/tests/codec_pref/codec_pref_test.c b/tests/codec_pref/codec_pref_test.c
index 385854f12..0f908e591 100644
--- a/tests/codec_pref/codec_pref_test.c
+++ b/tests/codec_pref/codec_pref_test.c
@@ -329,7 +329,7 @@ static int test_match_codec_pref(const struct gsm0808_channel_type *ct, const st
{
int rc;
unsigned int i;
- int full_rate;
+ bool full_rate;
enum gsm48_chan_mode chan_mode;
printf("Determining channel mode and rate:\n");
@@ -355,7 +355,7 @@ static int test_match_codec_pref(const struct gsm0808_channel_type *ct, const st
printf(" codec->efr=%u\n", bts->codec.efr);
printf(" codec->amr=%u\n", bts->codec.amr);
- rc = match_codec_pref(&full_rate, &chan_mode, ct, scl, msc, bts);
+ rc = match_codec_pref(&chan_mode, &full_rate, ct, scl, msc->audio_support, msc->audio_length, &bts->codec);
printf(" * result: rc=%i, full_rate=%i, chan_mode=%s\n", rc, full_rate, gsm48_chan_mode_name(chan_mode));
printf("\n");
diff --git a/tests/codec_pref/codec_pref_test.ok b/tests/codec_pref/codec_pref_test.ok
index d3cd0285b..3b36ea1c4 100644
--- a/tests/codec_pref/codec_pref_test.ok
+++ b/tests/codec_pref/codec_pref_test.ok
@@ -932,7 +932,7 @@ Determining channel mode and rate:
codec->hr=1
codec->efr=1
codec->amr=1
- * result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
+ * result: rc=-1, full_rate=0, chan_mode=SIGNALLING
Determining channel mode and rate:
* MS: speech codec list (1 items):
@@ -949,7 +949,7 @@ Determining channel mode and rate:
codec->hr=1
codec->efr=1
codec->amr=1
- * result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
+ * result: rc=-1, full_rate=0, chan_mode=SIGNALLING
Determining channel mode and rate:
* MS: speech codec list (1 items):
@@ -965,7 +965,7 @@ Determining channel mode and rate:
codec->hr=1
codec->efr=1
codec->amr=1
- * result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
+ * result: rc=-1, full_rate=0, chan_mode=SIGNALLING
Determining channel mode and rate:
* MS: speech codec list (1 items):
@@ -981,7 +981,7 @@ Determining channel mode and rate:
codec->hr=1
codec->efr=1
codec->amr=1
- * result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
+ * result: rc=-1, full_rate=0, chan_mode=SIGNALLING
Determining channel mode and rate:
* MS: speech codec list (1 items):
@@ -996,7 +996,7 @@ Determining channel mode and rate:
codec->hr=1
codec->efr=1
codec->amr=1
- * result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
+ * result: rc=-1, full_rate=0, chan_mode=SIGNALLING
Determining channel mode and rate:
* MS: speech codec list (5 items):
@@ -1016,6 +1016,6 @@ Determining channel mode and rate:
codec->hr=0
codec->efr=0
codec->amr=1
- * result: rc=-1, full_rate=-1, chan_mode=SIGNALLING
+ * result: rc=-1, full_rate=0, chan_mode=SIGNALLING
Testing execution completed.
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index 9552fb11d..bc2777d3c 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -852,3 +852,5 @@ bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts)
{
return true;
}
+
+void ts_fsm_alloc(struct gsm_bts_trx_ts *ts) {}
diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am
index 6f0fed66c..107a234eb 100644
--- a/tests/handover/Makefile.am
+++ b/tests/handover/Makefile.am
@@ -32,8 +32,9 @@ handover_test_SOURCES = \
handover_test.c \
$(NULL)
-handover_test_LDFLAGS =\
- -Wl,--wrap=abis_rsl_sendmsg,--wrap=mgcp_conn_modify,--wrap=mgcp_conn_delete\
+handover_test_LDFLAGS = \
+ -Wl,--wrap=abis_rsl_sendmsg \
+ -Wl,--wrap=mgw_endpoint_ci_request \
$(NULL)
handover_test_LDADD = \
@@ -41,8 +42,8 @@ handover_test_LDADD = \
$(top_builddir)/src/osmo-bsc/abis_nm.o \
$(top_builddir)/src/osmo-bsc/abis_rsl.o \
$(top_builddir)/src/osmo-bsc/arfcn_range_encode.o \
+ $(top_builddir)/src/osmo-bsc/assignment_fsm.o \
$(top_builddir)/src/osmo-bsc/bsc_api.o \
- $(top_builddir)/src/osmo-bsc/bsc_dyn_ts.o \
$(top_builddir)/src/osmo-bsc/bsc_init.o \
$(top_builddir)/src/osmo-bsc/bsc_rll.o \
$(top_builddir)/src/osmo-bsc/bsc_subscr_conn_fsm.o \
@@ -51,6 +52,7 @@ handover_test_LDADD = \
$(top_builddir)/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.o \
$(top_builddir)/src/osmo-bsc/bts_sysmobts.o \
$(top_builddir)/src/osmo-bsc/chan_alloc.o \
+ $(top_builddir)/src/osmo-bsc/codec_pref.o \
$(top_builddir)/src/osmo-bsc/gsm_04_08_rr.o \
$(top_builddir)/src/osmo-bsc/gsm_04_80_utils.o \
$(top_builddir)/src/osmo-bsc/gsm_data.o \
@@ -58,16 +60,21 @@ handover_test_LDADD = \
$(top_builddir)/src/osmo-bsc/handover_cfg.o \
$(top_builddir)/src/osmo-bsc/handover_decision.o \
$(top_builddir)/src/osmo-bsc/handover_decision_2.o \
+ $(top_builddir)/src/osmo-bsc/handover_fsm.o \
$(top_builddir)/src/osmo-bsc/handover_logic.o \
+ $(top_builddir)/src/osmo-bsc/lchan_fsm.o \
+ $(top_builddir)/src/osmo-bsc/lchan_select.o \
$(top_builddir)/src/osmo-bsc/meas_rep.o \
+ $(top_builddir)/src/osmo-bsc/mgw_endpoint_fsm.o \
$(top_builddir)/src/osmo-bsc/neighbor_ident.o \
- $(top_builddir)/src/osmo-bsc/osmo_bsc_lcls.o \
$(top_builddir)/src/osmo-bsc/net_init.o \
+ $(top_builddir)/src/osmo-bsc/osmo_bsc_lcls.o \
$(top_builddir)/src/osmo-bsc/paging.o \
$(top_builddir)/src/osmo-bsc/pcu_sock.o \
$(top_builddir)/src/osmo-bsc/penalty_timers.o \
$(top_builddir)/src/osmo-bsc/rest_octets.o \
$(top_builddir)/src/osmo-bsc/system_information.o \
+ $(top_builddir)/src/osmo-bsc/timeslot_fsm.o \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOABIS_LIBS) \
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index 769fd069e..3a5748e5a 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -32,67 +32,45 @@
#include <osmocom/bsc/abis_rsl.h>
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/bsc_subscriber.h>
-#include <osmocom/bsc/chan_alloc.h>
+#include <osmocom/bsc/lchan_select.h>
+#include <osmocom/bsc/lchan_fsm.h>
#include <osmocom/bsc/handover_decision.h>
#include <osmocom/bsc/system_information.h>
+#include <osmocom/bsc/handover.h>
#include <osmocom/bsc/handover_cfg.h>
#include <osmocom/bsc/handover_decision_2.h>
#include <osmocom/bsc/bss.h>
#include <osmocom/bsc/bsc_api.h>
#include <osmocom/bsc/osmo_bsc.h>
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
+#include <osmocom/bsc/timeslot_fsm.h>
+#include <osmocom/bsc/lchan_fsm.h>
+#include <osmocom/bsc/mgw_endpoint_fsm.h>
+#include <osmocom/bsc/handover_fsm.h>
+#include <osmocom/bsc/bsc_msc_data.h>
void *ctx;
struct gsm_network *bsc_gsmnet;
-/* override, requires '-Wl,--wrap=mgcp_conn_modify'.
+/* override, requires '-Wl,--wrap=mgw_endpoint_ci_request'.
* Catch modification of an MGCP connection. */
-int __real_mgcp_conn_modify(struct osmo_fsm_inst *fi, uint32_t parent_evt, struct mgcp_conn_peer *conn_peer);
-int __wrap_mgcp_conn_modify(struct osmo_fsm_inst *fi, uint32_t parent_evt, struct mgcp_conn_peer *conn_peer)
+void __real_mgw_endpoint_ci_request(struct mgwep_ci *ci,
+ enum mgcp_verb verb, const struct mgcp_conn_peer *verb_info,
+ struct osmo_fsm_inst *notify,
+ uint32_t event_success, uint32_t event_failure,
+ void *notify_data);
+void __wrap_mgw_endpoint_ci_request(struct mgwep_ci *ci,
+ enum mgcp_verb verb, const struct mgcp_conn_peer *verb_info,
+ struct osmo_fsm_inst *notify,
+ uint32_t event_success, uint32_t event_failure,
+ void *notify_data)
{
- /* CAUTION HACK:
- *
- * The pointer fi is misused to pass a reference to GSCON FSM !
- *
- * This function is called from gscon_fsm_wait_ho_compl() from
- * bsc_subscr_conn_fsm.c when GSCON_EV_HO_COMPL is dispatched to the
- * GSCON FSM. By then, the GSCON FSM has already changed to the state
- * ST_WAIT_MDCX_BTS_HO (see gscon_fsm_wait_mdcx_bts_ho()) and waits for
- * GSCON_EV_MGW_MDCX_RESP_BTS. The signal GSCON_EV_MGW_MDCX_RESP_BTS
- * is sent to this function using the parameter parent_evt. So we
- * implicitly know the event that is needed to simulate a successful
- * MGW negotiation to the GSCON FSM. All we need to do is to dispatch
- * parent_evt back to the GSCON FSM in order to make it think that the
- * MGW negotiation is done.
- *
- * Unfortunately, there is a problem with this test implementation.
- * in order to simplfy the test we do not allocate any MGCP Client
- * FSM but the GSCON FSM will call this function with the fi pointer
- * pointing to the MGCP Client FSM. This means we get a nullpointer
- * here and there is no way to distinguish which GSCON FSM called
- * the function at all (normally we would know through the parent
- * pointer).
- *
- * To get around this problem we populate the fi pointer with the
- * reference to the GSCON FSM itsself, so we can know who called the
- * function. This is a misuse of the pointer since it normally would
- * hold an MGCP Client FSM instead of a GSCON FSM.
- *
- * See also note in function create_conn() */
-
- osmo_fsm_inst_dispatch(fi, parent_evt, NULL);
- return 0;
-}
-
-/* override, requires '-Wl,--wrap=mgcp_conn_delete'.
- * Catch deletion of an MGCP connection. */
-int __real_mgcp_conn_delete(struct osmo_fsm_inst *fi);
-int __wrap_mgcp_conn_delete(struct osmo_fsm_inst *fi)
-{
- /* Just do nothing and pretend that everything went well.
- * We never have allocatec any MGCP connections. */
- return 0;
+ struct mgcp_conn_peer fake_data = {};
+ /* All MGCP shall be successful */
+ if (!notify)
+ return;
+ osmo_fsm_inst_dispatch(notify, event_success, &fake_data);
}
/* measurement report */
@@ -225,36 +203,34 @@ static struct gsm_bts *create_bts(int arfcn)
/* 4 full rate and 4 half rate channels */
for (i = 1; i <= 6; i++) {
- bts->c0->ts[i].pchan =
- (i < 5) ? GSM_PCHAN_TCH_F : GSM_PCHAN_TCH_H;
+ bts->c0->ts[i].pchan_from_config = (i < 5) ? GSM_PCHAN_TCH_F : GSM_PCHAN_TCH_H;
bts->c0->ts[i].mo.nm_state.operational = NM_OPSTATE_ENABLED;
bts->c0->ts[i].mo.nm_state.availability = NM_AVSTATE_OK;
- bts->c0->ts[i].lchan[0].type = GSM_LCHAN_NONE;
- bts->c0->ts[i].lchan[0].state = LCHAN_S_NONE;
- bts->c0->ts[i].lchan[1].type = GSM_LCHAN_NONE;
- bts->c0->ts[i].lchan[1].state = LCHAN_S_NONE;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(bts->c0->ts); i++) {
+ /* make sure ts->lchans[] get initialized */
+ osmo_fsm_inst_dispatch(bts->c0->ts[i].fi, TS_EV_OML_READY, 0);
}
return bts;
}
void create_conn(struct gsm_lchan *lchan)
{
+ static struct bsc_msc_data fake_msc_data = {};
static unsigned int next_imsi = 0;
char imsi[sizeof(lchan->conn->bsub->imsi)];
struct gsm_network *net = lchan->ts->trx->bts->network;
struct gsm_subscriber_connection *conn;
+ struct mgcp_client *fake_mgcp_client = (void*)talloc_zero(net, int);
conn = bsc_subscr_con_allocate(net);
- /* CAUTION HACK: When __real_mgcp_conn_modify() is called by the GSCON
- * FSM, then we need to know the reference to caller FSM (GSCON FSM).
- * Unfortunately the function __real_mgcp_conn_modify() is called with
- * fi_bts, which is unpopulated in this setup. The real function would
- * perform the communication with the MGW and then dispatch a signal
- * back to the parent FSM. Since we do not have all that in this setup
- * we populate the fi_bts pointer with a reference to the GSCON FSM in
- * order to have it available later in __real_mgcp_conn_modify(). */
- conn->user_plane.fi_bts = conn->fi;
+ conn->user_plane.mgw_endpoint = mgw_endpoint_alloc(conn->fi,
+ GSCON_EV_FORGET_MGW_ENDPOINT,
+ fake_mgcp_client, "test",
+ "fake endpoint");
+ conn->sccp.msc = &fake_msc_data;
lchan->conn = conn;
conn->lchan = lchan;
@@ -274,13 +250,17 @@ struct gsm_lchan *create_lchan(struct gsm_bts *bts, int full_rate, char *codec)
{
struct gsm_lchan *lchan;
- lchan = lchan_alloc(bts,
- (full_rate) ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H, 0);
+ lchan = lchan_select_by_type(bts, (full_rate) ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H);
if (!lchan) {
printf("No resource for lchan\n");
exit(EXIT_FAILURE);
}
- lchan->state = LCHAN_S_ACTIVE;
+
+ /* serious hack into osmo_fsm */
+ lchan->fi->state = LCHAN_ST_ESTABLISHED;
+ lchan->ts->fi->state = TS_ST_IN_USE;
+ LOG_LCHAN(lchan, LOGL_DEBUG, "activated by handover_test.c\n");
+
create_conn(lchan);
if (!strcasecmp(codec, "FR") && full_rate)
lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
@@ -305,7 +285,6 @@ struct gsm_lchan *create_lchan(struct gsm_bts *bts, int full_rate, char *codec)
},
.len = 5,
};
- lchan->conn->codec_list_present = true;
return lchan;
}
@@ -382,6 +361,27 @@ static void send_chan_act_ack(struct gsm_lchan *lchan, int act)
abis_rsl_rcvmsg(msg);
}
+/* Send RLL Est Ind for SAPI[0] */
+static void send_est_ind(struct gsm_lchan *lchan)
+{
+ struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
+ struct abis_rsl_rll_hdr *rh;
+ uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
+
+ rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
+ rh->c.msg_discr = ABIS_RSL_MDISC_RLL;
+ rh->c.msg_type = RSL_MT_EST_IND;
+ rh->ie_chan = RSL_IE_CHAN_NR;
+ rh->chan_nr = chan_nr;
+ rh->ie_link_id = RSL_IE_LINK_IDENT;
+ rh->link_id = 0x00;
+
+ msg->dst = lchan->ts->trx->bts->c0->rsl_link;
+ msg->l2h = (unsigned char *)rh;
+
+ abis_rsl_rcvmsg(msg);
+}
+
/* send handover complete */
static void send_ho_complete(struct gsm_lchan *lchan, bool success)
{
@@ -392,6 +392,8 @@ static void send_ho_complete(struct gsm_lchan *lchan, bool success)
struct gsm48_hdr *gh;
struct gsm48_ho_cpl *hc;
+ send_est_ind(lchan);
+
rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
rh->c.msg_discr = ABIS_RSL_MDISC_RLL;
rh->c.msg_type = RSL_MT_DATA_IND;
@@ -1336,6 +1338,18 @@ static const struct log_info_cat log_categories[] = {
.color = "\033[1;35m",
.enabled = 1, .loglevel = LOGL_DEBUG,
},
+ [DRR] = {
+ .name = "DRR",
+ .description = "RR",
+ .color = "\033[1;35m",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+ [DRLL] = {
+ .name = "DRLL",
+ .description = "RLL",
+ .color = "\033[1;35m",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
[DMSC] = {
.name = "DMSC",
.description = "Mobile Switching Center",
@@ -1380,11 +1394,18 @@ int main(int argc, char **argv)
log_set_print_category(osmo_stderr_target, 1);
log_set_print_category_hex(osmo_stderr_target, 0);
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_BASENAME);
+ osmo_fsm_log_addr(false);
bsc_network_alloc();
if (!bsc_gsmnet)
exit(1);
+ ts_fsm_init();
+ lchan_fsm_init();
+ mgw_endpoint_fsm_init(bsc_gsmnet->T_defs);
+ bsc_subscr_conn_fsm_init();
+ handover_fsm_init();
+
ho_set_algorithm(bsc_gsmnet->ho, 2);
ho_set_ho_active(bsc_gsmnet->ho, true);
ho_set_hodec2_as_active(bsc_gsmnet->ho, true);
@@ -1429,7 +1450,7 @@ int main(int argc, char **argv)
for (i = 0; i < n; i++)
bts[bts_num + i] = create_bts(arfcn++);
for (i = 0; i < n; i++) {
- if (gsm_generate_si(bts[bts_num + i], SYSINFO_TYPE_2))
+ if (gsm_generate_si(bts[bts_num + i], SYSINFO_TYPE_2) <= 0)
fprintf(stderr, "Error generating SI2\n");
}
bts_num += n;
@@ -1670,6 +1691,27 @@ int main(int argc, char **argv)
*test_case);
return EXIT_FAILURE;
}
+
+ {
+ /* Help the lchan out of releasing states */
+ struct gsm_bts *bts;
+ llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
+ struct gsm_bts_trx *trx;
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ int ts_nr;
+ for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
+ struct gsm_lchan *lchan;
+ ts_for_each_lchan(lchan, &trx->ts[ts_nr]) {
+
+ if (lchan->fi && lchan->fi->state == LCHAN_ST_WAIT_BEFORE_RF_RELEASE) {
+ osmo_fsm_inst_state_chg(lchan->fi, LCHAN_ST_WAIT_RF_RELEASE_ACK, 0, 0);
+ osmo_fsm_inst_dispatch(lchan->fi, LCHAN_EV_RSL_RF_CHAN_REL_ACK, 0);
+ }
+ }
+ }
+ }
+ }
+ }
}
for (i = 0; i < lchan_num; i++) {
@@ -1677,7 +1719,6 @@ int main(int argc, char **argv)
lchan[i]->conn = NULL;
conn->lchan = NULL;
osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_REGULAR, NULL);
- lchan_free(lchan[i]);
}
fprintf(stderr, "--------------------\n");
@@ -1708,10 +1749,17 @@ int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, uint1
{ return 0; }
void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) {}
void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause) {}
-void bsc_assign_fail(struct gsm_subscriber_connection *conn, uint8_t cause, uint8_t *rr_cause) {}
int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
{ return 0; }
void bsc_cm_update(struct gsm_subscriber_connection *conn,
const uint8_t *cm2, uint8_t cm2_len,
const uint8_t *cm3, uint8_t cm3_len) {}
-void bsc_mr_config(struct gsm_subscriber_connection *conn, struct gsm_lchan *lchan, int full_rate) {}
+struct gsm0808_handover_required;
+int bsc_tx_bssmap_ho_required(struct gsm_lchan *lchan, const struct gsm0808_cell_id_list2 *target_cells)
+{ return 0; }
+int bsc_tx_bssmap_ho_request_ack(struct gsm_subscriber_connection *conn, struct msgb *rr_ho_command)
+{ return 0; }
+int bsc_tx_bssmap_ho_detect(struct gsm_subscriber_connection *conn) { return 0; }
+enum handover_result bsc_tx_bssmap_ho_complete(struct gsm_subscriber_connection *conn,
+ struct gsm_lchan *lchan) { return HO_RESULT_OK; }
+void bsc_tx_bssmap_ho_failure(struct gsm_subscriber_connection *conn) {}
diff --git a/tests/handover/neighbor_ident_test.c b/tests/handover/neighbor_ident_test.c
index 4eddd4a08..9acbea035 100644
--- a/tests/handover/neighbor_ident_test.c
+++ b/tests/handover/neighbor_ident_test.c
@@ -28,7 +28,7 @@
#include <osmocom/bsc/neighbor_ident.h>
-struct neighbor_ident_list *nil;
+static struct neighbor_ident_list *nil;
static const struct neighbor_ident_key *k(int from_bts, uint16_t arfcn, uint8_t bsic)
{
@@ -105,7 +105,7 @@ static const struct gsm0808_cell_id_list2 lac2 = {
},
};
-void print_cil(const struct gsm0808_cell_id_list2 *cil)
+static void print_cil(const struct gsm0808_cell_id_list2 *cil)
{
unsigned int i;
if (!cil) {
@@ -132,7 +132,7 @@ void print_cil(const struct gsm0808_cell_id_list2 *cil)
static int print_nil_i;
-bool nil_cb(const struct neighbor_ident_key *key, const struct gsm0808_cell_id_list2 *val,
+static bool nil_cb(const struct neighbor_ident_key *key, const struct gsm0808_cell_id_list2 *val,
void *cb_data)
{
printf(" %2d: %s\n", print_nil_i++, neighbor_ident_key_name(key));
@@ -140,7 +140,7 @@ bool nil_cb(const struct neighbor_ident_key *key, const struct gsm0808_cell_id_l
return true;
}
-void print_nil()
+static void print_nil()
{
print_nil_i = 0;
neighbor_ident_iter(nil, nil_cb, NULL);
diff --git a/tests/nanobts_omlattr/nanobts_omlattr_test.c b/tests/nanobts_omlattr/nanobts_omlattr_test.c
index 7a3a80e2d..38729ac35 100644
--- a/tests/nanobts_omlattr/nanobts_omlattr_test.c
+++ b/tests/nanobts_omlattr/nanobts_omlattr_test.c
@@ -317,3 +317,5 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *ne
bool on_gsm_ts_init(struct gsm_bts_trx_ts *ts)
{ return true; }
+
+void ts_fsm_alloc(struct gsm_bts_trx_ts *ts) {}