diff options
author | pravin <pravin.manoharan@radisys.com> | 2016-09-30 11:30:26 +0530 |
---|---|---|
committer | pravin <pravin.manoharan@radisys.com> | 2016-09-30 11:30:26 +0530 |
commit | f15edb81ff67385420df9c725dcf5a276ff292b4 (patch) | |
tree | ff29c0d381edfb53d79ae0e5b3b50c17701d2229 | |
parent | 99e78ab60e4c7dec5253df174a1ae1eea9cc36a2 (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.cpp | 3 | ||||
-rw-r--r-- | src/rlc.h | 13 | ||||
-rw-r--r-- | src/tbf_dl.cpp | 9 | ||||
-rw-r--r-- | tests/tbf/TbfTest.cpp | 101 | ||||
-rw-r--r-- | tests/tbf/TbfTest.err | 123 | ||||
-rw-r--r-- | tests/tbf/TbfTest.ok | 4 |
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) */ @@ -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 === |