aboutsummaryrefslogtreecommitdiffstats
path: root/tests/handover/handover_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/handover/handover_test.c')
-rw-r--r--tests/handover/handover_test.c127
1 files changed, 59 insertions, 68 deletions
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index 769fd06..ca3fc6e 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -32,7 +32,8 @@
#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_cfg.h>
@@ -41,58 +42,31 @@
#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/mgw_endpoint_fsm.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,14 +199,14 @@ 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;
}
@@ -243,18 +217,14 @@ void create_conn(struct gsm_lchan *lchan)
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");
lchan->conn = conn;
conn->lchan = lchan;
@@ -274,13 +244,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_ACTIVE;
+ lchan->ts->fi->state = TS_ST_IN_USE;
+ LOG_LCHAN(lchan, LOGL_DEBUG, "activated by handover_test.c");
+
create_conn(lchan);
if (!strcasecmp(codec, "FR") && full_rate)
lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
@@ -305,7 +279,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;
}
@@ -1336,6 +1309,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 +1365,14 @@ 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);
+ mgw_endpoint_fsm_init(bsc_gsmnet->T_defs);
+
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 +1417,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;
@@ -1677,7 +1665,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 +1695,14 @@ 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_send_handover_required(struct gsm_lchan *lchan,
+ const struct gsm0808_handover_required *params) { return -EINVAL; }
+int bsc_send_handover_request_ack(struct gsm_subscriber_connection *conn, struct msgb *rr_ho_command)
+{ return 0; }