diff options
author | Max <msuraev@sysmocom.de> | 2016-02-12 14:59:00 +0100 |
---|---|---|
committer | Max <msuraev@sysmocom.de> | 2016-02-12 14:59:00 +0100 |
commit | 48301471dd33e6b3c85bb43ab09b25ff168e253d (patch) | |
tree | 967ab27b37b47259b649ef17103e6cb2afa62418 | |
parent | a5ae651ee47f56301eaf1b344d9c1da13e3bd643 (diff) |
todo
Signed-off-by: Max <msuraev@sysmocom.de>
-rw-r--r-- | src/bts.cpp | 15 | ||||
-rw-r--r-- | src/gprs_rlcmac_sched.cpp | 21 | ||||
-rw-r--r-- | src/tbf.cpp | 171 | ||||
-rw-r--r-- | src/tbf.h | 8 |
4 files changed, 187 insertions, 28 deletions
diff --git a/src/bts.cpp b/src/bts.cpp index ca9776c2..277726d6 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -196,13 +196,13 @@ void BTS::set_current_block_frame_number(int fn, unsigned max_delay) if (current_frame_number() != 0) delay = (fn + 2715648 * 3 / 2 - current_frame_number()) % 2715648 - 2715648/2; -/* if (delay <= -late_block_delay_thresh) { + if (delay <= -late_block_delay_thresh) { LOGP(DRLCMAC, LOGL_NOTICE, "Late RLC block, FN delta: %d FN: %d curFN: %d\n", delay, fn, current_frame_number()); rlc_late_block(); } -FIXME - enable back before committing*/ + m_cur_blk_fn = fn; if (delay < fn_update_ok_min_delay || delay > fn_update_ok_max_delay || current_frame_number() == 0) @@ -560,18 +560,19 @@ void BTS::trigger_dl_ts_recon(gprs_rlcmac_dl_tbf *dl_tbf)//FIXME: no actual send /* stop pending timer */ dl_tbf->stop_timer(); - LOGP(DRLCMAC, LOGL_DEBUG, "PTSR: Send TS RECONFIGURE for %s on PCH (IMSI=%s)\n", tbf_name(dl_tbf), dl_tbf->imsi()); + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: Send TS RECONFIGURE for %s on PCH (IMSI=%s)\n", tbf_name(dl_tbf), dl_tbf->imsi()); // FIXME: change state - dl_ass_state vs tbf->state vs state_flags + /* change state */ dl_tbf->set_state(GPRS_RLCMAC_RECONFIGURING); // FIXME - more flags? if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) // FIXME: are we doing it right here? dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); - dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; - //tbf->was_releasing = tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE); // what's was_releasing for? - + dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; // FIXME: use dedicated state and enum + dl_tbf->was_releasing = dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE); // what's was_releasing for? + /* "send" PACKET TS RECON. */ - tbf_timer_start(dl_tbf, 0, Tassign_pacch); // FIXME - do we have to wait for ACK from phone? + tbf_timer_start(dl_tbf, 0, Tassign_pacch); // FIXME - do we have to time this? } /* depending on the current TBF, we assign on PACCH or AGCH */ diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index ede04423..a3483c48 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -130,6 +130,19 @@ static struct msgb *sched_select_ctrl_msg( if (!tbf) continue; + // schedule PTSR if necessary + if (tbf->direction == GPRS_RLCMAC_DL_TBF && tbf->state_is(GPRS_RLCMAC_RECONFIGURING)) { + //tbf = dl_ass_tbf; + //msg = tbf->create_dl_ts_recon(fn, ts); + if (tbf == dl_ass_tbf) { + LOGP(DRLCMACSCHED, LOGL_NOTICE, "PTSR: scheduling on %s\n", tbf_name(dl_ass_tbf)); + msg = dl_ass_tbf->create_dl_ts_recon(fn, ts); + if (msg) + break; + } else + LOGP(DRLCMACSCHED, LOGL_NOTICE, "PTSR: FIXME - scheduling PTSR on non-DL TBF\n"); + } + /* * Assignments for the same direction have lower precedence, * because they may kill the TBF when the CONTOL ACK is @@ -152,7 +165,7 @@ static struct msgb *sched_select_ctrl_msg( pdch->next_ctrl_prio %= 3; break; } - + if (!msg) { /* * If one of these is left, the response (CONTROL ACK) from the @@ -167,12 +180,6 @@ static struct msgb *sched_select_ctrl_msg( msg = ul_ass_tbf->create_ul_ass(fn, ts); } } - - if (!msg) { - // create PACKET RS RECONFIGURE (check for state) - tbf = dl_ass_tbf; - msg = dl_ass_tbf->create_dl_ts_recon(fn, ts); - } /* any message */ if (msg) { diff --git a/src/tbf.cpp b/src/tbf.cpp index 6c0a0bb7..52077730 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -862,10 +862,10 @@ void gprs_rlcmac_tbf::handle_timeout() dl_tbf->update(); // do the MSLOT assignment // dl_tbf->bts->trigger_dl_ass(dl_tbf, dl_tbf); // FIXME: use write_packet_ts_reconfigure() - // [state/flags change] -> //LOGP(DRLCMAC, LOGL_NOTICE, "DL. ASS. for multislot\n"); LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: trigger for multislot\n"); dl_tbf->bts->trigger_dl_ts_recon(dl_tbf); + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: trigger set\n"); // abort(); // CRASH! } else LOGP(DRLCMAC, LOGL_NOTICE, "%s Continue flow after " @@ -910,13 +910,10 @@ int gprs_rlcmac_tbf::rlcmac_diag() return 0; } -struct msgb *gprs_rlcmac_tbf::create_dl_ts_recon(uint32_t fn, uint8_t ts) +struct msgb *gprs_rlcmac_tbf::create_dl_ts_recon_exp(uint32_t fn, uint8_t ts) { - // FIXME - check appropriate flags - if (this->state_is_not(GPRS_RLCMAC_RECONFIGURING)) { -// LOGP(DRLCMAC, LOGL_NOTICE, "TS. R. -- ignoring due to incompatible state\n"); - return NULL; - } + // FIXME - check appropriate flags? + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: GPRS_RLCMAC_RECONFIGURING: preparing msg\n"); unsigned int rrbp = 0; uint32_t new_poll_fn = 0; @@ -927,31 +924,179 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ts_recon(uint32_t fn, uint8_t ts) LOGP(DRLCMAC, LOGL_ERROR, "PTSR: check polling failed!\n"); return NULL; } - +// LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: polling checked\n"); msg = msgb_alloc(23, "rlcmac_pack_ts_recon"); if (!msg) { LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: msg alloc failed\n"); return NULL; } +// LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: msg alloc ok\n"); bitvec *recon_vec = bitvec_alloc(123); if (!recon_vec) { msgb_free(msg); LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: bitvec alloc failed\n"); return NULL; } - + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: bitvec alloc ok\n"); + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: %s start Packet TS Reconfigure (PACCH)\n", tbf_name(this)); // abort()? bitvec_unhex(recon_vec, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); - - LOGP(DRLCMAC, LOGL_INFO, "PTSR: %s start Packet TS Reconfigure (PACCH)\n", tbf_name(this)); RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); + Encoding::write_packet_ts_reconfigure(mac_control_block, this, new_poll_fn, rrbp, bts_data()->alpha, bts_data()->gamma, this->is_egprs_enabled()); - LOGP(DRLCMAC, LOGL_DEBUG, "PTSR: +++++++++++++++++++++++++ TX : Packet TS Reconfigure +++++++++++++++++++++++++\n"); + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: +++++++++++++++++++++++++ TX : Packet TS Reconfigure +++++++++++++++++++++++++\n"); encode_gsm_rlcmac_downlink(recon_vec, mac_control_block); LOGPC(DCSN1, LOGL_NOTICE, "\n"); - LOGP(DRLCMAC, LOGL_DEBUG, "PTSR: _________________________ TX : Packet TS Reconfigure _________________________\n"); + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: _________________________ TX : Packet TS Reconfigure _________________________\n"); + bitvec_pack(recon_vec, msgb_put(msg, 23)); // FIXME - size? bitvec_free(recon_vec); talloc_free(mac_control_block); + +// FIXME: change to proper state before returning +// if (poll_ass_dl) { + set_polling(new_poll_fn, ts); + // if (new_dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) + this->set_state(GPRS_RLCMAC_WAIT_ASSIGN); + dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK; + LOGP(DRLCMACDL, LOGL_INFO, + "%s Scheduled PTSR polling on FN=%d, TS=%d\n", + name(), poll_fn, poll_ts); +/* } else { + dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + new_dl_tbf->set_state(GPRS_RLCMAC_FLOW); + tbf_assign_control_ts(new_dl_tbf); + // stop pending assignment timer + new_dl_tbf->stop_timer(); + } +*/ + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: msg assembled ok\n"); + return msg; +} + +struct msgb *gprs_rlcmac_tbf::create_dl_ts_recon(uint32_t fn, uint8_t ts) +{ + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: GPRS_RLCMAC_RECONFIGURING: preparing msg\n"); + struct msgb *msg; + struct gprs_rlcmac_dl_tbf *new_dl_tbf = NULL; + int poll_ass_dl = 1; + unsigned int rrbp = 0; + uint32_t new_poll_fn = 0; + int rc; + bool old_tfi_is_valid = is_tfi_assigned(); + + if (direction == GPRS_RLCMAC_DL_TBF && !is_control_ts(ts)) { + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: Cannot poll for downlink " + "assigment, because MS cannot reply. (TS=%d, " + "first common TS=%d)\n", ts, + first_common_ts); + poll_ass_dl = 0; + } + if (poll_ass_dl) { + if (poll_state == GPRS_RLCMAC_POLL_SCHED && + ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) + { + LOGP(DRLCMACUL, LOGL_DEBUG, "PTSR: Polling is already " + "scheduled for %s, so we must wait for the uplink " + "assignment...\n", tbf_name(this)); + return NULL; + } + rc = check_polling(fn, ts, &new_poll_fn, &rrbp); + if (rc < 0) { + LOGP(DRLCMAC, LOGL_ERROR, "PTSR: check polling failed!\n"); + return NULL; + } + } + + /* on uplink TBF we get the downlink TBF to be assigned. */ + if (direction == GPRS_RLCMAC_UL_TBF) { + gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this); + + /* be sure to check first, if contention resolution is done, + * otherwise we cannot send the assignment yet */ + if (!ul_tbf->m_contention_resolution_done) { + LOGP(DRLCMAC, LOGL_DEBUG, "PTSR: Cannot assign DL TBF now, " + "because contention resolution is not " + "finished.\n"); + return NULL; + } + } + + if (ms()) + new_dl_tbf = ms()->dl_tbf(); + + if (!new_dl_tbf) { + LOGP(DRLCMACDL, LOGL_ERROR, "PTSR: We have a schedule for downlink " + "assignment at %s, but there is no downlink " + "TBF\n", tbf_name(this)); + dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + return NULL; + } + + if (new_dl_tbf == as_dl_tbf(this)) + LOGP(DRLCMAC, LOGL_DEBUG, + "PTSR: New and old TBF are the same %s\n", name()); + + if (old_tfi_is_valid && !new_dl_tbf->is_tlli_valid()) { + LOGP(DRLCMACDL, LOGL_ERROR, + "PTSR: The old TFI is not assigned and there is no " + "TLLI. Old TBF %s, new TBF %s\n", + name(), new_dl_tbf->name()); + dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + return NULL; + } + + new_dl_tbf->was_releasing = was_releasing; + msg = msgb_alloc(23, "rlcmac_dl_ts_rec"); + if (!msg) + return NULL; + bitvec *ass_vec = bitvec_alloc(23); + if (!ass_vec) { + msgb_free(msg); + return NULL; + } + bitvec_unhex(ass_vec, + "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); + LOGP(DRLCMAC, LOGL_INFO, "PTSR: %s start Packet Downlink Assignment (PACCH)\n", tbf_name(new_dl_tbf)); + RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); +/* + Encoding::write_packet_downlink_assignment(mac_control_block, + old_tfi_is_valid, m_tfi, (direction == GPRS_RLCMAC_DL_TBF), + new_dl_tbf, poll_ass_dl, rrbp, + bts_data()->alpha, bts_data()->gamma, -1, 0, + is_egprs_enabled()); + LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n"); + encode_gsm_rlcmac_downlink(ass_vec, mac_control_block); + LOGPC(DCSN1, LOGL_NOTICE, "\n"); + LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Downlink Assignment -------------------------\n"); +*/ + Encoding::write_packet_ts_reconfigure(mac_control_block, new_dl_tbf, new_poll_fn, rrbp, bts_data()->alpha, bts_data()->gamma, is_egprs_enabled()); + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: +++++++++++++++++++++++++ TX : Packet TS Reconfigure +++++++++++++++++++++++++\n"); + encode_gsm_rlcmac_downlink(ass_vec, mac_control_block); + LOGPC(DCSN1, LOGL_NOTICE, "\n"); + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: _________________________ TX : Packet TS Reconfigure _________________________\n"); + /*end diff*/ + + bitvec_pack(ass_vec, msgb_put(msg, 23)); + bitvec_free(ass_vec); + talloc_free(mac_control_block); + + if (poll_ass_dl) { + set_polling(new_poll_fn, ts); + if (new_dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) + new_dl_tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); + dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK; + LOGP(DRLCMACDL, LOGL_INFO, + "PTSR: %s Scheduled DL Assignment polling on FN=%d, TS=%d\n", + name(), poll_fn, poll_ts); + } else { + dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + new_dl_tbf->set_state(GPRS_RLCMAC_FLOW); + tbf_assign_control_ts(new_dl_tbf); + /* stop pending assignment timer */ + new_dl_tbf->stop_timer(); + + } + LOGP(DRLCMAC, LOGL_NOTICE, "PTSR: msgb=%s\n", msgb_hexdump(msg)); return msg; } @@ -57,6 +57,12 @@ enum gprs_rlcmac_tbf_poll_state { GPRS_RLCMAC_POLL_SCHED, /* a polling was scheduled */ }; +enum gprs_rlcmac_tbf_dl_ts_recon_state { + GPRS_RLCMAC_DL_TS_RECON_NONE = 0, + GPRS_RLCMAC_DL_TS_RECON_SEND, /* send PTSR on next RTS */ + GPRS_RLCMAC_DL_TS_RECON_WAIT_ACK, /* wait for PACKET CONTROL ACK */ +}; + enum gprs_rlcmac_tbf_dl_ass_state { GPRS_RLCMAC_DL_ASS_NONE = 0, GPRS_RLCMAC_DL_ASS_SEND_ASS, /* send downlink assignment on next RTS */ @@ -105,8 +111,8 @@ struct gprs_rlcmac_tbf { struct msgb *create_dl_ass(uint32_t fn, uint8_t ts); struct msgb *create_ul_ass(uint32_t fn, uint8_t ts); + struct msgb *create_dl_ts_recon_exp(uint32_t fn, uint8_t ts); struct msgb *create_dl_ts_recon(uint32_t fn, uint8_t ts); - GprsMs *ms() const; void set_ms(GprsMs *ms); |