From 6b356a58d1269fe4ad449bc868cbc734c6d2a28e Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 29 Jan 2016 16:39:21 +0100 Subject: tbf: Use TLLI as ID if TFI not yet assigned Currently the old TFI is always used as ID when a PACKET DOWNLINK ASSIGNMENT is generated. This fails if the old TBF has not been fully assigned yet. The MS will then ignore the PDA. This commit changes write_packet_downlink_assignment to accept an additional parameter old_tfi_is_valid and uses the new TBF's TLLI instead of the olf TFI if that parameter is set to false. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 16 +++++++++++----- src/encoding.h | 2 +- src/tbf.cpp | 21 ++++++++++++++++++--- src/tbf.h | 11 +++++++++++ 4 files changed, 41 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/encoding.cpp b/src/encoding.cpp index a5e50646..9471fff5 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -274,8 +274,9 @@ void Encoding::write_packet_uplink_assignment( /* generate downlink assignment */ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, - uint8_t old_tfi, uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, - uint8_t poll, uint8_t rrbp, uint8_t alpha, uint8_t gamma, int8_t ta_idx, + bool old_tfi_is_valid, uint8_t old_tfi, uint8_t old_downlink, + struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t rrbp, + uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts, bool use_egprs) { // Packet downlink assignment TS 44.060 11.2.7 @@ -295,9 +296,14 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block, block->u.Packet_Downlink_Assignment.Exist_PERSISTENCE_LEVEL = 0x0; // PERSISTENCE_LEVEL: off - block->u.Packet_Downlink_Assignment.ID.UnionType = 0x0; // TFI = on - block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.UnionType = old_downlink; // 0=UPLINK TFI, 1=DL TFI - block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.u.UPLINK_TFI = old_tfi; // TFI + if (old_tfi_is_valid) { + block->u.Packet_Downlink_Assignment.ID.UnionType = 0x0; // TFI = on + block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.UnionType = old_downlink; // 0=UPLINK TFI, 1=DL TFI + block->u.Packet_Downlink_Assignment.ID.u.Global_TFI.u.UPLINK_TFI = old_tfi; // TFI + } else { + block->u.Packet_Downlink_Assignment.ID.UnionType = 0x1; // TLLI + block->u.Packet_Downlink_Assignment.ID.u.TLLI = tbf->tlli(); + } block->u.Packet_Downlink_Assignment.MAC_MODE = 0x0; // Dynamic Allocation block->u.Packet_Downlink_Assignment.RLC_MODE = 0x0; // RLC acknowledged mode diff --git a/src/encoding.h b/src/encoding.h index 6ee30ac8..12487258 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -55,7 +55,7 @@ public: int8_t use_egprs); static void write_packet_downlink_assignment(RlcMacDownlink_t * block, - uint8_t old_tfi, uint8_t old_downlink, + bool old_tfi_is_valid, uint8_t old_tfi, uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t rrbp, uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts, bool use_egprs); diff --git a/src/tbf.cpp b/src/tbf.cpp index 1694bbbc..04c72724 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -907,6 +907,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) 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, "Cannot poll for downlink " @@ -954,6 +955,19 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) return NULL; } + if (new_dl_tbf == as_dl_tbf(this)) + LOGP(DRLCMAC, LOGL_DEBUG, + "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, + "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_ass"); if (!msg) @@ -967,9 +981,10 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); LOGP(DRLCMAC, LOGL_INFO, "%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, m_tfi, - (direction == GPRS_RLCMAC_DL_TBF), new_dl_tbf, - poll_ass_dl, rrbp, bts_data()->alpha, bts_data()->gamma, -1, 0, + 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); diff --git a/src/tbf.h b/src/tbf.h index edb8280e..d1b286cb 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -132,6 +132,7 @@ struct gprs_rlcmac_tbf { void update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction); uint8_t tfi() const; + bool is_tfi_assigned() const; const char *imsi() const; void assign_imsi(const char *imsi); @@ -310,6 +311,16 @@ inline bool gprs_rlcmac_tbf::is_tlli_valid() const return tlli() != 0; } +inline bool gprs_rlcmac_tbf::is_tfi_assigned() const +{ + /* The TBF is established or has been assigned by a IMM.ASS for + * download */ + return state > GPRS_RLCMAC_ASSIGN || + (direction == GPRS_RLCMAC_DL_TBF && + state == GPRS_RLCMAC_ASSIGN && + (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))); +} + inline uint8_t gprs_rlcmac_tbf::tfi() const { return m_tfi; -- cgit v1.2.3