/* * TbfTest.cpp * * Copyright (C) 2013 by Holger Hans Peter Freyther * * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * */ #include "bts.h" #include "tbf.h" #include "gprs_debug.h" extern "C" { #include #include #include #include } void *tall_pcu_ctx; int16_t spoof_mnc = 0, spoof_mcc = 0; static void test_tbf_tlli_update() { BTS the_bts; the_bts.bts_data()->alloc_algorithm = alloc_algorithm_a; the_bts.bts_data()->trx[0].pdch[2].enable(); the_bts.bts_data()->trx[0].pdch[3].enable(); /* * Make a uplink and downlink allocation */ gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(the_bts.bts_data(), NULL, 0, 0, 0, 0); dl_tbf->update_tlli(0x2342); dl_tbf->tlli_mark_valid(); dl_tbf->ta = 4; the_bts.timing_advance()->remember(0x2342, dl_tbf->ta); gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(the_bts.bts_data(), ul_tbf, 0, 0, 0, 0); ul_tbf->update_tlli(0x2342); ul_tbf->tlli_mark_valid(); OSMO_ASSERT(the_bts.dl_tbf_by_tlli(0x2342) == dl_tbf); OSMO_ASSERT(the_bts.ul_tbf_by_tlli(0x2342) == ul_tbf); /* * Now check.. that DL changes and that the timing advance * has changed. */ dl_tbf->update_tlli(0x4232); OSMO_ASSERT(!the_bts.dl_tbf_by_tlli(0x2342)); OSMO_ASSERT(!the_bts.ul_tbf_by_tlli(0x2342)); OSMO_ASSERT(the_bts.dl_tbf_by_tlli(0x4232) == dl_tbf); OSMO_ASSERT(the_bts.ul_tbf_by_tlli(0x4232) == ul_tbf); OSMO_ASSERT(the_bts.timing_advance()->recall(0x4232) == 4); } static uint8_t llc_data[200]; int pcu_sock_send(struct msgb *msg) { return 0; } static void test_tbf_final_ack() { BTS the_bts; gprs_rlcmac_bts *bts; gprs_rlcmac_trx *trx; gprs_rlcmac_pdch * pdch; int tfi, i; uint8_t ts_no, trx_no; uint8_t ms_class = 45; uint32_t fn; uint8_t rbb[64/8]; struct msgb *dl_msg; gprs_rlcmac_dl_tbf *dl_tbf; gprs_rlcmac_tbf *new_tbf; bts = the_bts.bts_data(); bts->alloc_algorithm = alloc_algorithm_a; trx = &bts->trx[0]; ts_no = 4; trx->pdch[ts_no].enable(); pdch = &trx->pdch[ts_no]; tfi = the_bts.tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); dl_tbf = tbf_alloc_dl_tbf(bts, NULL, tfi, trx_no, ms_class, 1); OSMO_ASSERT(dl_tbf); /* "Establish" the DL TBF */ dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; dl_tbf->set_state(GPRS_RLCMAC_FLOW); dl_tbf->m_wait_confirm = 0; dl_tbf->set_new_tbf(dl_tbf); for (i = 0; i < sizeof(llc_data); i++) llc_data[i] = i%256; /* Schedule two blocks */ dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data)); dl_tbf->append_data(ms_class, 1000, llc_data, sizeof(llc_data)); /* FIXME: Need correct frame number here? */ fn = 0; for (; fn < 3; fn++) { /* Request to send one block */ gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, 0, fn, 0); } /* Queue a final ACK */ memset(rbb, 0, sizeof(rbb)); /* Receive a final ACK */ dl_tbf->rcvd_dl_ack(1, 1, rbb); /* Clean up and ensure tbfs are in the correct state */ OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)); new_tbf = dl_tbf->new_tbf(); OSMO_ASSERT(new_tbf != dl_tbf); OSMO_ASSERT(new_tbf->tfi() == 1); dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; tbf_free(dl_tbf); tbf_free(new_tbf); } static const struct log_info_cat default_categories[] = { {"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0}, {"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1}, {"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_DEBUG, 1}, {"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_DEBUG, 1}, {"DRLCMACDL", "\033[1;33m", "GPRS RLC/MAC layer Downlink (RLCMAC)", LOGL_DEBUG, 1}, {"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_DEBUG, 1}, {"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_DEBUG, 1}, {"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1}, {"DBSSGP","\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO , 1}, {"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1}, }; static int filter_fn(const struct log_context *ctx, struct log_target *tar) { return 1; } const struct log_info debug_log_info = { filter_fn, (struct log_info_cat*)default_categories, ARRAY_SIZE(default_categories), }; int main(int argc, char **argv) { tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile TbfTest context"); if (!tall_pcu_ctx) abort(); msgb_set_talloc_ctx(tall_pcu_ctx); osmo_init_logging(&debug_log_info); log_set_use_color(osmo_stderr_target, 0); log_set_print_filename(osmo_stderr_target, 0); test_tbf_tlli_update(); test_tbf_final_ack(); return EXIT_SUCCESS; } /* * stubs that should not be reached */ extern "C" { void l1if_pdch_req() { abort(); } void l1if_connect_pdch() { abort(); } void l1if_close_pdch() { abort(); } void l1if_open_pdch() { abort(); } }