aboutsummaryrefslogtreecommitdiffstats
path: root/tests/alloc/AllocTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/alloc/AllocTest.cpp')
-rw-r--r--tests/alloc/AllocTest.cpp200
1 files changed, 135 insertions, 65 deletions
diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp
index 35bbfc4d..8d833f54 100644
--- a/tests/alloc/AllocTest.cpp
+++ b/tests/alloc/AllocTest.cpp
@@ -11,10 +11,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "gprs_rlcmac.h"
@@ -31,6 +27,7 @@
extern "C" {
#include "mslot_class.h"
+#include "alloc_algo.h"
#include <osmocom/core/application.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
@@ -43,16 +40,59 @@ void *tall_pcu_ctx;
int16_t spoof_mnc = 0, spoof_mcc = 0;
bool spoof_mnc_3_digits = false;
+/* override, requires '-Wl,--wrap=pcu_sock_send' */
+int __real_pcu_sock_send(struct msgb *msg);
+extern "C" int __wrap_pcu_sock_send(struct msgb *msg)
+{
+ return 0;
+}
+
static gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts,
GprsMs *ms, gprs_rlcmac_tbf_direction dir,
uint8_t use_trx, bool single_slot)
{
OSMO_ASSERT(ms != NULL);
- if (dir == GPRS_RLCMAC_UL_TBF)
- return tbf_alloc_ul_tbf(bts, ms, use_trx, single_slot);
- else
- return tbf_alloc_dl_tbf(bts, ms, use_trx, single_slot);
+ const struct alloc_resources_req req = {
+ .bts = bts,
+ .ms = ms,
+ .direction = dir,
+ .single = single_slot,
+ .use_trx = (int8_t)use_trx,
+ };
+ struct alloc_resources_res res = {};
+ int rc;
+
+ rc = the_pcu->alloc_algorithm(&req, &res);
+ if (rc < 0) {
+ LOGPMS(ms, DTBF, LOGL_NOTICE,
+ "Timeslot Allocation failed: trx = %d, single_slot = %d\n",
+ req.use_trx, req.single);
+ bts_do_rate_ctr_inc(ms->bts, CTR_TBF_ALLOC_FAIL);
+ return NULL;
+ }
+
+ /* Update MS, really allocate the resources */
+ if (res.reserved_ul_slots != ms_reserved_ul_slots(ms) ||
+ res.reserved_dl_slots != ms_reserved_dl_slots(ms)) {
+ /* The reserved slots have changed, update the MS */
+ ms_set_reserved_slots(ms, res.trx, res.reserved_ul_slots, res.reserved_dl_slots);
+ }
+ ms_set_first_common_ts(ms, res.first_common_ts);
+
+ if (dir == GPRS_RLCMAC_UL_TBF) {
+ struct gprs_rlcmac_ul_tbf *ul_tbf;
+ ul_tbf = ul_tbf_alloc(bts, ms);
+ ul_tbf_apply_allocated_resources(ul_tbf, &res);
+ ms_attach_tbf(ms, ul_tbf_as_tbf(ul_tbf));
+ return ul_tbf;
+ } else {
+ struct gprs_rlcmac_dl_tbf *dl_tbf;
+ dl_tbf = dl_tbf_alloc(bts, ms);
+ dl_tbf_apply_allocated_resources(dl_tbf, &res);
+ ms_attach_tbf(ms, dl_tbf_as_tbf(dl_tbf));
+ return dl_tbf;
+ }
}
static void check_tfi_usage(struct gprs_rlcmac_bts *bts)
@@ -138,8 +178,9 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir,
* least this part is working okay.
*/
for (i = 0; i < (int)ARRAY_SIZE(tbfs); ++i) {
- ms = bts_alloc_ms(bts, 0, 0);
+ ms = ms_alloc(bts, __func__);
tbfs[i] = tbf_alloc(bts, ms, dir, -1, 0);
+ ms_unref(ms, __func__);
if (tbfs[i] == NULL)
break;
@@ -152,11 +193,13 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir,
OSMO_ASSERT(i == count);
+ OSMO_ASSERT(bts_all_pdch_allocated(bts));
+
for (i = 0; i < count; ++i)
if (tbfs[i])
tbf_free(tbfs[i]);
- ms = bts_alloc_ms(bts, 0, 0);
+ ms = ms_alloc(bts, NULL);
tbfs[0] = tbf_alloc(bts, ms, dir, -1, 0);
OSMO_ASSERT(tbfs[0]);
tbf_free(tbfs[0]);
@@ -178,12 +221,14 @@ static void dump_assignment(struct gprs_rlcmac_tbf *tbf, const char *dir, bool v
{
if (!verbose)
return;
+ const struct GprsMs *ms = tbf_ms(tbf);
+ const struct gprs_rlcmac_pdch *first_common = ms_first_common_ts(ms);
for (size_t i = 0; i < ARRAY_SIZE(tbf->pdch); ++i)
if (tbf->pdch[i])
printf("PDCH[%zu] is used for %s\n", i, dir);
- printf("PDCH[%d] is control_ts for %s\n", tbf->control_ts, dir);
- printf("PDCH[%d] is first common for %s\n", tbf->first_common_ts, dir);
+ printf("%s is control_ts for %s\n", tbf->control_ts ? pdch_name(tbf->control_ts) : "(none)", dir);
+ printf("%s is first common for %s\n", first_common ? pdch_name(first_common) : "(none)", dir);
}
#define ENABLE_PDCH(ts_no, enable_flag, trx) \
@@ -220,12 +265,15 @@ static inline bool test_alloc_b_ul_dl(bool ts0, bool ts1, bool ts2, bool ts3, bo
enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);
- ms = bts_alloc_ms(bts, ms_class, 0);
+ ms = ms_alloc(bts, __func__);
+ ms_set_ms_class(ms, ms_class);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
- ms_set_timeout(ms, 0);
- ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, true);
- if (!ul_tbf)
+ OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S) == 0);
+ ul_tbf = (gprs_rlcmac_ul_tbf *)tbf_alloc(bts, ms, GPRS_RLCMAC_UL_TBF, -1, true);
+ if (!ul_tbf) {
+ ms_unref(ms, __func__);
return false;
+ }
OSMO_ASSERT(ul_tbf->ms());
OSMO_ASSERT(ms_current_trx(ul_tbf->ms()));
@@ -233,16 +281,17 @@ static inline bool test_alloc_b_ul_dl(bool ts0, bool ts1, bool ts2, bool ts3, bo
dump_assignment(ul_tbf, "UL", verbose);
/* assume final ack has not been sent */
- dl_tbf = tbf_alloc_dl_tbf(bts, ms, ms_current_trx(ms)->trx_no, false);
- if (!dl_tbf)
+ dl_tbf = (gprs_rlcmac_dl_tbf *)tbf_alloc(bts, ms, GPRS_RLCMAC_DL_TBF, ms_current_trx(ms)->trx_no, false);
+ if (!dl_tbf) {
+ ms_unref(ms, __func__);
return false;
+ }
dump_assignment(dl_tbf, "DL", verbose);
- OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
-
check_tfi_usage(bts);
+ ms_unref(ms, __func__);
tbf_free(dl_tbf);
tbf_free(ul_tbf);
talloc_free(bts);
@@ -264,37 +313,40 @@ static inline bool test_alloc_b_dl_ul(bool ts0, bool ts1, bool ts2, bool ts3, bo
enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);
- ms = bts_alloc_ms(bts, ms_class, 0);
+ ms = ms_alloc(bts, __func__);
+ ms_set_ms_class(ms, ms_class);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
- ms_set_timeout(ms, 0);
- dl_tbf = tbf_alloc_dl_tbf(bts, ms, -1, true);
- if (!dl_tbf)
+ OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S) == 0);
+ dl_tbf = (gprs_rlcmac_dl_tbf *)tbf_alloc(bts, ms, GPRS_RLCMAC_DL_TBF, -1, true);
+ if (!dl_tbf) {
+ ms_unref(ms, __func__);
return false;
+ }
- dl_tbf->update_ms(0x23, GPRS_RLCMAC_DL_TBF);
+ ms_confirm_tlli(ms, 0x23);
OSMO_ASSERT(dl_tbf->ms() == ms);
OSMO_ASSERT(ms_current_trx(dl_tbf->ms()));
dump_assignment(dl_tbf, "DL", verbose);
- ul_tbf = tbf_alloc_ul_tbf(bts, ms, ms_current_trx(ms)->trx_no, false);
- if (!ul_tbf)
+ ul_tbf = (gprs_rlcmac_ul_tbf *)tbf_alloc(bts, ms, GPRS_RLCMAC_UL_TBF, ms_current_trx(ms)->trx_no, false);
+ if (!ul_tbf) {
+ ms_unref(ms, __func__);
return false;
+ }
- ul_tbf->update_ms(0x23, GPRS_RLCMAC_UL_TBF);
- ul_tbf->m_contention_resolution_done = 1;
+ ms_update_announced_tlli(ms, 0x23);
+ ul_tbf->m_contention_resolution_done = true;
dump_assignment(ul_tbf, "UL", verbose);
- OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
-
- /* now update the dl_tbf */
- dl_tbf->update();
+ /* now upgrade the dl_tbf */
+ OSMO_ASSERT(dl_tbf_upgrade_to_multislot(dl_tbf) == 0);
dump_assignment(dl_tbf, "DL", verbose);
- OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
check_tfi_usage(bts);
+ ms_unref(ms, __func__);
tbf_free(dl_tbf);
tbf_free(ul_tbf);
talloc_free(bts);
@@ -317,12 +369,15 @@ static inline bool test_alloc_b_jolly(uint8_t ms_class)
tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1);
OSMO_ASSERT(tfi >= 0);
- ms = bts_alloc_ms(bts, ms_class, 0);
+ ms = ms_alloc(bts, __func__);
+ ms_set_ms_class(ms, ms_class);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
- ms_set_timeout(ms, 0);
- ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, false);
- if (!ul_tbf)
+ OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S) == 0);
+ ul_tbf = tbf_alloc(bts, ms, GPRS_RLCMAC_UL_TBF, -1, false);
+ if (!ul_tbf) {
+ ms_unref(ms, __func__);
return false;
+ }
OSMO_ASSERT(ul_tbf->ms() == ms);
OSMO_ASSERT(ms_current_trx(ul_tbf->ms()));
@@ -330,16 +385,17 @@ static inline bool test_alloc_b_jolly(uint8_t ms_class)
dump_assignment(ul_tbf, "UL", true);
/* assume final ack has not been sent */
- dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, false);
- if (!dl_tbf)
+ dl_tbf = tbf_alloc(bts, ms, GPRS_RLCMAC_DL_TBF, trx_no, false);
+ if (!dl_tbf) {
+ ms_unref(ms, __func__);
return false;
+ }
dump_assignment(dl_tbf, "DL", true);
- OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts);
-
check_tfi_usage(bts);
+ ms_unref(ms, __func__);
tbf_free(dl_tbf);
tbf_free(ul_tbf);
talloc_free(bts);
@@ -468,7 +524,7 @@ static GprsMs *alloc_tbfs(struct gprs_rlcmac_bts *bts, struct GprsMs *old_ms, en
if (ms_current_trx(old_ms))
trx_no = ms_current_trx(old_ms)->trx_no;
- ms_ref(old_ms);
+ ms_ref(old_ms, __func__);
/* Allocate what is needed first */
switch (mode) {
@@ -477,9 +533,10 @@ static GprsMs *alloc_tbfs(struct gprs_rlcmac_bts *bts, struct GprsMs *old_ms, en
case TEST_MODE_UL_AND_DL:
if (ms_ul_tbf(old_ms))
tbf_free(ms_ul_tbf(old_ms));
- tbf = tbf_alloc_ul_tbf(bts, old_ms, trx_no, false);
+ tbf = tbf_alloc(bts, old_ms, GPRS_RLCMAC_UL_TBF, trx_no, false);
if (tbf == NULL) {
- ms_unref(old_ms);
+ OSMO_ASSERT(trx_no != -1 || bts_all_pdch_allocated(bts));
+ ms_unref(old_ms, __func__);
return NULL;
}
break;
@@ -488,9 +545,10 @@ static GprsMs *alloc_tbfs(struct gprs_rlcmac_bts *bts, struct GprsMs *old_ms, en
case TEST_MODE_DL_AND_UL:
if (ms_dl_tbf(old_ms))
tbf_free(ms_dl_tbf(old_ms));
- tbf = tbf_alloc_dl_tbf(bts, old_ms, trx_no, false);
+ tbf = tbf_alloc(bts, old_ms, GPRS_RLCMAC_DL_TBF, trx_no, false);
if (tbf == NULL) {
- ms_unref(old_ms);
+ OSMO_ASSERT(trx_no != -1 || bts_all_pdch_allocated(bts));
+ ms_unref(old_ms, __func__);
return NULL;
}
}
@@ -500,7 +558,7 @@ static GprsMs *alloc_tbfs(struct gprs_rlcmac_bts *bts, struct GprsMs *old_ms, en
OSMO_ASSERT(old_ms == tbf->ms());
ms = tbf->ms();
- ms_ref(ms);
+ ms_ref(ms, __func__);
new_ms = ms;
/* Continue with what is needed next */
switch (mode) {
@@ -535,8 +593,8 @@ static GprsMs *alloc_tbfs(struct gprs_rlcmac_bts *bts, struct GprsMs *old_ms, en
if (!new_ms && tbf)
tbf_free(tbf);
- ms_unref(old_ms);
- ms_unref(ms);
+ ms_unref(old_ms, __func__);
+ ms_unref(ms, __func__);
return new_ms;
}
@@ -560,9 +618,9 @@ static unsigned alloc_many_tbfs(struct gprs_rlcmac_bts *bts, unsigned min_class,
enum gprs_rlcmac_tbf_direction dir;
uint32_t tlli = counter + 0xc0000000;
- ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
+ ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI);
if (!ms)
- ms = bts_alloc_ms(bts, 0, 0);
+ ms = ms_alloc(bts, NULL);
ms_set_ms_class(ms, ms_class);
ms = alloc_tbfs(bts, ms, mode);
if (!ms)
@@ -575,13 +633,13 @@ static unsigned alloc_many_tbfs(struct gprs_rlcmac_bts *bts, unsigned min_class,
trx = ms_current_trx(ms);
OSMO_ASSERT(ul_tbf || dl_tbf);
-
+ OSMO_ASSERT(ms_first_common_ts(ms) != NULL);
if (ul_tbf) {
- ul_slots = 1 << ul_tbf->first_common_ts;
+ ul_slots = 1 << (uint8_t)ms_first_common_ts(ms)->ts_no;
tfi = ul_tbf->tfi();
dir = GPRS_RLCMAC_UL_TBF;
} else {
- ul_slots = 1 << dl_tbf->first_common_ts;
+ ul_slots = 1 << (uint8_t)ms_first_common_ts(ms)->ts_no;
tfi = dl_tbf->tfi();
dir = GPRS_RLCMAC_DL_TBF;
}
@@ -771,8 +829,10 @@ static void test_2_consecutive_dl_tbfs()
trx->pdch[6].enable();
trx->pdch[7].enable();
- ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
- dl_tbf1 = tbf_alloc_dl_tbf(bts, ms, 0, false);
+ ms = ms_alloc(bts, NULL);
+ ms_set_ms_class(ms, ms_class);
+ ms_set_egprs_ms_class(ms, egprs_ms_class);
+ dl_tbf1 = tbf_alloc(bts, ms, GPRS_RLCMAC_DL_TBF, 0, false);
OSMO_ASSERT(dl_tbf1);
for (int i = 0; i < 8; i++) {
@@ -782,8 +842,10 @@ static void test_2_consecutive_dl_tbfs()
OSMO_ASSERT(numTs1 == 4);
printf("TBF1: numTs(%d)\n", numTs1);
- ms = bts_alloc_ms(bts, ms_class, egprs_ms_class);
- dl_tbf2 = tbf_alloc_dl_tbf(bts, ms, 0, false);
+ ms = ms_alloc(bts, NULL);
+ ms_set_ms_class(ms, ms_class);
+ ms_set_egprs_ms_class(ms, egprs_ms_class);
+ dl_tbf2 = tbf_alloc(bts, ms, GPRS_RLCMAC_DL_TBF, 0, false);
OSMO_ASSERT(dl_tbf2);
for (int i = 0; i < 8; i++) {
@@ -806,15 +868,22 @@ static void test_2_consecutive_dl_tbfs()
static void test_bts_pch_timer(void)
{
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
- const char *imsi1 = "1234";
- const char *imsi2 = "5678";
+ struct osmo_mobile_identity mi_imsi1, mi_imsi2;
+ struct osmo_mobile_identity mi_tmsi1;
+ mi_imsi1.type = mi_imsi2.type = GSM_MI_TYPE_IMSI;
+ mi_tmsi1.type = GSM_MI_TYPE_TMSI;
+ OSMO_STRLCPY_ARRAY(mi_imsi1.imsi, "1234");
+ OSMO_STRLCPY_ARRAY(mi_imsi2.imsi, "5678");
+ mi_tmsi1.tmsi = 987654321;
fprintf(stderr, "Testing bts_pch_timer dealloc on bts dealloc\n");
log_set_category_filter(osmo_stderr_target, DPCU, 1, LOGL_DEBUG);
fprintf(stderr, "Starting PCH timer for 2 IMSI\n");
- bts_pch_timer_start(bts, imsi1);
- bts_pch_timer_start(bts, imsi2);
+ bts_pch_timer_start(bts, &mi_imsi1, mi_imsi1.imsi);
+ bts_pch_timer_start(bts, &mi_imsi2, mi_imsi2.imsi);
+ fprintf(stderr, "Starting PCH timer for 1 TMSI\n");
+ bts_pch_timer_start(bts, &mi_tmsi1, "6666");
fprintf(stderr, "Deallocating BTS, expecting the PCH timer to be stopped and deallocated\n");
talloc_free(bts);
@@ -858,6 +927,7 @@ int main(int argc, char **argv)
extern "C" {
void l1if_pdch_req() { abort(); }
void l1if_connect_pdch() { abort(); }
-void l1if_close_pdch() { abort(); }
-void l1if_open_pdch() { abort(); }
+void l1if_disconnect_pdch() { abort(); }
+void l1if_close_trx() { abort(); }
+void l1if_open_trx() { abort(); }
}