diff --git a/TODO b/TODO index f004cdc9..f2ed92d1 100644 --- a/TODO +++ b/TODO @@ -4,4 +4,6 @@ * Group more into in classes.. remove bts pointers. * Change functions with 100 parameters to get a struct as param * Move move into the TBF class -* Replace trx/ts with +* Replace trx/ts with pointers. E.g. a PDCH should know the trx + it is on... then we can omit trx, ts and parameters and just pass + the pdch. diff --git a/src/bts.cpp b/src/bts.cpp index 29cd3e5d..ca012883 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -20,6 +20,13 @@ #include #include +#include + +#include + +extern "C" { + #include +} #include @@ -53,3 +60,40 @@ void BTS::set_current_frame_number(int fn) m_cur_fn = fn; m_pollController.expireTimedout(m_cur_fn); } + +void gprs_rlcmac_pdch::enable() +{ + /* TODO: Check if there are still allocated resources.. */ + INIT_LLIST_HEAD(&paging_list); + m_is_enabled = 1; +} + +void gprs_rlcmac_pdch::disable() +{ + /* TODO.. kick free_resources once we know the TRX/TS we are on */ + m_is_enabled = 0; +} + +void gprs_rlcmac_pdch::free_resources(uint8_t trx, uint8_t ts) +{ + struct gprs_rlcmac_paging *pag; + struct gprs_rlcmac_sba *sba, *sba2; + + /* we are not enabled. there should be no resources */ + if (!is_enabled()) + return; + + /* kick all TBF on slot */ + gprs_rlcmac_tbf::free_all(this); + + /* flush all pending paging messages */ + while ((pag = gprs_rlcmac_dequeue_paging(this))) + talloc_free(pag); + + llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) { + if (sba->trx == trx && sba->ts == ts) { + llist_del(&sba->list); + talloc_free(sba); + } + } +} diff --git a/src/bts.h b/src/bts.h index 4babd25a..8e88bc93 100644 --- a/src/bts.h +++ b/src/bts.h @@ -39,7 +39,17 @@ struct BTS; * PDCH instance */ struct gprs_rlcmac_pdch { - uint8_t enable; /* TS is enabled */ +#ifdef __cplusplus + /* TODO: the PDCH should know the trx/ts it belongs to */ + void free_resources(uint8_t trx, uint8_t ts); + + bool is_enabled() const; + + void enable(); + void disable(); +#endif + + uint8_t m_is_enabled; /* TS is enabled */ uint8_t tsc; /* TSC of this slot */ uint8_t next_ul_tfi; /* next uplink TBF/TFI to schedule (0..31) */ uint8_t next_dl_tfi; /* next downlink TBF/TFI to schedule (0..31) */ @@ -135,4 +145,9 @@ extern "C" { struct gprs_rlcmac_bts *bts_main_data(); #ifdef __cplusplus } + +inline bool gprs_rlcmac_pdch::is_enabled() const +{ + return m_is_enabled; +} #endif diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 77264816..e83de21f 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -149,7 +149,7 @@ int tfi_find_free(struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction di for (trx = trx_from; trx <= trx_to; trx++) { for (ts = 0; ts < 8; ts++) { pdch = &bts->trx[trx].pdch[ts]; - if (!pdch->enable) + if (!pdch->is_enabled()) continue; break; } @@ -205,7 +205,7 @@ int sba_alloc(struct gprs_rlcmac_bts *bts, for (trx = 0; trx < 8; trx++) { for (ts = 0; ts < 8; ts++) { pdch = &bts->trx[trx].pdch[ts]; - if (!pdch->enable) + if (!pdch->is_enabled()) continue; break; } diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 67946df6..c0154fc5 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -241,7 +241,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, return -EINVAL; pdch = &bts->trx[trx].pdch[ts]; - if (!pdch->enable) { + if (!pdch->is_enabled()) { LOGP(DRLCMACSCHED, LOGL_ERROR, "Received RTS on disabled PDCH: " "TRX=%d TS=%d\n", trx, ts); return -EIO; diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index e5ca5b65..bf69296d 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -104,7 +104,7 @@ static int find_enabled_pdch(struct gprs_rlcmac_trx *trx, const uint8_t start_ts struct gprs_rlcmac_pdch *pdch; pdch = &trx->pdch[ts]; - if (!pdch->enable) { + if (!pdch->is_enabled()) { LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because " "not enabled\n", ts); continue; @@ -265,7 +265,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, for (ts = 0, i = 0; ts < 8; ts++) { pdch = &tbf->trx->pdch[ts]; /* check if enabled */ - if (!pdch->enable) { + if (!pdch->is_enabled()) { LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because " "not enabled\n", ts); /* increase window for Type 1 */ @@ -421,7 +421,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) { pdch = &tbf->trx->pdch[ts]; /* check if enabled */ - if (!pdch->enable) { + if (!pdch->is_enabled()) { LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " "because not enabled\n", ts); continue; @@ -493,7 +493,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) { pdch = &tbf->trx->pdch[ts]; /* check if enabled */ - if (!pdch->enable) { + if (!pdch->is_enabled()) { LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " "because not enabled\n", ts); continue; diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 438bfa86..49c91477 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -295,28 +295,6 @@ static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind) return rc; } -int flush_pdch(struct gprs_rlcmac_pdch *pdch, uint8_t trx, uint8_t ts) -{ - struct gprs_rlcmac_paging *pag; - struct gprs_rlcmac_sba *sba, *sba2; - - /* kick all TBF on slot */ - gprs_rlcmac_tbf::free_all(pdch); - - /* flush all pending paging messages */ - while ((pag = gprs_rlcmac_dequeue_paging(pdch))) - talloc_free(pag); - - llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) { - if (sba->trx == trx && sba->ts == ts) { - llist_del(&sba->list); - talloc_free(sba); - } - } - - return 0; -} - static int pcu_rx_info_ind(struct gsm_pcu_if_info_ind *info_ind) { struct gprs_rlcmac_bts *bts = bts_main_data(); @@ -342,11 +320,8 @@ bssgp_failed: /* free all TBF */ for (trx = 0; trx < 8; trx++) { bts->trx[trx].arfcn = info_ind->trx[trx].arfcn; - for (ts = 0; ts < 8; ts++) { - if (bts->trx[trx].pdch[ts].enable) - flush_pdch(&bts->trx[trx].pdch[ts], - trx, ts); - } + for (ts = 0; ts < 8; ts++) + bts->trx[trx].pdch[ts].free_resources(trx, ts); } gprs_bssgp_destroy_or_exit(); return 0; @@ -465,7 +440,7 @@ bssgp_failed: pdch = &bts->trx[trx].pdch[ts]; if ((info_ind->trx[trx].pdch_mask & (1 << ts))) { /* FIXME: activate dynamically at RLCMAC */ - if (!pdch->enable) { + if (!pdch->is_enabled()) { #ifdef ENABLE_SYSMODSP if ((info_ind->flags & PCU_IF_FLAG_SYSMO)) @@ -473,17 +448,16 @@ bssgp_failed: bts->trx[trx].fl1h, ts); #endif pcu_tx_act_req(trx, ts, 1); - INIT_LLIST_HEAD(&pdch->paging_list); - pdch->enable = 1; + pdch->enable(); } pdch->tsc = info_ind->trx[trx].tsc[ts]; LOGP(DL1IF, LOGL_INFO, "PDCH: trx=%d ts=%d\n", trx, ts); } else { - if (pdch->enable) { + if (pdch->is_enabled()) { pcu_tx_act_req(trx, ts, 0); - pdch->enable = 0; - flush_pdch(pdch, trx, ts); + pdch->free_resources(trx, ts); + pdch->disable(); } } } diff --git a/src/sysmo_sock.cpp b/src/sysmo_sock.cpp index 2852c0e1..6af2e9ab 100644 --- a/src/sysmo_sock.cpp +++ b/src/sysmo_sock.cpp @@ -106,7 +106,8 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost) } #endif for (ts = 0; ts < 8; ts++) - bts->trx[trx].pdch[ts].enable = 0; + bts->trx[trx].pdch[ts].disable(); +#warning "NOT ALL RESOURCES are freed in this case... inconsistent with the other code. Share the code with pcu_l1if.c for the reset." gprs_rlcmac_tbf::free_all(&bts->trx[trx]); } diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index 3b75763a..2117b11a 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -48,8 +48,8 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count) bts.alloc_algorithm = alloc_algorithm_a; struct gprs_rlcmac_trx *trx = &bts.trx[0]; - trx->pdch[2].enable = 1; - trx->pdch[3].enable = 1; + trx->pdch[2].enable(); + trx->pdch[3].enable(); /** * Currently alloc_a will only allocate from the first