aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2016-01-29 16:39:21 +0100
committerJacob Erlbeck <jerlbeck@sysmocom.de>2016-02-08 00:45:38 +0100
commit6b356a58d1269fe4ad449bc868cbc734c6d2a28e (patch)
tree8736689113716ab1eebb56ef7055e4840700cf7b /src
parentf2694b74c9af6e308d3886cd3c75864d101de8d4 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/encoding.cpp16
-rw-r--r--src/encoding.h2
-rw-r--r--src/tbf.cpp21
-rw-r--r--src/tbf.h11
4 files changed, 41 insertions, 9 deletions
diff --git a/src/encoding.cpp b/src/encoding.cpp
index a5e5064..9471fff 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 6ee30ac..1248725 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 1694bbb..04c7272 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 edb8280..d1b286c 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;