From d9262b3b550d61ece3c3328608bf51e643c856eb Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 26 Oct 2013 20:12:59 +0200 Subject: [PATCH] tbf: Move gprs_rlcmac_poll_timeout into the tbf Move the gprs_rlcmac_poll_timeout method into the tbf class and gprs_rlcmac_downlink_assignment into the BTS. --- src/bts.cpp | 19 ++++++ src/bts.h | 2 + src/gprs_rlcmac.h | 2 - src/gprs_rlcmac_data.cpp | 131 +-------------------------------------- src/poll_controller.cpp | 4 +- src/tbf.cpp | 104 +++++++++++++++++++++++++++++++ src/tbf.h | 5 ++ 7 files changed, 133 insertions(+), 134 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 0e451889..8bb0f26e 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -330,6 +331,24 @@ int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn) return 0; } +void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi) +{ + int plen; + + debug_diagram(this, tbf->diag, "IMM.ASS (PCH)"); + LOGP(DRLCMAC, LOGL_INFO, "TX: START TFI: %u TLLI: 0x%08x Immediate Assignment Downlink (PCH)\n", tbf->tfi, tbf->tlli); + bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */ + bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); + /* use request reference that has maximum distance to current time, + * so the assignment will not conflict with possible RACH requests. */ + plen = Encoding::write_immediate_assignment(&m_bts, immediate_assignment, 1, 125, + (tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta, + tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, 0, tbf->tlli, poll, + tbf->poll_fn, 0, m_bts.alpha, m_bts.gamma, -1); + pcu_l1if_tx_pch(immediate_assignment, plen, imsi); + bitvec_free(immediate_assignment); +} + /* * PDCH code below. TODO: move to a separate file diff --git a/src/bts.h b/src/bts.h index 25c6473e..608f215e 100644 --- a/src/bts.h +++ b/src/bts.h @@ -170,6 +170,8 @@ public: int rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn); + void snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi); + private: int m_cur_fn; struct gprs_rlcmac_bts m_bts; diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index f5a0ee69..6184a515 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -94,8 +94,6 @@ enum gprs_rlcmac_block_type { int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf); -int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf); - int gprs_rlcmac_rcv_rach(struct gprs_rlcmac_bts *bts, uint8_t ra, uint32_t Fn, int16_t qta); struct msgb *gprs_rlcmac_send_packet_uplink_assignment( diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 00afa862..b016c764 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -46,114 +46,6 @@ extern void *tall_pcu_ctx; #define POLLING_ASSIGNMENT_UL 1 -static void gprs_rlcmac_downlink_assignment( - gprs_rlcmac_tbf *tbf, uint8_t poll, - const char *imsi); - -int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf) -{ - LOGP(DRLCMAC, LOGL_NOTICE, "Poll timeout for %s TBF=%d\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi); - - tbf->poll_state = GPRS_RLCMAC_POLL_NONE; - - if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) { - if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) { - LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " - "PACKET CONTROL ACK for PACKET UPLINK ACK\n"); - tbf->rlcmac_diag(); - tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK); - } - tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; - debug_diagram(bts->bts, tbf->diag, "timeout UL-ACK"); - if (tbf->state_is(GPRS_RLCMAC_FINISHED)) { - tbf->dir.ul.n3103++; - if (tbf->dir.ul.n3103 == bts->n3103) { - LOGP(DRLCMAC, LOGL_NOTICE, - "- N3103 exceeded\n"); - debug_diagram(bts->bts, tbf->diag, "N3103 exceeded"); - tbf_new_state(tbf, GPRS_RLCMAC_RELEASING); - tbf_timer_start(tbf, 3169, bts->t3169, 0); - return 0; - } - /* reschedule UL ack */ - tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_SEND_ACK; - } - } else - if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) { - if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) { - LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " - "PACKET CONTROL ACK for PACKET UPLINK " - "ASSIGNMENT.\n"); - tbf->rlcmac_diag(); - tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS); - } - tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; - debug_diagram(tbf->bts, tbf->diag, "timeout UL-ASS"); - tbf->n3105++; - if (tbf->n3105 == bts->n3105) { - LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); - debug_diagram(bts->bts, tbf->diag, "N3105 exceeded"); - tbf_new_state(tbf, GPRS_RLCMAC_RELEASING); - tbf_timer_start(tbf, 3195, bts->t3195, 0); - return 0; - } - /* reschedule UL assignment */ - tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; - } else - if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) { - if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) { - LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " - "PACKET CONTROL ACK for PACKET DOWNLINK " - "ASSIGNMENT.\n"); - tbf->rlcmac_diag(); - tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS); - } - tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; - debug_diagram(bts->bts, tbf->diag, "timeout DL-ASS"); - tbf->n3105++; - if (tbf->n3105 == bts->n3105) { - LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); - debug_diagram(bts->bts, tbf->diag, "N3105 exceeded"); - tbf_new_state(tbf, GPRS_RLCMAC_RELEASING); - tbf_timer_start(tbf, 3195, bts->t3195, 0); - return 0; - } - /* reschedule DL assignment */ - tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; - } else - if (tbf->direction == GPRS_RLCMAC_DL_TBF) { - if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { - LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " - "PACKET DOWNLINK ACK.\n"); - tbf->rlcmac_diag(); - tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); - } - debug_diagram(bts->bts, tbf->diag, "timeout DL-ACK"); - tbf->n3105++; - if (tbf->n3105 == bts->n3105) { - LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); - debug_diagram(bts->bts, tbf->diag, "N3105 exceeded"); - tbf_new_state(tbf, GPRS_RLCMAC_RELEASING); - tbf_timer_start(tbf, 3195, bts->t3195, 0); - return 0; - } - /* resend IMM.ASS on CCCH on timeout */ - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)) - && !(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) { - LOGP(DRLCMAC, LOGL_DEBUG, "Re-send dowlink assignment " - "for TBF=%d on PCH (IMSI=%s)\n", tbf->tfi, - tbf->dir.dl.imsi); - /* send immediate assignment */ - gprs_rlcmac_downlink_assignment(tbf, 0, tbf->dir.dl.imsi); - tbf->dir.dl.wait_confirm = 1; - } - } else - LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n"); - - return 0; -} - #ifdef DEBUG_DL_ASS_IDLE char debug_imsi[16]; #endif @@ -931,27 +823,6 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment( return msg; } -static void gprs_rlcmac_downlink_assignment( - gprs_rlcmac_tbf *tbf, uint8_t poll, - const char *imsi) -{ - gprs_rlcmac_bts *bts = tbf->bts->bts_data(); - int plen; - - debug_diagram(bts->bts, tbf->diag, "IMM.ASS (PCH)"); - LOGP(DRLCMAC, LOGL_INFO, "TX: START TFI: %u TLLI: 0x%08x Immediate Assignment Downlink (PCH)\n", tbf->tfi, tbf->tlli); - bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */ - bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); - /* use request reference that has maximum distance to current time, - * so the assignment will not conflict with possible RACH requests. */ - plen = Encoding::write_immediate_assignment(bts, immediate_assignment, 1, 125, - (tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta, - tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, 0, tbf->tlli, poll, - tbf->poll_fn, 0, bts->alpha, bts->gamma, -1); - pcu_l1if_tx_pch(immediate_assignment, plen, imsi); - bitvec_free(immediate_assignment); -} - /* depending on the current TBF, we assign on PACCH or AGCH */ void gprs_rlcmac_trigger_downlink_assignment( struct gprs_rlcmac_tbf *tbf, @@ -997,7 +868,7 @@ void gprs_rlcmac_trigger_downlink_assignment( tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH); strncpy(tbf->dir.dl.imsi, imsi, sizeof(tbf->dir.dl.imsi)); /* send immediate assignment */ - gprs_rlcmac_downlink_assignment(tbf, 0, imsi); + tbf->bts->snd_dl_ass(tbf, 0, imsi); tbf->dir.dl.wait_confirm = 1; } } diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp index 115a68f2..0f46472f 100644 --- a/src/poll_controller.cpp +++ b/src/poll_controller.cpp @@ -41,7 +41,7 @@ void PollController::expireTimedout(int frame_number) elapsed = (frame_number + 2715648 - tbf->poll_fn) % 2715648; if (elapsed >= 20 && elapsed < 2715400) - gprs_rlcmac_poll_timeout(bts, tbf); + tbf->poll_timeout(); } } llist_for_each_entry(tbf, &bts->dl_tbfs, list) { @@ -49,7 +49,7 @@ void PollController::expireTimedout(int frame_number) elapsed = (frame_number + 2715648 - tbf->poll_fn) % 2715648; if (elapsed >= 20 && elapsed < 2715400) - gprs_rlcmac_poll_timeout(bts, tbf); + tbf->poll_timeout(); } } llist_for_each_entry_safe(sba, sba2, &m_bts.sba()->m_sbas, list) { diff --git a/src/tbf.cpp b/src/tbf.cpp index 4225b3be..0321c400 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -42,6 +42,11 @@ extern void *tall_pcu_ctx; static void tbf_timer_cb(void *_tbf); +inline gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const +{ + return bts->bts_data(); +} + static inline void tbf_update_ms_class(struct gprs_rlcmac_tbf *tbf, const uint8_t ms_class) { @@ -407,6 +412,105 @@ void gprs_rlcmac_tbf::stop_timer() } } +void gprs_rlcmac_tbf::poll_timeout() +{ + LOGP(DRLCMAC, LOGL_NOTICE, "Poll timeout for %s TBF=%d\n", + (direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi); + + poll_state = GPRS_RLCMAC_POLL_NONE; + + if (ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) { + if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) { + LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " + "PACKET CONTROL ACK for PACKET UPLINK ACK\n"); + rlcmac_diag(); + state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK); + } + ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; + debug_diagram(bts, this->diag, "timeout UL-ACK"); + if (state_is(GPRS_RLCMAC_FINISHED)) { + dir.ul.n3103++; + if (dir.ul.n3103 == bts->bts_data()->n3103) { + LOGP(DRLCMAC, LOGL_NOTICE, + "- N3103 exceeded\n"); + debug_diagram(bts, diag, "N3103 exceeded"); + tbf_new_state(this, GPRS_RLCMAC_RELEASING); + tbf_timer_start(this, 3169, bts->bts_data()->t3169, 0); + return; + } + /* reschedule UL ack */ + ul_ack_state = GPRS_RLCMAC_UL_ACK_SEND_ACK; + } + } else if (ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) { + if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) { + LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " + "PACKET CONTROL ACK for PACKET UPLINK " + "ASSIGNMENT.\n"); + rlcmac_diag(); + state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS); + } + ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; + debug_diagram(bts, diag, "timeout UL-ASS"); + n3105++; + if (n3105 == bts_data()->n3105) { + LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); + debug_diagram(bts, diag, "N3105 exceeded"); + tbf_new_state(this, GPRS_RLCMAC_RELEASING); + tbf_timer_start(this, 3195, bts_data()->t3195, 0); + return; + } + /* reschedule UL assignment */ + ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; + } else if (dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) { + if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) { + LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " + "PACKET CONTROL ACK for PACKET DOWNLINK " + "ASSIGNMENT.\n"); + rlcmac_diag(); + state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS); + } + dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + debug_diagram(bts, diag, "timeout DL-ASS"); + n3105++; + if (n3105 == bts->bts_data()->n3105) { + LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); + debug_diagram(bts, diag, "N3105 exceeded"); + tbf_new_state(this, GPRS_RLCMAC_RELEASING); + tbf_timer_start(this, 3195, bts_data()->t3195, 0); + return; + } + /* reschedule DL assignment */ + dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; + } else if (direction == GPRS_RLCMAC_DL_TBF) { + if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { + LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " + "PACKET DOWNLINK ACK.\n"); + rlcmac_diag(); + state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); + } + debug_diagram(bts, diag, "timeout DL-ACK"); + n3105++; + if (n3105 == bts->bts_data()->n3105) { + LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n"); + debug_diagram(bts, diag, "N3105 exceeded"); + tbf_new_state(this, GPRS_RLCMAC_RELEASING); + tbf_timer_start(this, 3195, bts_data()->t3195, 0); + return; + } + /* resend IMM.ASS on CCCH on timeout */ + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)) + && !(state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) { + LOGP(DRLCMAC, LOGL_DEBUG, "Re-send dowlink assignment " + "for TBF=%d on PCH (IMSI=%s)\n", tfi, + dir.dl.imsi); + /* send immediate assignment */ + bts->snd_dl_ass(this, 0, dir.dl.imsi); + dir.dl.wait_confirm = 1; + } + } else + LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n"); +} + struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *old_tbf, enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx, diff --git a/src/tbf.h b/src/tbf.h index 0f8e77d1..4afc6498 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -106,6 +106,8 @@ struct gprs_rlcmac_tbf { void stop_timer(); void stop_t3191(); + void poll_timeout(); + struct llist_head list; uint32_t state_flags; enum gprs_rlcmac_tbf_direction direction; @@ -207,6 +209,9 @@ struct gprs_rlcmac_tbf { /* store the BTS this TBF belongs to */ BTS *bts; + +protected: + gprs_rlcmac_bts *bts_data() const; };