blob: 62c01f06e391680a461b63285de9bd01d835fc0b [file] [log] [blame]
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001/*
2 * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <errno.h>
23
24#include <assert.h>
25
26#include <osmocom/core/application.h>
27#include <osmocom/core/select.h>
28#include <osmocom/core/talloc.h>
29
Neels Hofmeyrf14aaa42019-04-23 18:37:37 +020030#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
Pau Espin Pedrole2490452018-03-17 01:16:54 +010031
Neels Hofmeyr909e9722017-12-07 03:54:01 +010032#include <osmocom/bsc/abis_rsl.h>
33#include <osmocom/bsc/debug.h>
34#include <osmocom/bsc/bsc_subscriber.h>
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020035#include <osmocom/bsc/lchan_select.h>
36#include <osmocom/bsc/lchan_fsm.h>
Neels Hofmeyr909e9722017-12-07 03:54:01 +010037#include <osmocom/bsc/handover_decision.h>
38#include <osmocom/bsc/system_information.h>
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020039#include <osmocom/bsc/handover.h>
Neels Hofmeyr909e9722017-12-07 03:54:01 +010040#include <osmocom/bsc/handover_cfg.h>
41#include <osmocom/bsc/handover_decision_2.h>
Neels Hofmeyr909e9722017-12-07 03:54:01 +010042#include <osmocom/bsc/bss.h>
Neels Hofmeyr81a49632018-07-24 18:10:05 +020043#include <osmocom/bsc/gsm_08_08.h>
Neels Hofmeyr909e9722017-12-07 03:54:01 +010044#include <osmocom/bsc/osmo_bsc.h>
Harald Welte3561bd42018-01-28 03:04:16 +010045#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020046#include <osmocom/bsc/timeslot_fsm.h>
47#include <osmocom/bsc/lchan_fsm.h>
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020048#include <osmocom/bsc/handover_fsm.h>
49#include <osmocom/bsc/bsc_msc_data.h>
Pau Espin Pedrol388ed582020-07-15 20:53:16 +020050#include <osmocom/bsc/bts.h>
Neels Hofmeyr86ce1052020-09-18 02:49:32 +020051#include <osmocom/bsc/paging.h>
Neels Hofmeyr909e9722017-12-07 03:54:01 +010052
Neels Hofmeyre3416182018-03-05 05:31:14 +010053void *ctx;
54
Neels Hofmeyr909e9722017-12-07 03:54:01 +010055struct gsm_network *bsc_gsmnet;
56
Neels Hofmeyrf14aaa42019-04-23 18:37:37 +020057/* override, requires '-Wl,--wrap=osmo_mgcpc_ep_ci_request'.
Harald Welte3561bd42018-01-28 03:04:16 +010058 * Catch modification of an MGCP connection. */
Neels Hofmeyrf14aaa42019-04-23 18:37:37 +020059void __real_osmo_mgcpc_ep_ci_request(struct osmo_mgcpc_ep_ci *ci,
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020060 enum mgcp_verb verb, const struct mgcp_conn_peer *verb_info,
61 struct osmo_fsm_inst *notify,
62 uint32_t event_success, uint32_t event_failure,
63 void *notify_data);
Neels Hofmeyrf14aaa42019-04-23 18:37:37 +020064void __wrap_osmo_mgcpc_ep_ci_request(struct osmo_mgcpc_ep_ci *ci,
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020065 enum mgcp_verb verb, const struct mgcp_conn_peer *verb_info,
66 struct osmo_fsm_inst *notify,
67 uint32_t event_success, uint32_t event_failure,
68 void *notify_data)
Harald Welte3561bd42018-01-28 03:04:16 +010069{
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020070 struct mgcp_conn_peer fake_data = {};
71 /* All MGCP shall be successful */
72 if (!notify)
73 return;
74 osmo_fsm_inst_dispatch(notify, event_success, &fake_data);
Harald Welte3561bd42018-01-28 03:04:16 +010075}
76
Neels Hofmeyr909e9722017-12-07 03:54:01 +010077/* measurement report */
78
79uint8_t meas_rep_ba = 0, meas_rep_valid = 1, meas_valid = 1, meas_multi_rep = 0;
80uint8_t meas_dl_rxlev = 0, meas_dl_rxqual = 0;
81uint8_t meas_ul_rxlev = 0, meas_ul_rxqual = 0;
82uint8_t meas_tx_power_ms = 0, meas_tx_power_bs = 0, meas_ta_ms = 0;
83uint8_t meas_dtx_ms = 0, meas_dtx_bs = 0, meas_nr = 0;
84uint8_t meas_num_nc = 0, meas_rxlev_nc[6], meas_bsic_nc[6], meas_bcch_f_nc[6];
85
86static void gen_meas_rep(struct gsm_lchan *lchan)
87{
88 struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
89 struct abis_rsl_dchan_hdr *dh;
90 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
91 uint8_t ulm[3], l1i[2], *buf;
92 struct gsm48_hdr *gh;
93 struct gsm48_meas_res *mr;
94
95 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
96 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
97 dh->c.msg_type = RSL_MT_MEAS_RES;
98 dh->ie_chan = RSL_IE_CHAN_NR;
99 dh->chan_nr = chan_nr;
100
101 msgb_tv_put(msg, RSL_IE_MEAS_RES_NR, meas_nr++);
102
103 ulm[0] = meas_ul_rxlev | (meas_dtx_bs << 7);
104 ulm[1] = meas_ul_rxlev;
105 ulm[2] = (meas_ul_rxqual << 3) | meas_ul_rxqual;
106 msgb_tlv_put(msg, RSL_IE_UPLINK_MEAS, sizeof(ulm), ulm);
107
108 msgb_tv_put(msg, RSL_IE_BS_POWER, meas_tx_power_bs);
109
110 l1i[0] = 0;
111 l1i[1] = meas_ta_ms;
112 msgb_tv_fixed_put(msg, RSL_IE_L1_INFO, sizeof(l1i), l1i);
113
114 buf = msgb_put(msg, 3);
115 buf[0] = RSL_IE_L3_INFO;
116 buf[1] = (sizeof(*gh) + sizeof(*mr)) >> 8;
117 buf[2] = (sizeof(*gh) + sizeof(*mr)) & 0xff;
118
119 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
120 mr = (struct gsm48_meas_res *) msgb_put(msg, sizeof(*mr));
121
122 gh->proto_discr = GSM48_PDISC_RR;
123 gh->msg_type = GSM48_MT_RR_MEAS_REP;
124
125 /* measurement results */
126 mr->rxlev_full = meas_dl_rxlev;
127 mr->rxlev_sub = meas_dl_rxlev;
128 mr->rxqual_full = meas_dl_rxqual;
129 mr->rxqual_sub = meas_dl_rxqual;
130 mr->dtx_used = meas_dtx_ms;
131 mr->ba_used = meas_rep_ba;
132 mr->meas_valid = !meas_valid; /* 0 = valid */
133 if (meas_rep_valid) {
134 mr->no_nc_n_hi = meas_num_nc >> 2;
135 mr->no_nc_n_lo = meas_num_nc & 3;
136 } else {
137 /* no results for serving cells */
138 mr->no_nc_n_hi = 1;
139 mr->no_nc_n_lo = 3;
140 }
141 mr->rxlev_nc1 = meas_rxlev_nc[0];
142 mr->rxlev_nc2_hi = meas_rxlev_nc[1] >> 1;
143 mr->rxlev_nc2_lo = meas_rxlev_nc[1] & 1;
144 mr->rxlev_nc3_hi = meas_rxlev_nc[2] >> 2;
145 mr->rxlev_nc3_lo = meas_rxlev_nc[2] & 3;
146 mr->rxlev_nc4_hi = meas_rxlev_nc[3] >> 3;
147 mr->rxlev_nc4_lo = meas_rxlev_nc[3] & 7;
148 mr->rxlev_nc5_hi = meas_rxlev_nc[4] >> 4;
149 mr->rxlev_nc5_lo = meas_rxlev_nc[4] & 15;
150 mr->rxlev_nc6_hi = meas_rxlev_nc[5] >> 5;
151 mr->rxlev_nc6_lo = meas_rxlev_nc[5] & 31;
152 mr->bsic_nc1_hi = meas_bsic_nc[0] >> 3;
153 mr->bsic_nc1_lo = meas_bsic_nc[0] & 7;
154 mr->bsic_nc2_hi = meas_bsic_nc[1] >> 4;
155 mr->bsic_nc2_lo = meas_bsic_nc[1] & 15;
156 mr->bsic_nc3_hi = meas_bsic_nc[2] >> 5;
157 mr->bsic_nc3_lo = meas_bsic_nc[2] & 31;
158 mr->bsic_nc4 = meas_bsic_nc[3];
159 mr->bsic_nc5 = meas_bsic_nc[4];
160 mr->bsic_nc6 = meas_bsic_nc[5];
161 mr->bcch_f_nc1 = meas_bcch_f_nc[0];
162 mr->bcch_f_nc2 = meas_bcch_f_nc[1];
163 mr->bcch_f_nc3 = meas_bcch_f_nc[2];
164 mr->bcch_f_nc4 = meas_bcch_f_nc[3];
165 mr->bcch_f_nc5_hi = meas_bcch_f_nc[4] >> 1;
166 mr->bcch_f_nc5_lo = meas_bcch_f_nc[4] & 1;
167 mr->bcch_f_nc6_hi = meas_bcch_f_nc[5] >> 2;
168 mr->bcch_f_nc6_lo = meas_bcch_f_nc[5] & 3;
169
170 msg->dst = lchan->ts->trx->bts->c0->rsl_link;
171 msg->l2h = (unsigned char *)dh;
172 msg->l3h = (unsigned char *)gh;
173
174 abis_rsl_rcvmsg(msg);
175}
176
Neels Hofmeyre3eb67c2020-11-12 22:53:59 +0100177enum gsm_phys_chan_config pchan_from_str(const char *str)
178{
Neels Hofmeyrcfbf11f2020-11-12 23:12:48 +0100179 enum gsm_phys_chan_config pchan;
180 if (!strcmp(str, "dyn"))
181 return GSM_PCHAN_TCH_F_TCH_H_PDCH;
182 if (!strcmp(str, "c+s4"))
183 return GSM_PCHAN_CCCH_SDCCH4;
184 if (!strcmp(str, "-"))
185 return GSM_PCHAN_NONE;
186 pchan = gsm_pchan_parse(str);
Neels Hofmeyre3eb67c2020-11-12 22:53:59 +0100187 if (pchan < 0) {
188 fprintf(stderr, "Invalid timeslot pchan type: %s\n", str);
189 exit(1);
190 }
191 return pchan;
192}
193
194const char * const bts_default_ts[] = {
Neels Hofmeyrcfbf11f2020-11-12 23:12:48 +0100195 "c+s4", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "TCH/H", "TCH/H", "-",
Neels Hofmeyre3eb67c2020-11-12 22:53:59 +0100196};
197
Neels Hofmeyrdd7b7102020-11-12 22:54:58 +0100198static struct gsm_bts *create_bts(int num_trx, const char * const *ts_args)
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100199{
Neels Hofmeyr2f58de52020-11-12 22:51:11 +0100200 static int arfcn = 870;
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100201 struct gsm_bts *bts;
202 struct e1inp_sign_link *rsl_link;
203 int i;
Neels Hofmeyrdd7b7102020-11-12 22:54:58 +0100204 int trx_i;
Neels Hofmeyre3eb67c2020-11-12 22:53:59 +0100205 struct gsm_bts_trx *trx;
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100206
Neels Hofmeyrcfbf11f2020-11-12 23:12:48 +0100207 fprintf(stderr, "- Creating BTS %d, %d TRX\n", bsc_gsmnet->num_bts, num_trx);
208 for (trx_i = 0; trx_i < num_trx; trx_i++) {
209 for (i = 0; i < 8; i++)
210 fprintf(stderr, "\t%s", ts_args[8*trx_i + i]);
211 fprintf(stderr, "\n");
212 }
213
Vadim Yanitskiy4f3a6412020-05-31 01:56:20 +0700214 bts = bsc_bts_alloc_register(bsc_gsmnet, GSM_BTS_TYPE_UNKNOWN, 0x3f);
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100215 if (!bts) {
216 printf("No resource for bts1\n");
217 return NULL;
218 }
219
220 bts->location_area_code = 23;
Neels Hofmeyr2f58de52020-11-12 22:51:11 +0100221 bts->c0->arfcn = arfcn++;
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100222
223 bts->codec.efr = 1;
224 bts->codec.hr = 1;
225 bts->codec.amr = 1;
226
Neels Hofmeyre3416182018-03-05 05:31:14 +0100227 rsl_link = talloc_zero(ctx, struct e1inp_sign_link);
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100228 rsl_link->trx = bts->c0;
229 bts->c0->rsl_link = rsl_link;
230
Neels Hofmeyrdd7b7102020-11-12 22:54:58 +0100231 for (trx_i = 0; trx_i < num_trx; trx_i++) {
232 while (!(trx = gsm_bts_trx_num(bts, trx_i)))
233 gsm_bts_trx_alloc(bts);
Neels Hofmeyre3eb67c2020-11-12 22:53:59 +0100234
Neels Hofmeyrdd7b7102020-11-12 22:54:58 +0100235 trx->mo.nm_state.operational = NM_OPSTATE_ENABLED;
236 trx->mo.nm_state.availability = NM_AVSTATE_OK;
237 trx->mo.nm_state.administrative = NM_STATE_UNLOCKED;
238 trx->bb_transc.mo.nm_state.operational = NM_OPSTATE_ENABLED;
239 trx->bb_transc.mo.nm_state.availability = NM_AVSTATE_OK;
240 trx->bb_transc.mo.nm_state.administrative = NM_STATE_UNLOCKED;
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100241
Neels Hofmeyrdd7b7102020-11-12 22:54:58 +0100242 /* 4 full rate and 4 half rate channels */
243 for (i = 0; i < 8; i++) {
244 trx->ts[i].pchan_from_config = pchan_from_str(ts_args[trx_i * 8 + i]);
245 if (trx->ts[i].pchan_from_config == GSM_PCHAN_NONE)
246 continue;
247 trx->ts[i].mo.nm_state.operational = NM_OPSTATE_ENABLED;
248 trx->ts[i].mo.nm_state.availability = NM_AVSTATE_OK;
249 trx->ts[i].mo.nm_state.administrative = NM_STATE_UNLOCKED;
250 }
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200251
Neels Hofmeyrcfbf11f2020-11-12 23:12:48 +0100252 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
Neels Hofmeyrdd7b7102020-11-12 22:54:58 +0100253 /* make sure ts->lchans[] get initialized */
Neels Hofmeyrcfbf11f2020-11-12 23:12:48 +0100254 osmo_fsm_inst_dispatch(trx->ts[i].fi, TS_EV_RSL_READY, 0);
255 osmo_fsm_inst_dispatch(trx->ts[i].fi, TS_EV_OML_READY, 0);
256
257 /* Unused dyn TS start out as used for PDCH */
258 switch (trx->ts[i].pchan_on_init) {
259 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
260 case GSM_PCHAN_TCH_F_PDCH:
261 trx->ts[i].pchan_is = GSM_PCHAN_PDCH;
262 break;
263 default:
264 break;
265 }
Neels Hofmeyrdd7b7102020-11-12 22:54:58 +0100266 }
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100267 }
Neels Hofmeyr780f0282020-11-12 22:51:58 +0100268
269 for (i = 0; i < bsc_gsmnet->num_bts; i++) {
270 if (gsm_generate_si(gsm_bts_num(bsc_gsmnet, i), SYSINFO_TYPE_2) <= 0)
271 fprintf(stderr, "Error generating SI2\n");
272 }
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100273 return bts;
274}
275
Neels Hofmeyr43666542020-11-13 01:12:34 +0100276const char *ts_use_str(struct gsm_bts_trx_ts *ts)
277{
278 switch (ts->pchan_is) {
279 case GSM_PCHAN_CCCH_SDCCH4:
280 return "c+s4";
281
282 case GSM_PCHAN_NONE:
283 return "-";
284
285 case GSM_PCHAN_TCH_F:
286 if (lchan_state_is(&ts->lchan[0], LCHAN_ST_ESTABLISHED))
287 return "TCH/F";
288 else
289 return "-";
290
291 case GSM_PCHAN_TCH_H:
292 if (lchan_state_is(&ts->lchan[0], LCHAN_ST_ESTABLISHED)
293 && lchan_state_is(&ts->lchan[1], LCHAN_ST_ESTABLISHED))
294 return "TCH/HH";
295 if (lchan_state_is(&ts->lchan[0], LCHAN_ST_ESTABLISHED))
296 return "TCH/H-";
297 if (lchan_state_is(&ts->lchan[1], LCHAN_ST_ESTABLISHED))
298 return "TCH/-H";
299 return "-";
300
301 default:
302 return gsm_pchan_name(ts->pchan_is);
303 }
304}
305
306bool expect_ts_use(int bts_nr, int trx_nr, const char * const *ts_use)
307{
308 struct gsm_bts *bts;
309 struct gsm_bts_trx *trx;
310 int i;
311 int mismatching_ts = -1;
312 bts = gsm_bts_num(bsc_gsmnet, bts_nr);
313 OSMO_ASSERT(bts);
314 trx = gsm_bts_trx_num(bts, trx_nr);
315 OSMO_ASSERT(trx);
316
317 fprintf(stderr, "Expect TS use:");
318 for (i = 0; i < 8; i++)
319 fprintf(stderr, "\t%s", ts_use[i]);
320 fprintf(stderr, "\n");
321 fprintf(stderr, " Got TS use:");
322
323 for (i = 0; i < 8; i++) {
324 struct gsm_bts_trx_ts *ts = &trx->ts[i];
325 const char *use = ts_use_str(ts);
326
327 fprintf(stderr, "\t%s", use);
328
329 if (!strcmp(ts_use[i], "*"))
330 continue;
331 if (strcmp(ts_use[i], use) && mismatching_ts < 0)
332 mismatching_ts = i;
333 }
334 fprintf(stderr, "\n");
335
336 if (mismatching_ts >= 0) {
337 fprintf(stderr, "Test failed: mismatching TS use in bts %d trx %d ts %d\n",
338 bts_nr, trx_nr, mismatching_ts);
339 return false;
340 }
341 return true;
342}
343
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100344void create_conn(struct gsm_lchan *lchan)
345{
Neels Hofmeyrbb6c13b2018-05-24 18:43:58 +0200346 static unsigned int next_imsi = 0;
347 char imsi[sizeof(lchan->conn->bsub->imsi)];
348 struct gsm_network *net = lchan->ts->trx->bts->network;
Harald Welte3561bd42018-01-28 03:04:16 +0100349 struct gsm_subscriber_connection *conn;
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200350 struct mgcp_client *fake_mgcp_client = (void*)talloc_zero(net, int);
Neels Hofmeyrbb6c13b2018-05-24 18:43:58 +0200351
352 conn = bsc_subscr_con_allocate(net);
Harald Welte3561bd42018-01-28 03:04:16 +0100353
Neels Hofmeyrf14aaa42019-04-23 18:37:37 +0200354 conn->user_plane.mgw_endpoint = osmo_mgcpc_ep_alloc(conn->fi,
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200355 GSCON_EV_FORGET_MGW_ENDPOINT,
Neels Hofmeyrf14aaa42019-04-23 18:37:37 +0200356 fake_mgcp_client,
357 net->mgw.tdefs,
358 "test",
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200359 "fake endpoint");
Alexander Chemeris69ba8be2020-05-10 22:48:01 +0300360 conn->sccp.msc = osmo_msc_data_alloc(net, 0);
Harald Welte3561bd42018-01-28 03:04:16 +0100361
362 lchan->conn = conn;
363 conn->lchan = lchan;
Neels Hofmeyrbb6c13b2018-05-24 18:43:58 +0200364
365 /* Make up a new IMSI for this test, for logging the subscriber */
366 next_imsi ++;
367 snprintf(imsi, sizeof(imsi), "%06u", next_imsi);
Neels Hofmeyr86a1dca2020-09-15 01:03:58 +0000368 lchan->conn->bsub = bsc_subscr_find_or_create_by_imsi(net->bsc_subscribers, imsi, BSUB_USE_CONN);
Neels Hofmeyrbb6c13b2018-05-24 18:43:58 +0200369
Harald Welte3561bd42018-01-28 03:04:16 +0100370 /* kick the FSM from INIT through to the ACTIVE state */
Neels Hofmeyrd1e7d392020-09-27 23:34:57 +0200371 osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MO_COMPL_L3, NULL);
Harald Welte3561bd42018-01-28 03:04:16 +0100372 osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CONN_CFM, NULL);
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100373}
374
Neels Hofmeyr5531fae2020-11-13 03:43:57 +0100375struct gsm_lchan *lchan_act(struct gsm_lchan *lchan, int full_rate, const char *codec)
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100376{
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200377 /* serious hack into osmo_fsm */
378 lchan->fi->state = LCHAN_ST_ESTABLISHED;
379 lchan->ts->fi->state = TS_ST_IN_USE;
Neels Hofmeyr5531fae2020-11-13 03:43:57 +0100380 lchan->type = full_rate ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H;
Neels Hofmeyrfb6d9dc2020-11-13 01:13:20 +0100381
382 if (lchan->ts->pchan_on_init == GSM_PCHAN_TCH_F_TCH_H_PDCH)
383 lchan->ts->pchan_is = full_rate ? GSM_PCHAN_TCH_F : GSM_PCHAN_TCH_H;
384 if (lchan->ts->pchan_on_init == GSM_PCHAN_TCH_F_PDCH) {
385 OSMO_ASSERT(full_rate);
386 lchan->ts->pchan_is = GSM_PCHAN_TCH_F;
387 }
388
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200389 LOG_LCHAN(lchan, LOGL_DEBUG, "activated by handover_test.c\n");
390
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100391 create_conn(lchan);
392 if (!strcasecmp(codec, "FR") && full_rate)
393 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
394 else if (!strcasecmp(codec, "HR") && !full_rate)
395 lchan->tch_mode = GSM48_CMODE_SPEECH_V1;
396 else if (!strcasecmp(codec, "EFR") && full_rate)
397 lchan->tch_mode = GSM48_CMODE_SPEECH_EFR;
Philipp Maiereda6bfa2019-03-11 14:10:26 +0100398 else if (!strcasecmp(codec, "AMR")) {
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100399 lchan->tch_mode = GSM48_CMODE_SPEECH_AMR;
Philipp Maiereda6bfa2019-03-11 14:10:26 +0100400 lchan->activate.info.s15_s0 = 0x0002;
401 } else {
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100402 printf("Given codec unknown\n");
403 exit(EXIT_FAILURE);
404 }
405
406 lchan->conn->codec_list = (struct gsm0808_speech_codec_list){
407 .codec = {
408 { .fi=true, .type=GSM0808_SCT_FR1, },
409 { .fi=true, .type=GSM0808_SCT_FR2, },
410 { .fi=true, .type=GSM0808_SCT_FR3, },
411 { .fi=true, .type=GSM0808_SCT_HR1, },
412 { .fi=true, .type=GSM0808_SCT_HR3, },
413 },
414 .len = 5,
415 };
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100416
417 return lchan;
418}
419
Neels Hofmeyr5531fae2020-11-13 03:43:57 +0100420struct gsm_lchan *create_lchan(struct gsm_bts *bts, int full_rate, const char *codec)
421{
422 struct gsm_lchan *lchan;
423
424 lchan = lchan_select_by_type(bts, (full_rate) ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H);
425 if (!lchan) {
426 printf("No resource for lchan\n");
427 exit(EXIT_FAILURE);
428 }
429
430 return lchan_act(lchan, full_rate, codec);
431}
432
433static void lchan_clear(struct gsm_lchan *lchan)
434{
435 lchan_release(lchan, true, false, 0);
436}
437
438static void ts_clear(struct gsm_bts_trx_ts *ts)
439{
440 struct gsm_lchan *lchan;
441 ts_for_each_lchan(lchan, ts) {
442 if (lchan_state_is(lchan, LCHAN_ST_UNUSED))
443 continue;
444 lchan_clear(lchan);
445 }
446}
447
448bool set_ts_use(int bts_nr, int trx_nr, const char * const *ts_use)
449{
450 struct gsm_bts *bts;
451 struct gsm_bts_trx *trx;
452 int i;
453 bts = gsm_bts_num(bsc_gsmnet, bts_nr);
454 OSMO_ASSERT(bts);
455 trx = gsm_bts_trx_num(bts, trx_nr);
456 OSMO_ASSERT(trx);
457
458 fprintf(stderr, "Setting TS use:");
459 for (i = 0; i < 8; i++)
460 fprintf(stderr, "\t%s", ts_use[i]);
461 fprintf(stderr, "\n");
462
463 for (i = 0; i < 8; i++) {
464 struct gsm_bts_trx_ts *ts = &trx->ts[i];
465 const char *want_use = ts_use[i];
466 const char *is_use = ts_use_str(ts);
467
468 if (!strcmp(want_use, "*"))
469 continue;
470
471 /* If it is already as desired, don't change anything */
472 if (!strcmp(want_use, is_use))
473 continue;
474
475 if (!strcmp(want_use, "TCH/F")) {
476 if (!ts_is_capable_of_pchan(ts, GSM_PCHAN_TCH_F)) {
477 printf("Error: bts %d trx %d ts %d cannot be used as TCH/F\n",
478 bts_nr, trx_nr, i);
479 return false;
480 }
481 ts_clear(ts);
482
483 lchan_act(&ts->lchan[0], true, "AMR");
484 } else if (!strcmp(want_use, "TCH/H-")
485 || !strcmp(want_use, "TCH/HH")
486 || !strcmp(want_use, "TCH/-H")) {
487 bool act[2];
488 int j;
489
490 if (!ts_is_capable_of_pchan(ts, GSM_PCHAN_TCH_H)) {
491 printf("Error: bts %d trx %d ts %d cannot be used as TCH/H\n",
492 bts_nr, trx_nr, i);
493 return false;
494 }
495
496 if (ts->pchan_is != GSM_PCHAN_TCH_H)
497 ts_clear(ts);
498
499 act[0] = want_use[4] == 'H';
500 act[1] = want_use[5] == 'H';
501
502 for (j = 0; j < 2; j++) {
503 if (lchan_state_is(&ts->lchan[j], LCHAN_ST_UNUSED)) {
504 if (act[j])
505 lchan_act(&ts->lchan[j], false, "AMR");
506 } else if (!act[j])
507 lchan_clear(&ts->lchan[j]);
508 }
509 } else if (!strcmp(want_use, "-") || !strcmp(want_use, "PDCH")) {
510 ts_clear(ts);
511 }
512 }
513 return true;
514}
515
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100516/* parse channel request */
517
518static int got_chan_req = 0;
519static struct gsm_lchan *chan_req_lchan = NULL;
520
521static int parse_chan_act(struct gsm_lchan *lchan, uint8_t *data)
522{
523 chan_req_lchan = lchan;
524 return 0;
525}
526
527static int parse_chan_rel(struct gsm_lchan *lchan, uint8_t *data)
528{
529 chan_req_lchan = lchan;
530 return 0;
531}
532
533/* parse handover request */
534
535static int got_ho_req = 0;
536static struct gsm_lchan *ho_req_lchan = NULL;
537
538static int parse_ho_command(struct gsm_lchan *lchan, uint8_t *data, int len)
539{
540 struct gsm48_hdr *gh = (struct gsm48_hdr *) data;
541 struct gsm48_ho_cmd *ho = (struct gsm48_ho_cmd *) gh->data;
542 int arfcn;
543 struct gsm_bts *neigh;
544
545 switch (gh->msg_type) {
546 case GSM48_MT_RR_HANDO_CMD:
547 arfcn = (ho->cell_desc.arfcn_hi << 8) | ho->cell_desc.arfcn_lo;
548
549 /* look up trx. since every dummy bts uses different arfcn and
550 * only one trx, it is simple */
551 llist_for_each_entry(neigh, &bsc_gsmnet->bts_list, list) {
552 if (neigh->c0->arfcn != arfcn)
553 continue;
554 ho_req_lchan = lchan;
555 return 0;
556 }
557 break;
558 case GSM48_MT_RR_ASS_CMD:
559 ho_req_lchan = lchan;
560 return 0;
561 break;
562 default:
563 fprintf(stderr, "Error, expecting HO or AS command\n");
564 return -EINVAL;
565 }
566
567 return -1;
568}
569
570/* send channel activation ack */
571static void send_chan_act_ack(struct gsm_lchan *lchan, int act)
572{
573 struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
574 struct abis_rsl_dchan_hdr *dh;
575
576 dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
577 dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
578 dh->c.msg_type = (act) ? RSL_MT_CHAN_ACTIV_ACK : RSL_MT_RF_CHAN_REL_ACK;
579 dh->ie_chan = RSL_IE_CHAN_NR;
580 dh->chan_nr = gsm_lchan2chan_nr(lchan);
581
582 msg->dst = lchan->ts->trx->bts->c0->rsl_link;
583 msg->l2h = (unsigned char *)dh;
584
585 abis_rsl_rcvmsg(msg);
586}
587
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200588/* Send RLL Est Ind for SAPI[0] */
589static void send_est_ind(struct gsm_lchan *lchan)
590{
591 struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
592 struct abis_rsl_rll_hdr *rh;
593 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
594
595 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
596 rh->c.msg_discr = ABIS_RSL_MDISC_RLL;
597 rh->c.msg_type = RSL_MT_EST_IND;
598 rh->ie_chan = RSL_IE_CHAN_NR;
599 rh->chan_nr = chan_nr;
600 rh->ie_link_id = RSL_IE_LINK_IDENT;
601 rh->link_id = 0x00;
602
603 msg->dst = lchan->ts->trx->bts->c0->rsl_link;
604 msg->l2h = (unsigned char *)rh;
605
606 abis_rsl_rcvmsg(msg);
607}
608
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100609/* send handover complete */
610static void send_ho_complete(struct gsm_lchan *lchan, bool success)
611{
612 struct msgb *msg = msgb_alloc_headroom(256, 64, "RSL");
613 struct abis_rsl_rll_hdr *rh;
614 uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
615 uint8_t *buf;
616 struct gsm48_hdr *gh;
617 struct gsm48_ho_cpl *hc;
618
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200619 send_est_ind(lchan);
Neels Hofmeyrac85b342018-07-12 21:23:26 +0200620 osmo_fsm_inst_dispatch(lchan->fi, LCHAN_EV_RTP_READY, 0);
Neels Hofmeyr31f525e2018-05-14 18:14:15 +0200621
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100622 rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
623 rh->c.msg_discr = ABIS_RSL_MDISC_RLL;
624 rh->c.msg_type = RSL_MT_DATA_IND;
625 rh->ie_chan = RSL_IE_CHAN_NR;
626 rh->chan_nr = chan_nr;
627 rh->ie_link_id = RSL_IE_LINK_IDENT;
628 rh->link_id = 0x00;
629
630 buf = msgb_put(msg, 3);
631 buf[0] = RSL_IE_L3_INFO;
632 buf[1] = (sizeof(*gh) + sizeof(*hc)) >> 8;
633 buf[2] = (sizeof(*gh) + sizeof(*hc)) & 0xff;
634
635 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
636 hc = (struct gsm48_ho_cpl *) msgb_put(msg, sizeof(*hc));
637
638 gh->proto_discr = GSM48_PDISC_RR;
639 gh->msg_type =
640 success ? GSM48_MT_RR_HANDO_COMPL : GSM48_MT_RR_HANDO_FAIL;
641
642 msg->dst = lchan->ts->trx->bts->c0->rsl_link;
643 msg->l2h = (unsigned char *)rh;
644 msg->l3h = (unsigned char *)gh;
645
646 abis_rsl_rcvmsg(msg);
647}
648
Neels Hofmeyr1d7473c2018-03-05 21:53:18 +0100649/* override, requires '-Wl,--wrap=abis_rsl_sendmsg'.
650 * Catch RSL messages sent towards the BTS. */
651int __real_abis_rsl_sendmsg(struct msgb *msg);
652int __wrap_abis_rsl_sendmsg(struct msgb *msg)
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100653{
654 struct abis_rsl_dchan_hdr *dh = (struct abis_rsl_dchan_hdr *) msg->data;
655 struct e1inp_sign_link *sign_link = msg->dst;
656 int rc;
657 struct gsm_lchan *lchan = rsl_lchan_lookup(sign_link->trx, dh->chan_nr, &rc);
Neels Hofmeyrfb6d9dc2020-11-13 01:13:20 +0100658 struct gsm_lchan *other_lchan;
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100659
660 if (rc) {
661 printf("rsl_lchan_lookup() failed\n");
662 exit(1);
663 }
664
665 switch (dh->c.msg_type) {
666 case RSL_MT_CHAN_ACTIV:
667 rc = parse_chan_act(lchan, dh->data);
668 if (rc == 0)
669 got_chan_req = 1;
670 break;
671 case RSL_MT_RF_CHAN_REL:
672 rc = parse_chan_rel(lchan, dh->data);
673 if (rc == 0)
674 send_chan_act_ack(chan_req_lchan, 0);
Neels Hofmeyrfb6d9dc2020-11-13 01:13:20 +0100675
676 /* send dyn TS back to PDCH if unused */
677 switch (chan_req_lchan->ts->pchan_on_init) {
678 case GSM_PCHAN_TCH_F_TCH_H_PDCH:
679 case GSM_PCHAN_TCH_F_PDCH:
680 switch (chan_req_lchan->ts->pchan_is) {
681 case GSM_PCHAN_TCH_H:
682 other_lchan = &chan_req_lchan->ts->lchan[
683 (chan_req_lchan == &chan_req_lchan->ts->lchan[0])?
684 1 : 0];
685 if (lchan_state_is(other_lchan, LCHAN_ST_ESTABLISHED))
686 break;
687 /* else fall thru */
688 case GSM_PCHAN_TCH_F:
689 chan_req_lchan->ts->pchan_is = GSM_PCHAN_PDCH;
690 break;
691 default:
692 break;
693 }
694 break;
695 default:
696 break;
697 }
698
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100699 break;
700 case RSL_MT_DATA_REQ:
701 rc = parse_ho_command(lchan, msg->l3h, msgb_l3len(msg));
702 if (rc == 0)
703 got_ho_req = 1;
704 break;
705 case RSL_MT_IPAC_CRCX:
706 break;
Neels Hofmeyr5b1a7d12018-11-06 22:24:07 +0100707 case RSL_MT_DEACTIVATE_SACCH:
708 break;
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100709 default:
710 printf("unknown rsl message=0x%x\n", dh->c.msg_type);
711 }
712 return 0;
713}
714
715/* test cases */
716
717static char *test_case_0[] = {
718 "2",
719
720 "Stay in better cell\n\n"
721 "There are many neighbor cells, but only the current cell is the best\n"
722 "cell, so no handover is performed\n",
723
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100724 "create-n-bts", "7",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100725 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100726 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100727 "meas-rep", "0","0","1","0",
728 "30","0",
729 "6", "0","20", "1","21", "2","18", "3","20", "4","23", "5","19",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100730 "expect-no-chan",
731 NULL
732};
733
734static char *test_case_1[] = {
735 "2",
736
737 "Handover to best better cell\n\n"
738 "The best neighbor cell is selected\n",
739
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100740 "create-n-bts", "7",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100741 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100742 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100743 "meas-rep", "0","0","1","0",
744 "10","0",
745 "6", "0","20", "1","21", "2","18", "3","20", "4","23", "5","19",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100746 "expect-chan", "5", "1",
747 "ack-chan",
748 "expect-ho", "0", "1",
749 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100750 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
751 "expect-ts-use", "5", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100752 NULL
753};
754
755static char *test_case_2[] = {
756 "2",
757
758 "Handover and Assignment must be enabled\n\n"
759 "This test will start with disabled assignment and handover. A\n"
760 "better neighbor cell (assignment enabled) will not be selected and \n"
761 "also no assignment from TCH/H to TCH/F to improve quality. There\n"
762 "will be no handover nor assignment. After enabling assignment on the\n"
763 "current cell, the MS will assign to TCH/F. After enabling handover\n"
764 "in the current cell, but disabling in the neighbor cell, handover\n"
765 "will not be performed, until it is enabled in the neighbor cell too.\n",
766
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100767 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100768 "afs-rxlev-improve", "0", "5",
769 "create-ms", "0", "TCH/H", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100770 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100771 "as-enable", "0", "0",
772 "ho-enable", "0", "0",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100773 "meas-rep", "0","0","5","0", "0","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100774 "expect-no-chan",
775 "as-enable", "0", "1",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100776 "meas-rep", "0","0","5","0", "0","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100777 "expect-chan", "0", "1",
778 "ack-chan",
779 "expect-ho", "0", "5",
780 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100781 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100782 "ho-enable", "0", "1",
783 "ho-enable", "1", "0",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100784 "meas-rep", "0","0","1","0", "0","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100785 "expect-no-chan",
786 "ho-enable", "1", "1",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100787 "meas-rep", "0","0","1","0", "0","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100788 "expect-chan", "1", "1",
789 "ack-chan",
790 "expect-ho", "0", "1",
791 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100792 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
793 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100794 NULL
795};
796
797static char *test_case_3[] = {
798 "2",
799
800 "Penalty timer must not run\n\n"
801 "The MS will try to handover to a better cell, but this will fail.\n"
802 "Even though the cell is still better, handover will not be performed\n"
803 "due to penalty timer after handover failure\n",
804
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100805 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100806 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100807 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100808 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100809 "expect-chan", "1", "1",
810 "ack-chan",
811 "expect-ho", "0", "1",
812 "ho-failed",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100813 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
814 "expect-ts-use", "1", "0", "*", "-", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100815 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100816 "expect-no-chan",
817 NULL
818};
819
820static char *test_case_4[] = {
821 "2",
822
823 "TCH/H keeping with HR codec\n\n"
824 "The MS is using half rate V1 codec, but the better cell is congested\n"
825 "at TCH/H slots. As the congestion is removed, the handover takes\n"
826 "place.\n",
827
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100828 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100829 "set-min-free", "1", "TCH/H", "4",
830 "create-ms", "0", "TCH/H", "HR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100831 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100832 "meas-rep", "0","0","5","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100833 "expect-no-chan",
834 "set-min-free", "1", "TCH/H", "3",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100835 "meas-rep", "0","0","5","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100836 "expect-chan", "1", "5",
837 "ack-chan",
838 "expect-ho", "0", "5",
839 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100840 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
841 "expect-ts-use", "1", "0", "*", "-", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100842 NULL
843};
844
845static char *test_case_5[] = {
846 "2",
847
848 "TCH/F keeping with FR codec\n\n"
849 "The MS is using full rate V1 codec, but the better cell is congested\n"
850 "at TCH/F slots. As the congestion is removed, the handover takes\n"
851 "place.\n",
852
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100853 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100854 "set-min-free", "1", "TCH/F", "4",
855 "create-ms", "0", "TCH/F", "FR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100856 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100857 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100858 "expect-no-chan",
859 "set-min-free", "1", "TCH/F", "3",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100860 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100861 "expect-chan", "1", "1",
862 "ack-chan",
863 "expect-ho", "0", "1",
864 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100865 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
866 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100867 NULL
868};
869
870static char *test_case_6[] = {
871 "2",
872
873 "TCH/F keeping with EFR codec\n\n"
874 "The MS is using full rate V2 codec, but the better cell is congested\n"
875 "at TCH/F slots. As the congestion is removed, the handover takes\n"
876 "place.\n",
877
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100878 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100879 "set-min-free", "1", "TCH/F", "4",
880 "create-ms", "0", "TCH/F", "EFR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100881 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100882 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100883 "expect-no-chan",
884 "set-min-free", "1", "TCH/F", "3",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100885 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100886 "expect-chan", "1", "1",
887 "ack-chan",
888 "expect-ho", "0", "1",
889 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100890 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
891 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100892 NULL
893};
894
895static char *test_case_7[] = {
896 "2",
897
898 "TCH/F to TCH/H changing with AMR codec\n\n"
899 "The MS is using AMR V3 codec, the better cell is congested at TCH/F\n"
900 "slots. The handover is performed to non-congested TCH/H slots.\n",
901
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100902 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100903 "set-min-free", "1", "TCH/F", "4",
904 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100905 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100906 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100907 "expect-chan", "1", "5",
908 "ack-chan",
909 "expect-ho", "0", "1",
910 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100911 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
912 "expect-ts-use", "1", "0", "*", "-", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100913 NULL
914};
915
916static char *test_case_8[] = {
917 "2",
918
919 "No handover to a cell with no slots available\n\n"
920 "If no slot is available, no handover is performed\n",
921
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100922 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100923 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100924 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100925 "create-ms", "1", "TCH/F", "AMR",
926 "create-ms", "1", "TCH/F", "AMR",
927 "create-ms", "1", "TCH/F", "AMR",
928 "create-ms", "1", "TCH/F", "AMR",
929 "create-ms", "1", "TCH/H", "AMR",
930 "create-ms", "1", "TCH/H", "AMR",
931 "create-ms", "1", "TCH/H", "AMR",
932 "create-ms", "1", "TCH/H", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100933 "expect-ts-use", "1", "0", "*", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "TCH/HH", "TCH/HH", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100934 "meas-rep", "0","0","1","0", "0","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100935 "expect-no-chan",
936 NULL
937};
938
939static char *test_case_9[] = {
940 "2",
941
942 "No more parallel handovers, if max_unsync_ho is defined\n\n"
943 "There are tree mobiles that want to handover, but only two can do\n"
944 "it at a time, because the maximum number is limited to two.\n",
945
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100946 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100947 "set-max-ho", "1", "2",
948 "create-ms", "0", "TCH/F", "AMR",
949 "create-ms", "0", "TCH/F", "AMR",
950 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100951 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100952 "meas-rep", "0","0","1","0", "0","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100953 "expect-chan", "1", "1",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100954 "meas-rep", "0","0","2","0", "0","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100955 "expect-chan", "1", "2",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100956 "meas-rep", "0","0","3","0", "0","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100957 "expect-no-chan",
958 NULL
959};
960
961static char *test_case_10[] = {
962 "2",
963
964 "Hysteresis\n\n"
965 "If neighbor cell is better, handover is only performed if the\n"
Martin Haukea29affd2019-11-13 22:10:41 +0100966 "amount of improvement is greater or equal hyteresis\n",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100967
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100968 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100969 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100970 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100971 "meas-rep", "0","0","1","0", "27","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100972 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100973 "meas-rep", "0","0","1","0", "26","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100974 "expect-chan", "1", "1",
975 "ack-chan",
976 "expect-ho", "0", "1",
977 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100978 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
979 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100980 NULL
981};
982
983static char *test_case_11[] = {
984 "2",
985
986 "No Hysteresis and minimum RX level\n\n"
987 "If current cell's RX level is below mimium level, handover must be\n"
988 "performed, no matter of the hysteresis. First do not perform\n"
989 "handover to better neighbor cell, because the hysteresis is not\n"
990 "met. Second do not perform handover because better neighbor cell is\n"
991 "below minimum RX level. Third perform handover because current cell\n"
992 "is below minimum RX level, even if the better neighbor cell (minimum\n"
993 "RX level reached) does not meet the hysteresis.\n",
994
Neels Hofmeyr4942da82020-11-12 22:58:17 +0100995 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100996 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +0100997 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +0100998 "meas-rep", "0","0","1","0", "10","0", "1","0","11",
Neels Hofmeyr909e9722017-12-07 03:54:01 +0100999 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001000 "meas-rep", "0","0","1","0", "8","0", "1","0","9",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001001 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001002 "meas-rep", "0","0","1","0", "9","0", "1","0","10",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001003 "expect-chan", "1", "1",
1004 "ack-chan",
1005 "expect-ho", "0", "1",
1006 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001007 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1008 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001009 NULL
1010};
1011
1012static char *test_case_12[] = {
1013 "2",
1014
1015 "No handover to congested cell\n\n"
1016 "The better neighbor cell is congested, so no handover is performed.\n"
1017 "After the congestion is over, handover will be performed.\n",
1018
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001019 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001020 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001021 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001022 "set-min-free", "1", "TCH/F", "4",
1023 "set-min-free", "1", "TCH/H", "4",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001024 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001025 "expect-no-chan",
1026 "set-min-free", "1", "TCH/F", "3",
1027 "set-min-free", "1", "TCH/H", "3",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001028 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001029 "expect-chan", "1", "1",
1030 "ack-chan",
1031 "expect-ho", "0", "1",
1032 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001033 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1034 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001035 NULL
1036};
1037
1038static char *test_case_13[] = {
1039 "2",
1040
1041 "Handover to balance congestion\n\n"
1042 "The current and the better cell are congested, so no handover is\n"
1043 "performed. This is because handover would congest the neighbor cell\n"
1044 "more. After congestion raises in the current cell, the handover is\n"
1045 "performed to balance congestion\n",
1046
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001047 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001048 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001049 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001050 "set-min-free", "0", "TCH/F", "4",
1051 "set-min-free", "0", "TCH/H", "4",
1052 "set-min-free", "1", "TCH/F", "4",
1053 "set-min-free", "1", "TCH/H", "4",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001054 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001055 "expect-no-chan",
1056 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001057 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001058 "meas-rep", "0","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001059 "expect-chan", "1", "1",
1060 "ack-chan",
1061 "expect-ho", "0", "1",
1062 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001063 "expect-ts-use", "0", "0", "*", "-", "TCH/F", "-", "-", "-", "-", "-",
1064 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001065 NULL
1066};
1067
1068static char *test_case_14[] = {
1069 "2",
1070
1071 "Handover to congested cell, if RX level is below minimum\n\n"
1072 "The better neighbor cell is congested, so no handover is performed.\n"
1073 "If the RX level of the current cell drops below minimum acceptable\n"
1074 "level, the handover is performed.\n",
1075
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001076 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001077 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001078 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001079 "set-min-free", "1", "TCH/F", "4",
1080 "set-min-free", "1", "TCH/H", "4",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001081 "meas-rep", "0","0","1","0", "10","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001082 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001083 "meas-rep", "0","0","1","0", "9","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001084 "expect-chan", "1", "1",
1085 "ack-chan",
1086 "expect-ho", "0", "1",
1087 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001088 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1089 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001090 NULL
1091};
1092
1093static char *test_case_15[] = {
1094 "2",
1095
1096 "Handover to cell with worse RXLEV, if RXQUAL is below minimum\n\n"
1097 "The neighbor cell has worse RXLEV, so no handover is performed.\n"
1098 "If the RXQUAL of the current cell drops below minimum acceptable\n"
1099 "level, the handover is performed. It is also required that 10\n"
1100 "reports are received, before RXQUAL is checked.\n",
1101 /* (See also test 28, which tests for RXQUAL triggering HO to congested cell.) */
1102 /* TODO: bad RXQUAL may want to prefer assignment within the same cell to avoid interference.
Martin Haukea29affd2019-11-13 22:10:41 +01001103 * See Performance Enhancements in a Frequency Hopping GSM Network (Nielsen Wigard 2002), Chapter
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001104 * 2.1.1, "Interference" in the list of triggers on p.157. */
1105
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001106 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001107 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001108 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001109 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001110 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001111 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001112 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001113 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001114 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001115 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001116 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001117 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001118 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001119 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001120 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001121 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001122 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001123 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001124 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001125 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001126 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001127 "meas-rep", "0","0","1","0", "40","6", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001128 "expect-chan", "1", "1",
1129 "ack-chan",
1130 "expect-ho", "0", "1",
1131 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001132 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1133 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001134 NULL
1135};
1136
1137static char *test_case_16[] = {
1138 "2",
1139
1140 "Handover due to maximum TA exceeded\n\n"
1141 "The MS in the current (best) cell has reached maximum allowed timing\n"
1142 "advance. No handover is performed until the timing advance exceeds\n"
1143 "it. The originating cell is still the best, but no handover is\n"
1144 "performed back to that cell, because the penalty timer (due to\n"
1145 "maximum allowed timing advance) is running.\n",
1146
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001147 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001148 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001149 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001150 "set-max-ta", "0", "5", /* of cell */
1151 "set-ta", "0", "5", /* of ms */
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001152 "meas-rep", "0","0","1","0", "30","0", "1","0","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001153 "expect-no-chan",
1154 "set-ta", "0", "6", /* of ms */
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001155 "meas-rep", "0","0","1","0", "30","0", "1","0","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001156 "expect-chan", "1", "1",
1157 "ack-chan",
1158 "expect-ho", "0", "1",
1159 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001160 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1161 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001162 "meas-rep", "1","0","1","0", "20","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001163 "expect-no-chan",
1164 NULL
1165};
1166
1167static char *test_case_17[] = {
1168 "2",
1169
1170 "Congestion check: No congestion\n\n"
1171 "Three cells have different number of used slots, but there is no\n"
1172 "congestion in any of these cells. No handover is performed.\n",
1173
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001174 "create-n-bts", "3",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001175 "set-min-free", "0", "TCH/F", "2",
1176 "set-min-free", "0", "TCH/H", "2",
1177 "set-min-free", "1", "TCH/F", "2",
1178 "set-min-free", "1", "TCH/H", "2",
1179 "set-min-free", "2", "TCH/F", "2",
1180 "set-min-free", "2", "TCH/H", "2",
1181 "create-ms", "0", "TCH/F", "AMR",
1182 "create-ms", "0", "TCH/F", "AMR",
1183 "create-ms", "0", "TCH/H", "AMR",
1184 "create-ms", "0", "TCH/H", "AMR",
1185 "create-ms", "1", "TCH/F", "AMR",
1186 "create-ms", "1", "TCH/H", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001187 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "-", "-", "TCH/HH", "-", "-",
1188 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001189 "meas-rep", "0","0","1","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001190 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001191 "meas-rep", "0","0","2","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001192 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001193 "meas-rep", "0","0","5","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001194 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001195 "meas-rep", "0","0","5","1", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001196 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001197 "meas-rep", "1","0","1","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001198 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001199 "meas-rep", "1","0","5","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001200 "expect-no-chan",
1201 "congestion-check",
1202 "expect-no-chan",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001203 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "-", "-", "TCH/HH", "-", "-",
1204 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001205 NULL
1206};
1207
1208static char *test_case_18[] = {
1209 "2",
1210
1211 "Congestion check: One out of three cells is congested\n\n"
1212 "Three cells have different number of used slots, but there is\n"
1213 "congestion at TCH/F in the first cell. Handover is performed with\n"
1214 "the best candidate.\n",
1215
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001216 "create-n-bts", "3",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001217 "set-min-free", "0", "TCH/F", "2",
1218 "set-min-free", "0", "TCH/H", "2",
1219 "set-min-free", "1", "TCH/F", "2",
1220 "set-min-free", "1", "TCH/H", "2",
1221 "set-min-free", "2", "TCH/F", "2",
1222 "set-min-free", "2", "TCH/H", "2",
1223 "create-ms", "0", "TCH/F", "AMR",
1224 "create-ms", "0", "TCH/F", "AMR",
1225 "create-ms", "0", "TCH/F", "AMR",
1226 "create-ms", "0", "TCH/H", "AMR",
1227 "create-ms", "0", "TCH/H", "AMR",
1228 "create-ms", "1", "TCH/F", "AMR",
1229 "create-ms", "1", "TCH/H", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001230 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "-", "TCH/HH", "-", "-",
1231 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001232 "meas-rep", "0","0","1","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001233 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001234 "meas-rep", "0","0","2","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001235 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001236 "meas-rep", "0","0","3","0", "30","0", "2","0","21","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001237 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001238 "meas-rep", "0","0","5","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001239 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001240 "meas-rep", "0","0","5","1", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001241 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001242 "meas-rep", "1","0","1","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001243 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001244 "meas-rep", "1","0","5","0", "30","0", "2","0","20","1","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001245 "expect-no-chan",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001246 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "-", "TCH/HH", "-", "-",
1247 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001248 "congestion-check",
1249 "expect-chan", "1", "2",
1250 "ack-chan",
Neels Hofmeyr72d64e72020-11-16 18:07:31 +01001251 "expect-ho", "0", "3", /* best candidate is MS 2 at BTS 0, TS 3 */
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001252 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001253 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "-", "-", "TCH/HH", "-", "-",
1254 "expect-ts-use", "1", "0", "*", "TCH/F", "TCH/F", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001255 NULL
1256};
1257
1258static char *test_case_19[] = {
1259 "2",
1260
1261 "Congestion check: Balancing over congested cells\n\n"
Neels Hofmeyr1336d942020-08-10 21:13:55 +02001262 "Two cells are congested, but the second cell is less congested.\n"
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001263 "Handover is performed to solve the congestion.\n",
1264
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001265 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001266 "set-min-free", "0", "TCH/F", "4",
1267 "set-min-free", "1", "TCH/F", "4",
1268 "create-ms", "0", "TCH/F", "FR",
1269 "create-ms", "0", "TCH/F", "FR",
1270 "create-ms", "0", "TCH/F", "FR",
1271 "create-ms", "1", "TCH/F", "FR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001272 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "-", "-", "-", "-",
1273 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001274 "meas-rep", "0","0","1","0", "30","0", "1","0","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001275 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001276 "meas-rep", "0","0","2","0", "30","0", "1","0","21",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001277 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001278 "meas-rep", "0","0","3","0", "30","0", "1","0","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001279 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001280 "meas-rep", "1","0","1","0", "30","0", "1","0","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001281 "expect-no-chan",
1282 "congestion-check",
1283 "expect-chan", "1", "2",
1284 "ack-chan",
1285 "expect-ho", "0", "2", /* best candidate is MS 1 at BTS 0, TS 2 */
1286 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001287 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "TCH/F", "-", "-", "-", "-",
1288 "expect-ts-use", "1", "0", "*", "TCH/F", "TCH/F", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001289 NULL
1290};
1291
1292static char *test_case_20[] = {
1293 "2",
1294
1295 "Congestion check: Solving congestion by handover TCH/F -> TCH/H\n\n"
1296 "Two BTS, one MS in the first congested BTS must handover to\n"
1297 "non-congested TCH/H of second BTS, in order to solve congestion\n",
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001298 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001299 "set-min-free", "0", "TCH/F", "4",
1300 "set-min-free", "0", "TCH/H", "4",
1301 "set-min-free", "1", "TCH/F", "4",
1302 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001303 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001304 "meas-rep", "0","0","1","0", "30","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001305 "expect-no-chan",
1306 "congestion-check",
1307 "expect-chan", "1", "5",
1308 "ack-chan",
1309 "expect-ho", "0", "1",
1310 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001311 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1312 "expect-ts-use", "1", "0", "*", "-", "-", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001313 NULL
1314};
1315
1316static char *test_case_21[] = {
1317 "2",
1318
1319 "Congestion check: Balancing congestion by handover TCH/F -> TCH/H\n\n"
1320 "Two BTS, one MS in the first congested BTS must handover to\n"
1321 "less-congested TCH/H of second BTS, in order to balance congestion\n",
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001322 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001323 "set-min-free", "0", "TCH/F", "4",
1324 "set-min-free", "0", "TCH/H", "4",
1325 "set-min-free", "1", "TCH/F", "4",
1326 "set-min-free", "1", "TCH/H", "4",
1327 "create-ms", "0", "TCH/F", "AMR",
1328 "create-ms", "0", "TCH/F", "AMR",
1329 "create-ms", "0", "TCH/H", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001330 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001331 "meas-rep", "0","0","1","0", "30","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001332 "expect-no-chan",
1333 "congestion-check",
1334 "expect-chan", "1", "1",
1335 "ack-chan",
1336 "expect-ho", "0", "1",
1337 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001338 "expect-ts-use", "0", "0", "*", "-", "TCH/F", "-", "-", "TCH/H-", "-", "-",
1339 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001340 NULL
1341};
1342
1343static char *test_case_22[] = {
1344 "2",
1345
1346 "Congestion check: Upgrading worst candidate from TCH/H -> TCH/F\n\n"
1347 "There is only one BTS. The TCH/H slots are congested. Since\n"
1348 "assignment is performed to less-congested TCH/F, the candidate with\n"
1349 "the worst RX level is chosen.\n",
1350
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001351 "create-n-bts", "1",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001352 "set-min-free", "0", "TCH/F", "4",
1353 "set-min-free", "0", "TCH/H", "4",
1354 "create-ms", "0", "TCH/H", "AMR",
1355 "create-ms", "0", "TCH/H", "AMR",
1356 "create-ms", "0", "TCH/H", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001357 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "TCH/HH", "TCH/H-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001358 "meas-rep", "0","0","5","0", "30","0", "0",
1359 "meas-rep", "0","0","5","1", "34","0", "0",
1360 "meas-rep", "0","0","6","0", "20","0", "0",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001361 "expect-no-chan",
1362 "congestion-check",
1363 "expect-chan", "0", "1",
1364 "ack-chan",
1365 "expect-ho", "0", "6",
1366 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001367 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "TCH/HH", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001368 NULL
1369};
1370
1371static char *test_case_23[] = {
1372 "2",
1373
1374 "Story: 'A neighbor is your friend'\n",
1375
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001376 "create-n-bts", "3",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001377
1378 "print",
1379 "Andreas is driving along the coast, on a sunny june afternoon.\n"
1380 "Suddenly he is getting a call from his friend and neighbor Axel.\n"
1381 "\n"
1382 "What happens: Two MS are created, #0 for Axel, #1 for Andreas.",
1383 /* Axel */
1384 "create-ms", "2", "TCH/F", "AMR",
1385 /* andreas */
1386 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001387 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
1388 "expect-ts-use", "1", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1389 "expect-ts-use", "2", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001390 "meas-rep", "0","0","1","0", "40","0", "1","0","30",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001391 "expect-no-chan",
1392
1393 "print",
1394 "Axel asks Andreas if he would like to join them for a barbecue.\n"
1395 "Axel's house is right in the neighborhood and the weather is fine.\n"
1396 "Andreas agrees, so he drives to a close store to buy some barbecue\n"
1397 "skewers.\n"
1398 "\n"
1399 "What happens: While driving, a different cell (mounted atop the\n"
1400 "store) becomes better.",
1401 /* drive to bts 1 */
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001402 "meas-rep", "0","0","1","0", "20","0", "1","0","35",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001403 "expect-chan", "1", "1",
1404 "ack-chan",
1405 "expect-ho", "0", "1",
1406 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001407 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1408 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
1409 "expect-ts-use", "2", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001410
1411 "print",
1412 "While Andreas is walking into the store, Axel asks, if he could also\n"
1413 "bring some beer. Andreas has problems understanding him: \"I have a\n"
1414 "bad reception here. The cell tower is right atop the store, but poor\n"
1415 "coverage inside. Can you repeat please?\"\n"
1416 "\n"
1417 "What happens: Inside the store the close cell is so bad, that\n"
1418 "handover back to the previous cell is required.",
1419 /* bts 1 becomes bad, so bts 0 helps out */
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001420 "meas-rep", "1","0","1","0", "5","0", "1","0","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001421 "expect-chan", "0", "1",
1422 "ack-chan",
1423 "expect-ho", "1", "1",
1424 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001425 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
1426 "expect-ts-use", "1", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1427 "expect-ts-use", "2", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001428
1429 "print",
1430 "After Andreas bought skewers and beer, he leaves the store.\n"
1431 "\n"
1432 "What happens: Outside the store the close cell is better again, so\n"
1433 "handover back to the that cell is performed.",
1434 /* bts 1 becomes better again */
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001435 "meas-rep", "0","0","1","0", "20","0", "1","0","35",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001436 "expect-chan", "1", "1",
1437 "ack-chan",
1438 "expect-ho", "0", "1",
1439 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001440 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1441 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
1442 "expect-ts-use", "2", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001443
1444 "print",
1445 /* bts 2 becomes better */
1446 "Andreas drives down to the lake where Axel's house is.\n"
1447 "\n"
1448 "What happens: There is a small cell at Axel's house, which becomes\n"
1449 "better, because the current cell has no good comverage at the lake.",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001450 "meas-rep", "1","0","1","0", "14","0", "2","0","2","1","63",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001451 "expect-chan", "2", "2",
1452 "ack-chan",
1453 "expect-ho", "1", "1",
1454 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001455 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1456 "expect-ts-use", "1", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1457 "expect-ts-use", "2", "0", "*", "TCH/F", "TCH/F", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001458
1459 "print",
1460 "Andreas wonders why he still has good radio coverage: \"Last time it\n"
1461 "was so bad\". Axel says: \"I installed a pico cell in my house,\n"
1462 "now we can use our mobile phones down here at the lake.\"",
1463
1464 NULL
1465};
1466
1467static char *test_case_24[] = {
1468 "2",
1469 "No (or not enough) measurements for handover\n\n"
1470 "Do not solve congestion in cell, because there is no measurement.\n"
Martin Haukea29affd2019-11-13 22:10:41 +01001471 "As soon as enough measurements available (1 in our case), perform\n"
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001472 "handover. Afterwards the old cell becomes congested and the new\n"
1473 "cell is not. Do not perform handover until new measurements are\n"
1474 "received.\n",
1475
1476 /* two cells, first in congested, but no handover */
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001477 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001478 "set-min-free", "0", "TCH/F", "4",
1479 "set-min-free", "0", "TCH/H", "4",
1480 "create-ms", "0", "TCH/F", "AMR",
1481 "congestion-check",
1482 "expect-no-chan",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001483 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001484
1485 /* send measurement and trigger congestion check */
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001486 "meas-rep", "0","0","1","0", "20","0", "1","0","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001487 "expect-no-chan",
1488 "congestion-check",
1489 "expect-chan", "1", "1",
1490 "ack-chan",
1491 "expect-ho", "0", "1",
1492 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001493 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1494 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001495
1496 /* congest the first cell and remove congestion from second cell */
1497 "set-min-free", "0", "TCH/F", "0",
1498 "set-min-free", "0", "TCH/H", "0",
1499 "set-min-free", "1", "TCH/F", "4",
1500 "set-min-free", "1", "TCH/H", "4",
1501
1502 /* no handover until measurements applied */
1503 "congestion-check",
1504 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001505 "meas-rep", "1","0","1","0", "20","0", "1","0","20",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001506 "expect-no-chan",
1507 "congestion-check",
1508 "expect-chan", "0", "1",
1509 "ack-chan",
1510 "expect-ho", "1", "1",
1511 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001512 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
1513 "expect-ts-use", "1", "0", "*", "-", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001514 NULL
1515};
1516
1517static char *test_case_25[] = {
1518 "1",
1519
1520 "Stay in better cell\n\n"
1521 "There are many neighbor cells, but only the current cell is the best\n"
1522 "cell, so no handover is performed\n",
1523
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001524 "create-n-bts", "7",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001525 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001526 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001527 "meas-rep", "0","0","1","0", "30","0",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001528 "6","0","20","1","21","2","18","3","20","4","23","5","19",
1529 "expect-no-chan",
1530 NULL
1531};
1532
1533static char *test_case_26[] = {
1534 "1",
1535
1536 "Handover to best better cell\n\n"
1537 "The best neighbor cell is selected\n",
1538
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001539 "create-n-bts", "7",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001540 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001541 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001542 "meas-rep", "0","0","1","0", "10","0",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001543 "6","0","20","1","21","2","18","3","20","4","23","5","19",
1544 "expect-chan", "5", "1",
1545 "ack-chan",
1546 "expect-ho", "0", "1",
1547 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001548 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1549 "expect-ts-use", "5", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001550 NULL
1551};
1552
1553static char *test_case_27[] = {
1554 "2",
1555
1556 "Congestion check: Upgrading worst candidate from TCH/H -> TCH/F\n\n"
1557 "There is only one BTS. The TCH/H slots are congested. Since\n"
1558 "assignment is performed to less-congested TCH/F, the candidate with\n"
1559 "the worst RX level is chosen. (So far like test 22.)\n"
1560 "After that, trigger more congestion checks to ensure stability.\n",
1561
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001562 "create-n-bts", "1",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001563 "set-min-free", "0", "TCH/F", "2",
1564 "set-min-free", "0", "TCH/H", "4",
1565 "create-ms", "0", "TCH/H", "AMR",
1566 "create-ms", "0", "TCH/H", "AMR",
1567 "create-ms", "0", "TCH/H", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001568 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "TCH/HH", "TCH/H-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001569 "meas-rep", "0","0","5","0", "30","0", "0",
1570 "meas-rep", "0","0","5","1", "34","0", "0",
1571 "meas-rep", "0","0","6","0", "20","0", "0",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001572 "expect-no-chan",
1573 "congestion-check",
1574 "expect-chan", "0", "1",
1575 "ack-chan",
1576 "expect-ho", "0", "6",
1577 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001578 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "TCH/HH", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001579 "congestion-check",
1580 "expect-chan", "0", "2",
1581 "ack-chan",
1582 "expect-ho", "0", "5",
1583 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001584 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "-", "-", "TCH/-H", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001585 "congestion-check",
1586 "expect-no-chan",
1587 "congestion-check",
1588 "expect-no-chan",
1589 NULL
1590};
1591
1592static char *test_case_28[] = {
1593 "2",
1594
1595 "Handover to congested cell, if RX quality is below minimum\n\n"
1596 "The better neighbor cell is congested, so no handover is performed.\n"
1597 "If the RX quality of the current cell drops below minimum acceptable\n"
1598 "level, the handover is performed. It is also required that 10\n"
1599 "resports are received, before RX quality is checked.\n",
1600
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001601 "create-n-bts", "2",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001602 "create-ms", "0", "TCH/F", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001603 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001604 "set-min-free", "1", "TCH/F", "4",
1605 "set-min-free", "1", "TCH/H", "4",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001606 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001607 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001608 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001609 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001610 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001611 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001612 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001613 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001614 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001615 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001616 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001617 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001618 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001619 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001620 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001621 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001622 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001623 "expect-no-chan",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001624 "meas-rep", "0","0","1","0", "30","6", "1","0","40",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001625 "expect-chan", "1", "1",
1626 "ack-chan",
1627 "expect-ho", "0", "1",
1628 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001629 "expect-ts-use", "0", "0", "*", "-", "-", "-", "-", "-", "-", "-",
1630 "expect-ts-use", "1", "0", "*", "TCH/F", "-", "-", "-", "-", "-", "-",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001631 NULL
1632};
1633
Neels Hofmeyr7b2b4302020-08-02 02:50:17 +02001634static char *test_case_29[] = {
1635 "2",
1636
1637 "Congestion check: Balancing congestion by handover TCH/F -> TCH/H\n\n"
1638 "One BTS, and TCH/F are considered congested, TCH/H are not.\n"
1639 ,
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001640 "create-n-bts", "1",
Neels Hofmeyr7b2b4302020-08-02 02:50:17 +02001641 "set-min-free", "0", "TCH/F", "3",
1642 "set-min-free", "0", "TCH/H", "0",
1643 "create-ms", "0", "TCH/F", "AMR",
1644 "create-ms", "0", "TCH/F", "AMR",
1645 "create-ms", "0", "TCH/H", "AMR",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001646 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "-", "-", "TCH/H-", "-", "-",
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01001647 "meas-rep", "0","0","1","0", "30","0", "1","0","30",
Neels Hofmeyr7b2b4302020-08-02 02:50:17 +02001648 "expect-no-chan",
1649 "congestion-check",
1650 "expect-chan", "0", "5",
1651 "ack-chan",
1652 "expect-ho", "0", "1",
1653 "ho-complete",
Neels Hofmeyr43666542020-11-13 01:12:34 +01001654 "expect-ts-use", "0", "0", "*", "-", "TCH/F", "-", "-", "TCH/HH", "-", "-",
Neels Hofmeyr7b2b4302020-08-02 02:50:17 +02001655 NULL
1656};
1657
Neels Hofmeyr25e8f762020-11-13 01:13:48 +01001658static char *test_case_30[] = {
1659 "2",
1660
1661 "Congestion check: Balancing congestion by handover TCH/F -> TCH/H\n\n"
1662 "With dynamic timeslots.\n"
1663 "As soon as only one TCH/F is left, there should be HO to a dyn TS.\n"
1664 ,
1665 "create-bts", "1", "c+s4", "TCH/F", "TCH/F", "TCH/F", "dyn", "dyn", "dyn", "PDCH",
1666 "set-min-free", "0", "TCH/F", "2",
1667 "set-min-free", "0", "TCH/H", "0",
1668 "as-enable", "0", "1",
1669 "set-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "PDCH", "PDCH", "PDCH",
1670 "meas-rep", "0","0","1","0", "40","0", "1", "0","30",
1671 "meas-rep", "0","0","2","0", "40","0", "1", "0","30",
1672 "meas-rep", "0","0","3","0", "40","0", "1", "0","30",
1673 "meas-rep", "0","0","4","0", "40","0", "1", "0","30",
1674 "congestion-check",
1675 "expect-no-chan",
1676 "create-ms", "0", "TCH/F", "AMR",
1677 "meas-rep", "0","0","5","0", "40","0", "1", "0","30",
1678 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "PDCH", "PDCH",
1679 "congestion-check",
1680 "expect-chan", "0", "6",
1681 "ack-chan",
Neels Hofmeyrdc69da12020-11-13 02:14:37 +01001682 "expect-ho", "0", "5",
Neels Hofmeyr25e8f762020-11-13 01:13:48 +01001683 "ho-complete",
Neels Hofmeyrdc69da12020-11-13 02:14:37 +01001684 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "PDCH", "TCH/H-", "PDCH",
Neels Hofmeyr25e8f762020-11-13 01:13:48 +01001685 "congestion-check",
1686 "expect-chan", "0", "6",
1687 "ack-chan",
Neels Hofmeyrdc69da12020-11-13 02:14:37 +01001688 "expect-ho", "0", "4",
Neels Hofmeyr25e8f762020-11-13 01:13:48 +01001689 "ho-complete",
Neels Hofmeyrdc69da12020-11-13 02:14:37 +01001690 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "PDCH", "PDCH", "TCH/HH", "PDCH",
Neels Hofmeyr25e8f762020-11-13 01:13:48 +01001691 "congestion-check",
1692 "expect-no-chan",
Neels Hofmeyre0792fd2020-11-13 03:33:10 +01001693 "create-ms", "0", "TCH/F", "AMR",
1694 "meas-rep", "0","0","4","0", "40","0", "1", "0","30",
1695 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "PDCH", "TCH/HH", "PDCH",
1696 "congestion-check",
1697 "expect-chan", "0", "5",
1698 "ack-chan",
1699 "expect-ho", "0", "4",
1700 "ho-complete",
1701 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "PDCH", "TCH/H-", "TCH/HH", "PDCH",
1702 "congestion-check",
1703 "expect-chan", "0", "5",
1704 "ack-chan",
1705 "expect-ho", "0", "1",
1706 "ho-complete",
1707 "expect-ts-use", "0", "0", "*", "-", "TCH/F", "TCH/F", "PDCH", "TCH/HH", "TCH/HH", "PDCH",
1708 "congestion-check",
1709 "expect-no-chan",
1710 "create-ms", "0", "TCH/F", "AMR",
1711 "meas-rep", "0","0","1","0", "40","0", "1", "0","30",
1712 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "PDCH", "TCH/HH", "TCH/HH", "PDCH",
1713 "congestion-check",
1714 "expect-chan", "0", "4",
1715 "ack-chan",
1716 "expect-ho", "0", "1",
1717 "ho-complete",
1718 "expect-ts-use", "0", "0", "*", "-", "TCH/F", "TCH/F", "TCH/H-", "TCH/HH", "TCH/HH", "PDCH",
1719 "congestion-check",
1720 "expect-chan", "0", "4",
1721 "ack-chan",
1722 "expect-ho", "0", "2",
1723 "ho-complete",
1724 "expect-ts-use", "0", "0", "*", "-", "-", "TCH/F", "TCH/HH", "TCH/HH", "TCH/HH", "PDCH",
1725 "congestion-check",
1726 "expect-no-chan",
1727 "create-ms", "0", "TCH/F", "AMR",
1728 "meas-rep", "0","0","1","0", "40","0", "1", "0","30",
1729 "expect-ts-use", "0", "0", "*", "TCH/F", "-", "TCH/F", "TCH/HH", "TCH/HH", "TCH/HH", "PDCH",
1730 "congestion-check",
1731 "expect-no-chan",
1732 "create-ms", "0", "TCH/F", "AMR",
1733 "meas-rep", "0","0","2","0", "40","0", "1", "0","30",
1734 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/F", "TCH/F", "TCH/HH", "TCH/HH", "TCH/HH", "PDCH",
1735 "congestion-check",
1736 "expect-no-chan",
Neels Hofmeyr25e8f762020-11-13 01:13:48 +01001737 NULL
1738};
1739
Neels Hofmeyrb08ec402020-11-13 04:17:30 +01001740static char *test_case_31[] = {
1741 "2",
1742
1743 "Congestion check: re-use half used TCH/H to avoid switching more dyn TS to TCH/H\n"
1744 ,
1745 "create-bts", "1", "c+s4", "TCH/F", "TCH/F", "TCH/F", "dyn", "dyn", "dyn", "PDCH",
1746 "set-ts-use", "0", "0", "*", "-", "-", "-", "PDCH", "TCH/H-", "PDCH", "PDCH",
1747 "create-ms", "0", "TCH/H", "AMR",
Neels Hofmeyrdad4e7c2020-11-13 04:19:24 +01001748 "expect-ts-use", "0", "0", "*", "-", "-", "-", "PDCH", "TCH/HH", "PDCH", "PDCH",
Neels Hofmeyrb08ec402020-11-13 04:17:30 +01001749 NULL
1750};
Neels Hofmeyr7b2b4302020-08-02 02:50:17 +02001751
Neels Hofmeyr2978e742020-11-18 13:45:59 +01001752static char *test_case_32[] = {
1753 "2",
1754
1755 "Congestion check: favor moving a TCH/H that frees a half-used dyn TS completely\n"
1756 ,
1757 "create-bts", "1", "c+s4", "dyn", "dyn", "dyn", "dyn", "dyn", "-", "-",
1758 "set-ts-use", "0", "0", "*", "PDCH", "TCH/HH", "TCH/H-", "TCH/HH", "PDCH", "-", "-",
1759 "meas-rep", "0","0","2","1", "30","0", "0",
1760 "meas-rep", "0","0","3","0", "30","0", "0",
1761 "meas-rep", "0","0","4","0", "30","0", "0",
1762 "meas-rep", "0","0","4","1", "30","0", "0",
1763 /* pick one to move */
1764 "set-min-free", "0", "TCH/H", "6",
1765 "congestion-check",
1766 "expect-chan", "0", "1",
1767 "ack-chan",
1768 /* Not so good: should move the half-used TCH/H instead of "halving" another dyn TS */
1769 "expect-ho", "0", "4",
1770 "ho-complete",
1771 "expect-ts-use", "0", "0", "*", "TCH/F", "TCH/HH", "TCH/H-", "TCH/H-", "PDCH", "-", "-",
1772 NULL
1773};
1774
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001775static char **test_cases[] = {
1776 test_case_0,
1777 test_case_1,
1778 test_case_2,
1779 test_case_3,
1780 test_case_4,
1781 test_case_5,
1782 test_case_6,
1783 test_case_7,
1784 test_case_8,
1785 test_case_9,
1786 test_case_10,
1787 test_case_11,
1788 test_case_12,
1789 test_case_13,
1790 test_case_14,
1791 test_case_15,
1792 test_case_16,
1793 test_case_17,
1794 test_case_18,
1795 test_case_19,
1796 test_case_20,
1797 test_case_21,
1798 test_case_22,
1799 test_case_23,
1800 test_case_24,
1801 test_case_25,
1802 test_case_26,
1803 test_case_27,
1804 test_case_28,
Neels Hofmeyr7b2b4302020-08-02 02:50:17 +02001805 test_case_29,
Neels Hofmeyr25e8f762020-11-13 01:13:48 +01001806 test_case_30,
Neels Hofmeyrb08ec402020-11-13 04:17:30 +01001807 test_case_31,
Neels Hofmeyr2978e742020-11-18 13:45:59 +01001808 test_case_32,
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001809};
1810
1811static const struct log_info_cat log_categories[] = {
1812 [DHO] = {
1813 .name = "DHO",
1814 .description = "Hand-Over Process",
1815 .color = "\033[1;38m",
1816 .enabled = 1, .loglevel = LOGL_DEBUG,
1817 },
1818 [DHODEC] = {
1819 .name = "DHODEC",
1820 .description = "Hand-Over Decision",
1821 .color = "\033[1;38m",
1822 .enabled = 1, .loglevel = LOGL_DEBUG,
1823 },
1824 [DMEAS] = {
1825 .name = "DMEAS",
1826 .description = "Radio Measurement Processing",
1827 .enabled = 1, .loglevel = LOGL_DEBUG,
1828 },
1829 [DREF] = {
1830 .name = "DREF",
1831 .description = "Reference Counting",
1832 .enabled = 1, .loglevel = LOGL_DEBUG,
1833 },
1834 [DRSL] = {
1835 .name = "DRSL",
Keithd925c7c2018-04-16 13:40:07 +02001836 .description = "A-bis Radio Signalling Link (RSL)",
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001837 .color = "\033[1;35m",
1838 .enabled = 1, .loglevel = LOGL_DEBUG,
1839 },
Neels Hofmeyr31f525e2018-05-14 18:14:15 +02001840 [DRR] = {
1841 .name = "DRR",
1842 .description = "RR",
1843 .color = "\033[1;35m",
1844 .enabled = 1, .loglevel = LOGL_DEBUG,
1845 },
1846 [DRLL] = {
1847 .name = "DRLL",
1848 .description = "RLL",
1849 .color = "\033[1;35m",
1850 .enabled = 1, .loglevel = LOGL_DEBUG,
1851 },
Harald Welte3561bd42018-01-28 03:04:16 +01001852 [DMSC] = {
1853 .name = "DMSC",
1854 .description = "Mobile Switching Center",
1855 .enabled = 1, .loglevel = LOGL_DEBUG,
1856 },
Neels Hofmeyr3c5612f2018-07-11 19:53:39 +02001857 [DCHAN] = {
1858 .name = "DCHAN",
1859 .description = "lchan FSM",
1860 .color = "\033[1;32m",
1861 .enabled = 1, .loglevel = LOGL_DEBUG,
1862 },
1863 [DTS] = {
1864 .name = "DTS",
1865 .description = "timeslot FSM",
1866 .color = "\033[1;31m",
1867 .enabled = 1, .loglevel = LOGL_DEBUG,
1868 },
1869 [DAS] = {
1870 .name = "DAS",
1871 .description = "assignment FSM",
1872 .color = "\033[1;33m",
1873 .enabled = 1, .loglevel = LOGL_DEBUG,
1874 },
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001875};
1876
1877const struct log_info log_info = {
1878 .cat = log_categories,
1879 .num_cat = ARRAY_SIZE(log_categories),
1880};
1881
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01001882struct gsm_bts *bts_by_num_str(const char *num_str)
1883{
1884 struct gsm_bts *bts = gsm_bts_num(bsc_gsmnet, atoi(num_str));
1885 OSMO_ASSERT(bts);
1886 return bts;
1887}
1888
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001889int main(int argc, char **argv)
1890{
1891 char **test_case;
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001892 int i;
Neels Hofmeyr958f2592018-05-27 01:26:31 +02001893 int algorithm;
Neels Hofmeyr00727552018-02-21 14:33:15 +01001894 int test_case_i;
1895 int last_test_i;
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001896
Neels Hofmeyre3416182018-03-05 05:31:14 +01001897 ctx = talloc_named_const(NULL, 0, "handover_test");
1898 msgb_talloc_ctx_init(ctx, 0);
1899
Neels Hofmeyr00727552018-02-21 14:33:15 +01001900 test_case_i = argc > 1? atoi(argv[1]) : -1;
1901 last_test_i = ARRAY_SIZE(test_cases) - 1;
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001902
Neels Hofmeyr00727552018-02-21 14:33:15 +01001903 if (test_case_i < 0 || test_case_i > last_test_i) {
1904 for (i = 0; i <= last_test_i; i++) {
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001905 printf("Test #%d (algorithm %s):\n%s\n", i,
1906 test_cases[i][0], test_cases[i][1]);
1907 }
Neels Hofmeyr00727552018-02-21 14:33:15 +01001908 printf("\nPlease specify test case number 0..%d\n", last_test_i);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001909 return EXIT_FAILURE;
1910 }
1911
Neels Hofmeyre3416182018-03-05 05:31:14 +01001912 osmo_init_logging2(ctx, &log_info);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001913
1914 log_set_print_category(osmo_stderr_target, 1);
1915 log_set_print_category_hex(osmo_stderr_target, 0);
1916 log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_BASENAME);
Neels Hofmeyr31f525e2018-05-14 18:14:15 +02001917 osmo_fsm_log_addr(false);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001918
Neels Hofmeyr958f2592018-05-27 01:26:31 +02001919 bsc_network_alloc();
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001920 if (!bsc_gsmnet)
1921 exit(1);
1922
Neels Hofmeyr31f525e2018-05-14 18:14:15 +02001923 ts_fsm_init();
1924 lchan_fsm_init();
Neels Hofmeyr31f525e2018-05-14 18:14:15 +02001925 bsc_subscr_conn_fsm_init();
1926 handover_fsm_init();
1927
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001928 ho_set_algorithm(bsc_gsmnet->ho, 2);
1929 ho_set_ho_active(bsc_gsmnet->ho, true);
1930 ho_set_hodec2_as_active(bsc_gsmnet->ho, true);
1931 ho_set_hodec2_min_rxlev(bsc_gsmnet->ho, -100);
1932 ho_set_hodec2_rxlev_avg_win(bsc_gsmnet->ho, 1);
1933 ho_set_hodec2_rxlev_neigh_avg_win(bsc_gsmnet->ho, 1);
1934 ho_set_hodec2_rxqual_avg_win(bsc_gsmnet->ho, 10);
1935 ho_set_hodec2_pwr_hysteresis(bsc_gsmnet->ho, 3);
1936 ho_set_hodec2_pwr_interval(bsc_gsmnet->ho, 1);
1937 ho_set_hodec2_afs_bias_rxlev(bsc_gsmnet->ho, 0);
1938 ho_set_hodec2_min_rxqual(bsc_gsmnet->ho, 5);
1939 ho_set_hodec2_afs_bias_rxqual(bsc_gsmnet->ho, 0);
1940 ho_set_hodec2_max_distance(bsc_gsmnet->ho, 9999);
1941 ho_set_hodec2_ho_max(bsc_gsmnet->ho, 9999);
1942 ho_set_hodec2_penalty_max_dist(bsc_gsmnet->ho, 300);
1943 ho_set_hodec2_penalty_failed_ho(bsc_gsmnet->ho, 60);
1944 ho_set_hodec2_penalty_failed_as(bsc_gsmnet->ho, 60);
1945
Vadim Yanitskiy4f3a6412020-05-31 01:56:20 +07001946 /* We don't really need any specific model here */
1947 bts_model_unknown_init();
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001948
Neels Hofmeyr00727552018-02-21 14:33:15 +01001949 test_case = test_cases[test_case_i];
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001950
1951 fprintf(stderr, "--------------------\n");
1952 fprintf(stderr, "Performing the following test %d (algorithm %s):\n%s",
Neels Hofmeyr00727552018-02-21 14:33:15 +01001953 test_case_i, test_case[0], test_case[1]);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001954 algorithm = atoi(test_case[0]);
1955 test_case += 2;
1956 fprintf(stderr, "--------------------\n");
1957
1958 /* Disable the congestion check timer, we will trigger manually. */
1959 bsc_gsmnet->hodec2.congestion_check_interval_s = 0;
1960
1961 handover_decision_1_init();
1962 hodec2_init(bsc_gsmnet);
1963
1964 while (*test_case) {
Neels Hofmeyr4942da82020-11-12 22:58:17 +01001965 if (!strcmp(*test_case, "create-n-bts")) {
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001966 int n = atoi(test_case[1]);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001967 for (i = 0; i < n; i++)
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01001968 create_bts(1, bts_default_ts);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001969 test_case += 2;
1970 } else
Neels Hofmeyrcfbf11f2020-11-12 23:12:48 +01001971 if (!strcmp(*test_case, "create-bts")) {
1972 /* new BTS with one TRX:
1973 * "create-bts", "1", "CCCH+SDCCH4", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "TCH/H", "TCH/H", "PDCH",
1974 *
1975 * new BTS with two TRX:
1976 * "create-bts", "2", "CCCH+SDCCH4", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "TCH/H", "TCH/H", "PDCH",
1977 * "SDCCH8", "TCH/F", "TCH/F", "TCH/F", "TCH/F", "TCH/H", "TCH/H", "PDCH",
1978 */
1979 int num_trx = atoi(test_case[1]);
1980 const char * const * ts_cfg = (void*)&test_case[2];
1981 create_bts(num_trx, ts_cfg);
1982 test_case += 2 + 8 * num_trx;
1983 } else
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001984 if (!strcmp(*test_case, "as-enable")) {
1985 fprintf(stderr, "- Set assignment enable state at "
1986 "BTS %s to %s\n", test_case[1], test_case[2]);
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01001987 ho_set_hodec2_as_active(bts_by_num_str(test_case[1])->ho, atoi(test_case[2]));
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001988 test_case += 3;
1989 } else
1990 if (!strcmp(*test_case, "ho-enable")) {
1991 fprintf(stderr, "- Set handover enable state at "
1992 "BTS %s to %s\n", test_case[1], test_case[2]);
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01001993 ho_set_ho_active(bts_by_num_str(test_case[1])->ho, atoi(test_case[2]));
Neels Hofmeyr909e9722017-12-07 03:54:01 +01001994 test_case += 3;
1995 } else
1996 if (!strcmp(*test_case, "afs-rxlev-improve")) {
1997 fprintf(stderr, "- Set afs RX level improvement at "
1998 "BTS %s to %s\n", test_case[1], test_case[2]);
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01001999 ho_set_hodec2_afs_bias_rxlev(bts_by_num_str(test_case[1])->ho, atoi(test_case[2]));
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002000 test_case += 3;
2001 } else
2002 if (!strcmp(*test_case, "afs-rxqual-improve")) {
2003 fprintf(stderr, "- Set afs RX quality improvement at "
2004 "BTS %s to %s\n", test_case[1], test_case[2]);
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01002005 ho_set_hodec2_afs_bias_rxqual(bts_by_num_str(test_case[1])->ho, atoi(test_case[2]));
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002006 test_case += 3;
2007 } else
2008 if (!strcmp(*test_case, "set-min-free")) {
2009 fprintf(stderr, "- Setting minimum required free %s "
2010 "slots at BTS %s to %s\n", test_case[2],
2011 test_case[1], test_case[3]);
2012 if (!strcmp(test_case[2], "TCH/F"))
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01002013 ho_set_hodec2_tchf_min_slots(bts_by_num_str(test_case[1])->ho, atoi(test_case[3]));
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002014 else
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01002015 ho_set_hodec2_tchh_min_slots(bts_by_num_str(test_case[1])->ho, atoi(test_case[3]));
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002016 test_case += 4;
2017 } else
2018 if (!strcmp(*test_case, "set-max-ho")) {
2019 fprintf(stderr, "- Setting maximum parallel handovers "
2020 "at BTS %s to %s\n", test_case[1],
2021 test_case[2]);
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01002022 ho_set_hodec2_ho_max( bts_by_num_str(test_case[1])->ho, atoi(test_case[2]));
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002023 test_case += 3;
2024 } else
2025 if (!strcmp(*test_case, "set-max-ta")) {
2026 fprintf(stderr, "- Setting maximum timing advance "
2027 "at BTS %s to %s\n", test_case[1],
2028 test_case[2]);
Neels Hofmeyrb5a107d2020-11-12 23:00:08 +01002029 ho_set_hodec2_max_distance(bts_by_num_str(test_case[1])->ho, atoi(test_case[2]));
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002030 test_case += 3;
2031 } else
2032 if (!strcmp(*test_case, "create-ms")) {
Neels Hofmeyr7424bd22020-11-13 05:49:12 +01002033 const char *bts_nr_str = test_case[1];
2034 const char *tch_type = test_case[2];
2035 const char *codec = test_case[3];
2036 struct gsm_lchan *lchan;
2037 fprintf(stderr, "- Creating mobile at BTS %s on "
2038 "%s with %s codec\n", bts_nr_str, tch_type, codec);
2039 lchan = create_lchan(bts_by_num_str(bts_nr_str),
2040 !strcmp(tch_type, "TCH/F"), codec);
2041 if (!lchan) {
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002042 printf("Failed to create lchan!\n");
2043 return EXIT_FAILURE;
2044 }
2045 fprintf(stderr, " * New MS is at BTS %d TS %d\n",
Neels Hofmeyr7424bd22020-11-13 05:49:12 +01002046 lchan->ts->trx->bts->nr,
2047 lchan->ts->nr);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002048 test_case += 4;
2049 } else
2050 if (!strcmp(*test_case, "set-ta")) {
2051 fprintf(stderr, "- Setting maximum timing advance "
2052 "at MS %s to %s\n", test_case[1],
2053 test_case[2]);
2054 meas_ta_ms = atoi(test_case[2]);
2055 test_case += 3;
2056 } else
2057 if (!strcmp(*test_case, "meas-rep")) {
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01002058 /* meas-rep <bts-nr> <trx-nr> <ts-nr> <lchan-nr> <rxlev> <rxqual> <nr-of-neighbors> [<cell-idx> <rxlev> [...]] */
2059 int n;
2060 struct gsm_bts *bts;
2061 struct gsm_bts_trx *trx;
2062 struct gsm_bts_trx_ts *ts;
2063 struct gsm_lchan *lc;
2064 int bts_nr = atoi(test_case[1]);
2065 int trx_nr = atoi(test_case[2]);
2066 int ts_nr = atoi(test_case[3]);
2067 int ss_nr = atoi(test_case[4]);
2068 meas_dl_rxlev = atoi(test_case[5]);
2069 meas_dl_rxqual = atoi(test_case[6]);
2070 n = atoi(test_case[7]);
2071
2072 bts = gsm_bts_num(bsc_gsmnet, bts_nr);
2073 trx = gsm_bts_trx_num(bts, trx_nr);
2074 ts = &trx->ts[ts_nr];
2075 lc = &ts->lchan[ss_nr];
2076
2077 if (!lchan_state_is(lc, LCHAN_ST_ESTABLISHED)) {
2078 printf("Error: sending measurement report for %d-%d-%d-%d which is in state %s\n",
2079 bts_nr, trx_nr, ts_nr, ss_nr,
2080 lchan_state_name(lc));
2081 exit(1);
2082 }
2083
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002084 fprintf(stderr, "- Sending measurement report from "
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01002085 "%d-%d-%d-%d (rxlev=%d, rxqual=%d)\n",
2086 bts_nr, trx_nr, ts_nr, ss_nr,
2087 meas_dl_rxlev, meas_dl_rxqual);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002088 meas_num_nc = n;
Neels Hofmeyr90d4b982020-11-13 05:45:53 +01002089 test_case += 8;
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002090 for (i = 0; i < n; i++) {
2091 int nr = atoi(test_case[0]);
2092 /* since our bts is not in the list of neighbor
2093 * cells, we need to shift */
2094 if (nr >= lc->ts->trx->bts->nr)
2095 nr++;
2096 fprintf(stderr, " * Neighbor cell #%s, actual "
2097 "BTS %d (rxlev=%s)\n", test_case[0], nr,
2098 test_case[1]);
2099 meas_bcch_f_nc[i] = atoi(test_case[0]);
2100 /* bts number, not counting our own */
2101 meas_rxlev_nc[i] = atoi(test_case[1]);
2102 meas_bsic_nc[i] = 0x3f;
2103 test_case += 2;
2104 }
2105 got_chan_req = 0;
2106 gen_meas_rep(lc);
2107 } else
2108 if (!strcmp(*test_case, "congestion-check")) {
2109 fprintf(stderr, "- Triggering congestion check\n");
2110 got_chan_req = 0;
2111 if (algorithm == 2)
2112 hodec2_congestion_check(bsc_gsmnet);
2113 test_case += 1;
2114 } else
2115 if (!strcmp(*test_case, "expect-chan")) {
2116 fprintf(stderr, "- Expecting channel request at BTS %s "
2117 "TS %s\n", test_case[1], test_case[2]);
2118 if (!got_chan_req) {
2119 printf("Test failed, because no channel was "
2120 "requested\n");
2121 return EXIT_FAILURE;
2122 }
2123 fprintf(stderr, " * Got channel request at BTS %d "
2124 "TS %d\n", chan_req_lchan->ts->trx->bts->nr,
2125 chan_req_lchan->ts->nr);
2126 if (chan_req_lchan->ts->trx->bts->nr
2127 != atoi(test_case[1])) {
2128 printf("Test failed, because channel was not "
2129 "requested on expected BTS\n");
2130 return EXIT_FAILURE;
2131 }
2132 if (chan_req_lchan->ts->nr != atoi(test_case[2])) {
2133 printf("Test failed, because channel was not "
2134 "requested on expected TS\n");
2135 return EXIT_FAILURE;
2136 }
2137 test_case += 3;
2138 } else
2139 if (!strcmp(*test_case, "expect-no-chan")) {
2140 fprintf(stderr, "- Expecting no channel request\n");
2141 if (got_chan_req) {
2142 fprintf(stderr, " * Got channel request at "
2143 "BTS %d TS %d\n",
2144 chan_req_lchan->ts->trx->bts->nr,
2145 chan_req_lchan->ts->nr);
2146 printf("Test failed, because channel was "
2147 "requested\n");
2148 return EXIT_FAILURE;
2149 }
2150 fprintf(stderr, " * Got no channel request\n");
2151 test_case += 1;
2152 } else
2153 if (!strcmp(*test_case, "expect-ho")) {
2154 fprintf(stderr, "- Expecting handover/assignment "
2155 "request at BTS %s TS %s\n", test_case[1],
2156 test_case[2]);
2157 if (!got_ho_req) {
2158 printf("Test failed, because no handover was "
2159 "requested\n");
2160 return EXIT_FAILURE;
2161 }
2162 fprintf(stderr, " * Got handover/assignment request at "
2163 "BTS %d TS %d\n",
2164 ho_req_lchan->ts->trx->bts->nr,
2165 ho_req_lchan->ts->nr);
2166 if (ho_req_lchan->ts->trx->bts->nr
2167 != atoi(test_case[1])) {
2168 printf("Test failed, because "
2169 "handover/assignment was not commanded "
2170 "at the expected BTS\n");
2171 return EXIT_FAILURE;
2172 }
2173 if (ho_req_lchan->ts->nr != atoi(test_case[2])) {
2174 printf("Test failed, because "
2175 "handover/assignment was not commanded "
2176 "at the expected TS\n");
2177 return EXIT_FAILURE;
2178 }
2179 test_case += 3;
2180 } else
2181 if (!strcmp(*test_case, "ack-chan")) {
2182 fprintf(stderr, "- Acknowledging channel request\n");
2183 if (!got_chan_req) {
2184 printf("Cannot ack channel, because no "
2185 "request\n");
2186 return EXIT_FAILURE;
2187 }
2188 test_case += 1;
2189 got_ho_req = 0;
2190 send_chan_act_ack(chan_req_lchan, 1);
2191 } else
2192 if (!strcmp(*test_case, "ho-complete")) {
2193 fprintf(stderr, "- Acknowledging handover/assignment "
2194 "request\n");
2195 if (!got_chan_req) {
2196 printf("Cannot ack handover/assignment, "
2197 "because no chan request\n");
2198 return EXIT_FAILURE;
2199 }
2200 if (!got_ho_req) {
2201 printf("Cannot ack handover/assignment, "
2202 "because no ho request\n");
2203 return EXIT_FAILURE;
2204 }
2205 test_case += 1;
2206 got_chan_req = 0;
2207 got_ho_req = 0;
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002208 send_ho_complete(chan_req_lchan, true);
2209 } else
2210 if (!strcmp(*test_case, "ho-failed")) {
2211 fprintf(stderr, "- Making handover fail\n");
2212 if (!got_chan_req) {
2213 printf("Cannot fail handover, because no chan "
2214 "request\n");
2215 return EXIT_FAILURE;
2216 }
2217 test_case += 1;
2218 got_chan_req = 0;
2219 got_ho_req = 0;
2220 send_ho_complete(ho_req_lchan, false);
2221 } else
Neels Hofmeyr43666542020-11-13 01:12:34 +01002222 if (!strcmp(*test_case, "expect-ts-use")) {
2223 /* expect-ts-use <bts-nr> <trx-nr> 8x<ts-use>
2224 * e.g.
2225 * expect-ts-use 0 0 - TCH/F - - TCH/H- TCH/HH TCH/-H PDCH
2226 * TCH/F: one FR call.
2227 * TCH/H-: HR TS with first subslot used as TCH/H, other subslot unused.
2228 * TCH/HH: HR TS with both subslots used as TCH/H
2229 * TCH/-H: HR TS with only second subslot used as TCH/H
2230 * PDCH: TS used for PDCH (e.g. unused dynamic TS)
2231 */
2232 int bts_nr = atoi(test_case[1]);
2233 int trx_nr = atoi(test_case[2]);
2234 const char * const * ts_use = (void*)&test_case[3];
2235 if (!expect_ts_use(bts_nr, trx_nr, ts_use))
2236 return EXIT_FAILURE;
2237 test_case += 1 + 2 + 8;
2238 } else
Neels Hofmeyr5531fae2020-11-13 03:43:57 +01002239 if (!strcmp(*test_case, "set-ts-use")) {
2240 /* set-ts-use <bts-nr> <trx-nr> 8x<ts-use>
2241 * e.g.
2242 * set-ts-use 0 0 * TCH/F - - TCH/H- TCH/HH TCH/-H PDCH
2243 * '*': keep as is
2244 * TCH/F: one FR call.
2245 * TCH/H-: HR TS with first subslot used as TCH/H, other subslot unused.
2246 * TCH/HH: HR TS with both subslots used as TCH/H
2247 * TCH/-H: HR TS with only second subslot used as TCH/H
2248 * PDCH: TS used for PDCH (e.g. unused dynamic TS)
2249 */
2250 int bts_nr = atoi(test_case[1]);
2251 int trx_nr = atoi(test_case[2]);
2252 const char * const * ts_use = (void*)&test_case[3];
2253 if (!set_ts_use(bts_nr, trx_nr, ts_use))
2254 return EXIT_FAILURE;
2255 if (!expect_ts_use(bts_nr, trx_nr, ts_use))
2256 return EXIT_FAILURE;
2257 test_case += 1 + 2 + 8;
2258 } else
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002259 if (!strcmp(*test_case, "print")) {
2260 fprintf(stderr, "\n%s\n\n", test_case[1]);
2261 test_case += 2;
2262 } else {
2263 printf("Unknown test command '%s', please fix!\n",
2264 *test_case);
2265 return EXIT_FAILURE;
2266 }
Neels Hofmeyr31f525e2018-05-14 18:14:15 +02002267
2268 {
2269 /* Help the lchan out of releasing states */
2270 struct gsm_bts *bts;
2271 llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
2272 struct gsm_bts_trx *trx;
2273 llist_for_each_entry(trx, &bts->trx_list, list) {
2274 int ts_nr;
2275 for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
2276 struct gsm_lchan *lchan;
2277 ts_for_each_lchan(lchan, &trx->ts[ts_nr]) {
2278
2279 if (lchan->fi && lchan->fi->state == LCHAN_ST_WAIT_BEFORE_RF_RELEASE) {
2280 osmo_fsm_inst_state_chg(lchan->fi, LCHAN_ST_WAIT_RF_RELEASE_ACK, 0, 0);
2281 osmo_fsm_inst_dispatch(lchan->fi, LCHAN_EV_RSL_RF_CHAN_REL_ACK, 0);
2282 }
2283 }
2284 }
2285 }
2286 }
2287 }
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002288 }
2289
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002290 fprintf(stderr, "--------------------\n");
2291
2292 printf("Test OK\n");
2293
2294 fprintf(stderr, "--------------------\n");
2295
Neels Hofmeyre3416182018-03-05 05:31:14 +01002296 talloc_free(ctx);
Neels Hofmeyr909e9722017-12-07 03:54:01 +01002297 return EXIT_SUCCESS;
2298}
2299
2300void rtp_socket_free() {}
2301void rtp_send_frame() {}
2302void rtp_socket_upstream() {}
2303void rtp_socket_create() {}
2304void rtp_socket_connect() {}
2305void rtp_socket_proxy() {}
2306void trau_mux_unmap() {}
2307void trau_mux_map_lchan() {}
2308void trau_recv_lchan() {}
2309void trau_send_frame() {}
Harald Welte3561bd42018-01-28 03:04:16 +01002310int osmo_bsc_sigtran_send(struct gsm_subscriber_connection *conn, struct msgb *msg) { return 0; }
2311int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg) { return 0; }
Vadim Yanitskiy6a26e2c2020-08-26 18:49:08 +07002312void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause) {}
Neels Hofmeyrc19581f2018-05-27 03:05:18 +02002313void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_encr) {}
Neels Hofmeyr2001dd62020-09-11 23:35:28 +00002314int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel)
Neels Hofmeyrc19581f2018-05-27 03:05:18 +02002315{ return 0; }
Neels Hofmeyr86ce1052020-09-18 02:49:32 +02002316int bsc_paging_start(struct bsc_paging_params *params)
2317{ return 0; }
Neels Hofmeyrc19581f2018-05-27 03:05:18 +02002318void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) {}
2319void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause) {}
Neels Hofmeyrc19581f2018-05-27 03:05:18 +02002320void bsc_cm_update(struct gsm_subscriber_connection *conn,
2321 const uint8_t *cm2, uint8_t cm2_len,
2322 const uint8_t *cm3, uint8_t cm3_len) {}
Neels Hofmeyr31f525e2018-05-14 18:14:15 +02002323struct gsm0808_handover_required;
2324int bsc_tx_bssmap_ho_required(struct gsm_lchan *lchan, const struct gsm0808_cell_id_list2 *target_cells)
2325{ return 0; }
2326int bsc_tx_bssmap_ho_request_ack(struct gsm_subscriber_connection *conn, struct msgb *rr_ho_command)
2327{ return 0; }
2328int bsc_tx_bssmap_ho_detect(struct gsm_subscriber_connection *conn) { return 0; }
2329enum handover_result bsc_tx_bssmap_ho_complete(struct gsm_subscriber_connection *conn,
2330 struct gsm_lchan *lchan) { return HO_RESULT_OK; }
2331void bsc_tx_bssmap_ho_failure(struct gsm_subscriber_connection *conn) {}
Neels Hofmeyrc27ae2d2020-10-04 21:32:52 +02002332void osmo_bsc_sigtran_tx_reset(void) {}
Neels Hofmeyre95b92b2020-10-09 17:18:29 +02002333void osmo_bsc_sigtran_tx_reset_ack(void) {}
Neels Hofmeyrc27ae2d2020-10-04 21:32:52 +02002334void osmo_bsc_sigtran_reset(void) {}
2335void bssmap_reset_alloc(void) {}
2336void bssmap_reset_is_conn_ready(void) {}