osmith has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/30271 )
Change subject: tests/handover: move some functions to test/common ......................................................................
tests/handover: move some functions to test/common
Move some of the functions from handover_test.c to test/common.c. This is in preparation for a new lchan_recover test, which will make use of these.
Change-Id: I3df5b26ea3a6da1c1e125e07119a91c7458c6758 --- A tests/common.c A tests/common.h M tests/handover/Makefile.am M tests/handover/handover_test.c 4 files changed, 200 insertions(+), 158 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/71/30271/1
diff --git a/tests/common.c b/tests/common.c new file mode 100644 index 0000000..797dd47 --- /dev/null +++ b/tests/common.c @@ -0,0 +1,188 @@ +/* + * (C) 2013 by Andreas Eversberg jolly@eversberg.eu + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + */ + +#include <stdio.h> +#include <stdbool.h> + +#include <osmocom/core/timer.h> +#include <osmocom/core/utils.h> +#include <osmocom/gsm/gsm_utils.h> + +#include <osmocom/bsc/abis_rsl.h> +#include <osmocom/bsc/bts.h> +#include <osmocom/bsc/gsm_data.h> +#include <osmocom/bsc/system_information.h> +#include <osmocom/bsc/timeslot_fsm.h> + +const struct timeval fake_time_start_time = { 123, 456 }; + +void fake_time_passes(time_t secs, suseconds_t usecs) +{ + struct timeval diff; + /* Add time to osmo_fsm timers, using osmo_gettimeofday() */ + osmo_gettimeofday_override_add(secs, usecs); + /* Add time to penalty timers, using osmo_clock_gettime() */ + osmo_clock_override_add(CLOCK_MONOTONIC, secs, usecs * 1000); + + timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); + fprintf(stderr, "Total time passed: %d.%06d s\n", (int)diff.tv_sec, (int)diff.tv_usec); + + osmo_timers_prepare(); + osmo_timers_update(); +} + +void fake_time_start(void) +{ + struct timespec *clock_override; + + /* osmo_fsm uses osmo_gettimeofday(). To affect FSM timeouts, we need osmo_gettimeofday_override. */ + osmo_gettimeofday_override_time = fake_time_start_time; + osmo_gettimeofday_override = true; + + /* Penalty timers use osmo_clock_gettime(CLOCK_MONOTONIC). To affect these timeouts, we need + * osmo_gettimeofday_override. */ + clock_override = osmo_clock_override_gettimespec(CLOCK_MONOTONIC); + OSMO_ASSERT(clock_override); + clock_override->tv_sec = fake_time_start_time.tv_sec; + clock_override->tv_nsec = fake_time_start_time.tv_usec * 1000; + osmo_clock_override_enable(CLOCK_MONOTONIC, true); + fake_time_passes(0, 0); +} + +enum gsm_phys_chan_config pchan_from_str(const char *str) +{ + enum gsm_phys_chan_config pchan; + if (!strcmp(str, "dyn")) + return GSM_PCHAN_OSMO_DYN; + if (!strcmp(str, "c+s4")) + return GSM_PCHAN_CCCH_SDCCH4; + if (!strcmp(str, "-")) + return GSM_PCHAN_NONE; + pchan = gsm_pchan_parse(str); + if (pchan < 0) { + fprintf(stderr, "Invalid timeslot pchan type: %s\n", str); + exit(1); + } + return pchan; +} + +const char * const bts_default_ts[] = { + "c+s4", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "TCH/H", "TCH/H", "-", +}; + +struct gsm_bts *test_create_bts(void *ctx, int num_trx, const char * const *ts_args, int ts_args_count) +{ + static int arfcn = 870; + static int ci = 0; + struct gsm_bts *bts; + struct e1inp_sign_link *rsl_link; + int i; + int trx_i; + struct gsm_bts_trx *trx; + + fprintf(stderr, "- Creating BTS %d, %d TRX\n", bsc_gsmnet->num_bts, num_trx); + + bts = bsc_bts_alloc_register(bsc_gsmnet, GSM_BTS_TYPE_UNKNOWN, 0x3f); + if (!bts) { + fprintf(stderr, "No resource for bts1\n"); + return NULL; + } + + bts->location_area_code = 0x0017; + bts->cell_identity = ci++; + bts->c0->arfcn = arfcn++; + + bts->codec.efr = 1; + bts->codec.hr = 1; + bts->codec.amr = 1; + + rsl_link = talloc_zero(ctx, struct e1inp_sign_link); + rsl_link->trx = bts->c0; + bts->c0->rsl_link_primary = rsl_link; + + for (trx_i = 0; trx_i < num_trx; trx_i++) { + while (!(trx = gsm_bts_trx_num(bts, trx_i))) + gsm_bts_trx_alloc(bts); + + trx->mo.nm_state.operational = NM_OPSTATE_ENABLED; + trx->mo.nm_state.availability = NM_AVSTATE_OK; + trx->mo.nm_state.administrative = NM_STATE_UNLOCKED; + trx->bb_transc.mo.nm_state.operational = NM_OPSTATE_ENABLED; + trx->bb_transc.mo.nm_state.availability = NM_AVSTATE_OK; + trx->bb_transc.mo.nm_state.administrative = NM_STATE_UNLOCKED; + + /* 4 full rate and 4 half rate channels */ + for (i = 0; i < 8; i++) { + int arg_i = trx_i * 8 + i; + const char *ts_arg; + if (arg_i >= ts_args_count) + ts_arg = bts_default_ts[i]; + else + ts_arg = ts_args[arg_i]; + fprintf(stderr, "\t%s", ts_arg); + trx->ts[i].pchan_from_config = pchan_from_str(ts_arg); + if (trx->ts[i].pchan_from_config == GSM_PCHAN_NONE) + continue; + trx->ts[i].mo.nm_state.operational = NM_OPSTATE_ENABLED; + trx->ts[i].mo.nm_state.availability = NM_AVSTATE_OK; + trx->ts[i].mo.nm_state.administrative = NM_STATE_UNLOCKED; + } + fprintf(stderr, "\n"); + + for (i = 0; i < ARRAY_SIZE(trx->ts); i++) { + /* make sure ts->lchans[] get initialized */ + osmo_fsm_inst_dispatch(trx->ts[i].fi, TS_EV_RSL_READY, 0); + osmo_fsm_inst_dispatch(trx->ts[i].fi, TS_EV_OML_READY, 0); + + /* Unused dyn TS start out as used for PDCH */ + switch (trx->ts[i].pchan_on_init) { + case GSM_PCHAN_OSMO_DYN: + case GSM_PCHAN_TCH_F_PDCH: + ts_set_pchan_is(&trx->ts[i], GSM_PCHAN_PDCH); + break; + default: + break; + } + } + } + + for (i = 0; i < bsc_gsmnet->num_bts; i++) { + if (gsm_generate_si(gsm_bts_num(bsc_gsmnet, i), SYSINFO_TYPE_2) <= 0) + fprintf(stderr, "Error generating SI2\n"); + } + return bts; +} + +/* send channel activation ack */ +void send_chan_act_ack(struct gsm_lchan *lchan, int act) +{ + struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL"); + struct abis_rsl_dchan_hdr *dh; + + dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh)); + dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN; + dh->c.msg_type = (act) ? RSL_MT_CHAN_ACTIV_ACK : RSL_MT_RF_CHAN_REL_ACK; + dh->ie_chan = RSL_IE_CHAN_NR; + dh->chan_nr = gsm_lchan2chan_nr(lchan, true); + + msg->dst = rsl_chan_link(lchan); + msg->l2h = (unsigned char *)dh; + + abis_rsl_rcvmsg(msg); +} diff --git a/tests/common.h b/tests/common.h new file mode 100644 index 0000000..b0d89e4 --- /dev/null +++ b/tests/common.h @@ -0,0 +1,8 @@ +#include <sys/time.h> + +void fake_time_passes(time_t secs, suseconds_t usecs); +void fake_time_start(void); + +struct gsm_bts *test_create_bts(void *ctx, int num_trx, const char * const *ts_args, int ts_args_count); + +void send_chan_act_ack(struct gsm_lchan *lchan, int act); diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am index 123fd61..8dc6882 100644 --- a/tests/handover/Makefile.am +++ b/tests/handover/Makefile.am @@ -31,6 +31,7 @@ $(NULL)
handover_test_SOURCES = \ + ../common.c \ handover_test.c \ $(NULL)
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c index 1e91e66..7c85386 100644 --- a/tests/handover/handover_test.c +++ b/tests/handover/handover_test.c @@ -57,6 +57,7 @@ #include <osmocom/mgcp_client/mgcp_client_pool.h>
#include "../../bscconfig.h" +#include "../common.h"
void *ctx;
@@ -95,41 +96,6 @@ uint8_t bcch_f; };
-const struct timeval fake_time_start_time = { 123, 456 }; - -void fake_time_passes(time_t secs, suseconds_t usecs) -{ - struct timeval diff; - /* Add time to osmo_fsm timers, using osmo_gettimeofday() */ - osmo_gettimeofday_override_add(secs, usecs); - /* Add time to penalty timers, using osmo_clock_gettime() */ - osmo_clock_override_add(CLOCK_MONOTONIC, secs, usecs * 1000); - - timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); - fprintf(stderr, "Total time passed: %d.%06d s\n", (int)diff.tv_sec, (int)diff.tv_usec); - - osmo_timers_prepare(); - osmo_timers_update(); -} - -void fake_time_start() -{ - struct timespec *clock_override; - - /* osmo_fsm uses osmo_gettimeofday(). To affect FSM timeouts, we need osmo_gettimeofday_override. */ - osmo_gettimeofday_override_time = fake_time_start_time; - osmo_gettimeofday_override = true; - - /* Penalty timers use osmo_clock_gettime(CLOCK_MONOTONIC). To affect these timeouts, we need - * osmo_gettimeofday_override. */ - clock_override = osmo_clock_override_gettimespec(CLOCK_MONOTONIC); - OSMO_ASSERT(clock_override); - clock_override->tv_sec = fake_time_start_time.tv_sec; - clock_override->tv_nsec = fake_time_start_time.tv_usec * 1000; - osmo_clock_override_enable(CLOCK_MONOTONIC, true); - fake_time_passes(0, 0); -} - static void gen_meas_rep(struct gsm_lchan *lchan, uint8_t bs_power_db, uint8_t rxlev, uint8_t rxqual, uint8_t ta, int neighbors_count, struct neighbor_meas *neighbors) @@ -219,109 +185,6 @@ abis_rsl_rcvmsg(msg); }
-enum gsm_phys_chan_config pchan_from_str(const char *str) -{ - enum gsm_phys_chan_config pchan; - if (!strcmp(str, "dyn")) - return GSM_PCHAN_OSMO_DYN; - if (!strcmp(str, "c+s4")) - return GSM_PCHAN_CCCH_SDCCH4; - if (!strcmp(str, "-")) - return GSM_PCHAN_NONE; - pchan = gsm_pchan_parse(str); - if (pchan < 0) { - fprintf(stderr, "Invalid timeslot pchan type: %s\n", str); - exit(1); - } - return pchan; -} - -const char * const bts_default_ts[] = { - "c+s4", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "TCH/H", "TCH/H", "-", -}; - -static struct gsm_bts *_create_bts(int num_trx, const char * const *ts_args, int ts_args_count) -{ - static int arfcn = 870; - static int ci = 0; - struct gsm_bts *bts; - struct e1inp_sign_link *rsl_link; - int i; - int trx_i; - struct gsm_bts_trx *trx; - - fprintf(stderr, "- Creating BTS %d, %d TRX\n", bsc_gsmnet->num_bts, num_trx); - - bts = bsc_bts_alloc_register(bsc_gsmnet, GSM_BTS_TYPE_UNKNOWN, 0x3f); - if (!bts) { - fprintf(stderr, "No resource for bts1\n"); - return NULL; - } - - bts->location_area_code = 0x0017; - bts->cell_identity = ci++; - bts->c0->arfcn = arfcn++; - - bts->codec.efr = 1; - bts->codec.hr = 1; - bts->codec.amr = 1; - - rsl_link = talloc_zero(ctx, struct e1inp_sign_link); - rsl_link->trx = bts->c0; - bts->c0->rsl_link_primary = rsl_link; - - for (trx_i = 0; trx_i < num_trx; trx_i++) { - while (!(trx = gsm_bts_trx_num(bts, trx_i))) - gsm_bts_trx_alloc(bts); - - trx->mo.nm_state.operational = NM_OPSTATE_ENABLED; - trx->mo.nm_state.availability = NM_AVSTATE_OK; - trx->mo.nm_state.administrative = NM_STATE_UNLOCKED; - trx->bb_transc.mo.nm_state.operational = NM_OPSTATE_ENABLED; - trx->bb_transc.mo.nm_state.availability = NM_AVSTATE_OK; - trx->bb_transc.mo.nm_state.administrative = NM_STATE_UNLOCKED; - - /* 4 full rate and 4 half rate channels */ - for (i = 0; i < 8; i++) { - int arg_i = trx_i * 8 + i; - const char *ts_arg; - if (arg_i >= ts_args_count) - ts_arg = bts_default_ts[i]; - else - ts_arg = ts_args[arg_i]; - fprintf(stderr, "\t%s", ts_arg); - trx->ts[i].pchan_from_config = pchan_from_str(ts_arg); - if (trx->ts[i].pchan_from_config == GSM_PCHAN_NONE) - continue; - trx->ts[i].mo.nm_state.operational = NM_OPSTATE_ENABLED; - trx->ts[i].mo.nm_state.availability = NM_AVSTATE_OK; - trx->ts[i].mo.nm_state.administrative = NM_STATE_UNLOCKED; - } - fprintf(stderr, "\n"); - - for (i = 0; i < ARRAY_SIZE(trx->ts); i++) { - /* make sure ts->lchans[] get initialized */ - osmo_fsm_inst_dispatch(trx->ts[i].fi, TS_EV_RSL_READY, 0); - osmo_fsm_inst_dispatch(trx->ts[i].fi, TS_EV_OML_READY, 0); - - /* Unused dyn TS start out as used for PDCH */ - switch (trx->ts[i].pchan_on_init) { - case GSM_PCHAN_OSMO_DYN: - case GSM_PCHAN_TCH_F_PDCH: - ts_set_pchan_is(&trx->ts[i], GSM_PCHAN_PDCH); - break; - default: - break; - } - } - } - - for (i = 0; i < bsc_gsmnet->num_bts; i++) { - if (gsm_generate_si(gsm_bts_num(bsc_gsmnet, i), SYSINFO_TYPE_2) <= 0) - fprintf(stderr, "Error generating SI2\n"); - } - return bts; -}
char *lchans_use_str(struct gsm_bts_trx_ts *ts, const char *established_prefix, char established_char) { @@ -603,24 +466,6 @@ static struct gsm_lchan *new_as_cmd = NULL; static struct gsm_lchan *last_as_cmd = NULL;
-/* send channel activation ack */ -static void send_chan_act_ack(struct gsm_lchan *lchan, int act) -{ - struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL"); - struct abis_rsl_dchan_hdr *dh; - - dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh)); - dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN; - dh->c.msg_type = (act) ? RSL_MT_CHAN_ACTIV_ACK : RSL_MT_RF_CHAN_REL_ACK; - dh->ie_chan = RSL_IE_CHAN_NR; - dh->chan_nr = gsm_lchan2chan_nr(lchan, true); - - msg->dst = rsl_chan_link(lchan); - msg->l2h = (unsigned char *)dh; - - abis_rsl_rcvmsg(msg); -} - /* Send RR Assignment Complete for SAPI[0] */ static void send_assignment_complete(struct gsm_lchan *lchan) { @@ -932,7 +777,7 @@ int n = atoi(argv[0]); VTY_ECHO(); for (i = 0; i < n; i++) - _create_bts(1, NULL, 0); + test_create_bts(ctx, 1, NULL, 0); return CMD_SUCCESS; }
@@ -947,7 +792,7 @@ { int num_trx = atoi(argv[0]); VTY_ECHO(); - _create_bts(num_trx, argv + 1, argc - 1); + test_create_bts(ctx, num_trx, argv + 1, argc - 1); return CMD_SUCCESS; }