aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpravin <pravin.manoharan@radisys.com>2016-09-30 11:30:26 +0530
committerpravin <pravin.manoharan@radisys.com>2016-09-30 11:30:26 +0530
commitf15edb81ff67385420df9c725dcf5a276ff292b4 (patch)
treeff29c0d381edfb53d79ae0e5b3b50c17701d2229
parent99e78ab60e4c7dec5253df174a1ae1eea9cc36a2 (diff)
EGPRS: fix for EPDAN out of window
Fix for aligning the EPDAN out of RLC transmit window is made according to section 9.1.8.2.4 in 44.060 version 7.27.0 Release 7. The specification explains that A bit within the uncompressed bitmap whose corresponding BSN is not within the transmit window shall be ignored Related: OS#1789
-rw-r--r--src/rlc.cpp3
-rw-r--r--src/rlc.h13
-rw-r--r--src/tbf_dl.cpp9
-rw-r--r--tests/tbf/TbfTest.cpp101
-rw-r--r--tests/tbf/TbfTest.err123
-rw-r--r--tests/tbf/TbfTest.ok4
6 files changed, 193 insertions, 60 deletions
diff --git a/src/rlc.cpp b/src/rlc.cpp
index 906f4cc..758bf3b 100644
--- a/src/rlc.cpp
+++ b/src/rlc.cpp
@@ -131,7 +131,8 @@ void gprs_rlc_dl_window::update(BTS *bts, const struct bitvec *rbb,
uint16_t first_bsn, uint16_t *lost,
uint16_t *received)
{
- unsigned num_blocks = rbb->cur_bit;
+ unsigned num_blocks = rbb->cur_bit > (unsigned)distance()
+ ? distance() : rbb->cur_bit;
unsigned bsn;
/* first_bsn is in range V(A)..V(S) */
diff --git a/src/rlc.h b/src/rlc.h
index 83b6815..2701d67 100644
--- a/src/rlc.h
+++ b/src/rlc.h
@@ -302,6 +302,9 @@ struct gprs_rlc_dl_window: public gprs_rlc_window {
const uint16_t v_a() const;
const int16_t distance() const;
+ void set_v_s(int);
+ void set_v_a(int);
+
/* Methods to manage reception */
int resend_needed();
int mark_for_resend();
@@ -510,6 +513,16 @@ inline const uint16_t gprs_rlc_dl_window::v_s() const
return m_v_s;
}
+inline void gprs_rlc_dl_window::set_v_s(int v_s)
+{
+ m_v_s = v_s;
+}
+
+inline void gprs_rlc_dl_window::set_v_a(int v_a)
+{
+ m_v_a = v_a;
+}
+
inline const uint16_t gprs_rlc_dl_window::v_s_mod(int offset) const
{
return mod_sns(m_v_s + offset);
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 457f2c9..fe85e4d 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -845,7 +845,8 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn,
uint16_t bsn = 0;
unsigned received_bytes = 0, lost_bytes = 0;
unsigned received_packets = 0, lost_packets = 0;
- unsigned num_blocks = strlen(show_rbb);
+ unsigned num_blocks = strlen(show_rbb) > (unsigned)m_window.distance()
+ ? m_window.distance() : strlen(show_rbb);
/* SSN - 1 is in range V(A)..V(S)-1 */
for (unsigned int bitpos = 0; bitpos < num_blocks; bitpos++) {
@@ -925,7 +926,8 @@ int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn,
char show_rbb[RLC_MAX_SNS + 1];
int error_rate;
struct ana_result ana_res;
- unsigned num_blocks = rbb->cur_bit;
+ unsigned num_blocks = rbb->cur_bit > (unsigned)m_window.distance()
+ ? m_window.distance() : rbb->cur_bit;
unsigned behind_last_bsn = m_window.mod_sns(first_bsn + num_blocks);
Decoding::extract_rbb(rbb, show_rbb);
@@ -948,8 +950,7 @@ int gprs_rlcmac_dl_tbf::update_window(unsigned first_bsn,
* TODO: check whether this FIXME still makes sense
*/
LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of "
- "V(A)..V(S) range %s Free TBF!\n", tbf_name(this));
- return 1; /* indicate to free TBF */
+ "V(A)..V(S) range %s\n", tbf_name(this));
}
}
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index d87fe0c..b500fa4 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -2025,62 +2025,52 @@ static void test_tbf_li_decoding(void)
* window shall be ignored. Which fails because of existing bug. This test case
* expects the same bug. which shall be fixed in subsequent patch
*/
-static void test_egprs_tbf_epdan_out_of_rx_window(void)
+static void egprs_tbf_epdan_outof_rx_window(BTS *the_bts, int mcs)
{
- BTS the_bts;
- gprs_rlcmac_bts *bts;
- int i;
+ unsigned i;
uint8_t ms_class = 11;
uint8_t egprs_ms_class = 11;
uint32_t fn = 2654167; /* 17,25,9 */
uint8_t trx_no;
int num_blocks;
uint32_t tlli = 0xffeeddcc;
+ uint8_t rbb[64/8];
gprs_rlcmac_dl_tbf *dl_tbf;
- int ts_no = 4;
+ int ts_no = 7;
bitvec *block;
uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
bitvec bits;
int bsn_begin, bsn_end;
EGPRS_PD_AckNack_t *ack_nack;
RlcMacUplink_t ul_control_block;
- gprs_rlc_v_b *prlcmvb;
- gprs_rlc_dl_window *prlcdlwindow;
-
- printf("=== start %s ===\n", __func__);
-
- bts = the_bts.bts_data();
-
- setup_bts(&the_bts, ts_no);
- bts->dl_tbf_idle_msec = 200;
- bts->egprs_enabled = 1;
- /* ARQ II */
- bts->dl_arq_type = EGPRS_ARQ2;
+ gprs_rlcmac_bts *bts;
/*
- * Over the Air message captured has been
- * used to simulate this test case. During
- * over the air testing, v_a was 1176, vs was 1288,
- * max sns was 2048
- * and window size of 480.
+ * Over the Air message captured. The same has been used
+ * used to simulate the EPDAN out of window scenario. During
+ * over the air testing, v_a was 1176, vs was 1288, max sns was 2048
+ * and window size of 480. same has been used below
*/
uint8_t data_msg[23] = {0x40, 0x20, 0x0b, 0xff, 0xd1,
0x61, 0x00, 0x3e, 0x0e, 0x51, 0x9f,
0xff, 0xff, 0xfb, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- dl_tbf = create_dl_tbf(&the_bts, ms_class, egprs_ms_class, &trx_no);
+ bts = the_bts->bts_data();
+
+ bts->initial_mcs_dl = mcs;
+
+ dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
- prlcdlwindow = &dl_tbf->m_window;
- prlcmvb = &prlcdlwindow->m_v_b;
- prlcdlwindow->m_v_s = 1288;
- prlcdlwindow->m_v_a = 1176;
- prlcdlwindow->set_sns(2048);
- prlcdlwindow->set_ws(480);
- prlcmvb->mark_unacked(1176);
- prlcmvb->mark_unacked(1177);
- prlcmvb->mark_unacked(1286);
- prlcmvb->mark_unacked(1287);
+
+ dl_tbf->m_window.set_v_s(1288);
+ dl_tbf->m_window.set_v_a(1176);
+ dl_tbf->m_window.set_sns(2048);
+ dl_tbf->m_window.set_ws(480);
+ dl_tbf->m_window.m_v_b.mark_unacked(1176);
+ dl_tbf->m_window.m_v_b.mark_unacked(1177);
+ dl_tbf->m_window.m_v_b.mark_unacked(1287);
+ dl_tbf->m_window.m_v_b.mark_unacked(1286);
OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
@@ -2096,10 +2086,10 @@ static void test_egprs_tbf_epdan_out_of_rx_window(void)
ack_nack = &ul_control_block.u.Egprs_Packet_Downlink_Ack_Nack;
- OSMO_ASSERT(prlcmvb->is_unacked(1176));
- OSMO_ASSERT(prlcmvb->is_unacked(1177));
- OSMO_ASSERT(prlcmvb->is_unacked(1286));
- OSMO_ASSERT(prlcmvb->is_unacked(1287));
+ OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1176));
+ OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1177));
+ OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1287));
+ OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_unacked(1286));
num_blocks = Decoding::decode_egprs_acknack_bits(
&ack_nack->EGPRS_AckNack.Desc, &bits,
@@ -2108,20 +2098,35 @@ static void test_egprs_tbf_epdan_out_of_rx_window(void)
dl_tbf->rcvd_dl_ack(
ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION,
bsn_begin, &bits);
- /*
- * TODO:status of BSN:1176,1177 shall be invalid
- * status of BSN:1286,1287 shall be acked.
- * both condition fails because of existing bug. Which shall be
- * fixed in subsequent commit
- */
- OSMO_ASSERT(prlcmvb->is_unacked(1176));
- OSMO_ASSERT(prlcmvb->is_unacked(1177));
- OSMO_ASSERT(prlcmvb->is_unacked(1286));
- OSMO_ASSERT(prlcmvb->is_unacked(1287));
+ OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_invalid(1176));
+ OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_invalid(1177));
+ OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_acked(1287));
+ OSMO_ASSERT(dl_tbf->m_window.m_v_b.is_acked(1286));
bitvec_free(block);
tbf_free(dl_tbf);
+}
+
+static void test_tbf_egprs_epdan(void)
+{
+ BTS the_bts;
+ gprs_rlcmac_bts *bts;
+ uint8_t ts_no = 4;
+ int i;
+
+ printf("=== start %s ===\n", __func__);
+
+ bts = the_bts.bts_data();
+
+ setup_bts(&the_bts, ts_no);
+ bts->dl_tbf_idle_msec = 200;
+ bts->egprs_enabled = 1;
+ /* ARQ II */
+ bts->dl_arq_type = EGPRS_ARQ2;
+
+ egprs_tbf_epdan_outof_rx_window(&the_bts, 4);
+
printf("=== end %s ===\n", __func__);
}
@@ -2803,7 +2808,7 @@ int main(int argc, char **argv)
test_tbf_puan_urbb_len();
test_tbf_update_ws();
test_tbf_li_decoding();
- test_egprs_tbf_epdan_out_of_rx_window();
+ test_tbf_egprs_epdan();
if (getenv("TALLOC_REPORT_FULL"))
talloc_report_full(tall_pcu_ctx, stderr);
diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err
index a2a8803..90f7195 100644
--- a/tests/tbf/TbfTest.err
+++ b/tests/tbf/TbfTest.err
@@ -447,7 +447,7 @@ msg block (BSN 20, CS-1): 07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b
Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=91 block=9 data=07 00 28 0a 41 c6 c7 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge
- ack: (BSN=85)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=20) R=ACK I=NACK
-TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, recv=21, skipped=0, bsn=127, info='RRRRRRRRRRRRRRRRRRRRR$..........................................'
+TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=0:21, lost=0, recv=21, skipped=0, bsn=0, info='RRRRRRRRRRRRRRRRRRRRR...........................................'
- got ack for BSN=20
- got ack for BSN=19
- got ack for BSN=18
@@ -486,7 +486,7 @@ msg block (BSN 21, CS-1): 07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
Sending data request: trx=0 ts=4 sapi=5 arfcn=0 fn=95 block=10 data=07 00 2a 4d 43 c0 01 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b
TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) downlink acknowledge
- ack: (BSN=86)"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"(BSN=21) R=ACK I=NACK
-TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, recv=1, skipped=0, bsn=20, info='R$..............................................................'
+TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW) DL analysis, range=21:22, lost=0, recv=1, skipped=0, bsn=21, info='R...............................................................'
- got ack for BSN=21
- V(B): (V(A)=22)""(V(S)-1=21) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid
Scheduling data message at RTS for DL TFI=0 (TRX=0, TS=4) prio=4
@@ -6561,9 +6561,122 @@ Modifying MS object, TLLI = 0x00000000, TA 220 -> 0
TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) changes state from NULL to FLOW
The MS object cannot fully confirm an unexpected TLLI: 0xffeeddcc, partly confirmed
TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) downlink acknowledge
-- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1288) R=ACK I=NACK
-- ack range is out of V(A)..V(S) range TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) Free TBF!
-DL packet loss of IMSI= / TLLI=0xffeeddcc: 100%
+- ack: (BSN=1176)"RRRRRRRRRRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRRIRRRRRRRRRRRRRRRRRRRRRRRRRRI"(BSN=1287) R=ACK I=NACK
+TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) DL analysis, range=1176:1288, lost=0, recv=0, skipped=112, bsn=1944, info='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx................................................................................................................................................................................................................................................................................................................................................................................'
+- got ack for BSN=1176
+- got ack for BSN=1177
+- got ack for BSN=1178
+- got ack for BSN=1179
+- got ack for BSN=1180
+- got ack for BSN=1181
+- got ack for BSN=1182
+- got ack for BSN=1183
+- got ack for BSN=1184
+- got ack for BSN=1185
+- got NACK for BSN=1186
+- got NACK for BSN=1187
+- got NACK for BSN=1188
+- got NACK for BSN=1189
+- got NACK for BSN=1190
+- got NACK for BSN=1191
+- got NACK for BSN=1192
+- got NACK for BSN=1193
+- got NACK for BSN=1194
+- got NACK for BSN=1195
+- got NACK for BSN=1196
+- got NACK for BSN=1197
+- got NACK for BSN=1198
+- got NACK for BSN=1199
+- got NACK for BSN=1200
+- got NACK for BSN=1201
+- got NACK for BSN=1202
+- got NACK for BSN=1203
+- got NACK for BSN=1204
+- got NACK for BSN=1205
+- got NACK for BSN=1206
+- got NACK for BSN=1207
+- got NACK for BSN=1208
+- got NACK for BSN=1209
+- got NACK for BSN=1210
+- got NACK for BSN=1211
+- got NACK for BSN=1212
+- got NACK for BSN=1213
+- got NACK for BSN=1214
+- got NACK for BSN=1215
+- got NACK for BSN=1216
+- got NACK for BSN=1217
+- got NACK for BSN=1218
+- got NACK for BSN=1219
+- got NACK for BSN=1220
+- got NACK for BSN=1221
+- got NACK for BSN=1222
+- got NACK for BSN=1223
+- got NACK for BSN=1224
+- got NACK for BSN=1225
+- got NACK for BSN=1226
+- got NACK for BSN=1227
+- got NACK for BSN=1228
+- got NACK for BSN=1229
+- got NACK for BSN=1230
+- got NACK for BSN=1231
+- got NACK for BSN=1232
+- got NACK for BSN=1233
+- got NACK for BSN=1234
+- got NACK for BSN=1235
+- got NACK for BSN=1236
+- got NACK for BSN=1237
+- got NACK for BSN=1238
+- got NACK for BSN=1239
+- got NACK for BSN=1240
+- got NACK for BSN=1241
+- got NACK for BSN=1242
+- got NACK for BSN=1243
+- got NACK for BSN=1244
+- got NACK for BSN=1245
+- got NACK for BSN=1246
+- got NACK for BSN=1247
+- got NACK for BSN=1248
+- got NACK for BSN=1249
+- got NACK for BSN=1250
+- got NACK for BSN=1251
+- got NACK for BSN=1252
+- got NACK for BSN=1253
+- got NACK for BSN=1254
+- got NACK for BSN=1255
+- got NACK for BSN=1256
+- got NACK for BSN=1257
+- got ack for BSN=1258
+- got ack for BSN=1259
+- got ack for BSN=1260
+- got NACK for BSN=1261
+- got ack for BSN=1262
+- got ack for BSN=1263
+- got ack for BSN=1264
+- got ack for BSN=1265
+- got ack for BSN=1266
+- got ack for BSN=1267
+- got ack for BSN=1268
+- got ack for BSN=1269
+- got ack for BSN=1270
+- got ack for BSN=1271
+- got ack for BSN=1272
+- got ack for BSN=1273
+- got ack for BSN=1274
+- got ack for BSN=1275
+- got ack for BSN=1276
+- got ack for BSN=1277
+- got ack for BSN=1278
+- got ack for BSN=1279
+- got ack for BSN=1280
+- got ack for BSN=1281
+- got ack for BSN=1282
+- got ack for BSN=1283
+- got ack for BSN=1284
+- got ack for BSN=1285
+- got ack for BSN=1286
+- got ack for BSN=1287
+- V(B): (V(A)=1186)"NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAANAAAAAAAAAAAAAAAAAAAAAAAAAA"(V(S)-1=1287) A=Acked N=Nacked U=Unacked X=Resend-Unacked I=Invalid
+DL packet loss of IMSI= / TLLI=0xffeeddcc: 78%
TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=FLOW EGPRS) changes state from FLOW to RELEASING
TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) free
TBF(TFI=0 TLLI=0xffeeddcc DIR=DL STATE=RELEASING EGPRS) Software error: Pending downlink assignment. This may not happen, because the assignment message never gets transmitted. Please be sure not to free in this state. PLEASE FIX!
diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok
index efcfdee..bbc0af6 100644
--- a/tests/tbf/TbfTest.ok
+++ b/tests/tbf/TbfTest.ok
@@ -66,5 +66,5 @@ Testing retx for MCS 6 to reseg_mcs 3
=== end test_tbf_update_ws ===
=== start test_tbf_li_decoding ===
=== end test_tbf_li_decoding ===
-=== start test_egprs_tbf_epdan_out_of_rx_window ===
-=== end test_egprs_tbf_epdan_out_of_rx_window ===
+=== start test_tbf_egprs_epdan ===
+=== end test_tbf_egprs_epdan ===