Bug #6102
closedFeature #5500: MS-Side GPRS RLC/MAC implementation
libosmo-gprs-rlcmac: DL ACK/NACK endless loop again PCU after 128 bsns received
100%
Description
While testing the "modem" app against osmo-pcu, ping-pong works fine until PCU submits an entire round of 128 BSNs (SNS=128). At that point in time, when PCU starts reusing BSN=0 to sends new data, the libosmo-gprs-rlcmac implementation becomes stuck always answering the DL_ACK/NACK containing STARTING_SEQUENCE_NUMBER=0 and an RRB full of zeroes.
As a result, the PCU keeps resending the same blocks endlessly. I attach a pcap showing the problem. By filtering for DL_ACK/NACK message, once can see the full loop BSN=0..BSN=127, and how the problem starts when PCU starts reusing BSN=0 again.
Ack_Nack_Description ...0 .... = FINAL_ACK_INDICATION: False .... 0000 000. .... = STARTING_SEQUENCE_NUMBER: 0 ...0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 000. .... = Received Block Bitmap: 0 ...0 .... = Exist_Channel_Request_Description: 0
Here's a quick status taken with gdb with breakpoint on gprs_rlcmac_dl_tbf_rcv_data_block() while already in the faulty state:
Breakpoint 2, gprs_rlcmac_dl_tbf_rcv_data_block (dl_tbf=dl_tbf@entry=0x613000014b60, rlc=rlc@entry=0x7ffff3662a20, data=0x6160019c5d9a "\a", fn=fn@entry=213356, ts_nr=ts_nr@entry=5 '\005') at /home/pespin/dev/sysmocom/git/libosmo-gprs/src/rlcmac/tbf_dl.c:266 266 { (gdb) n 270 const uint16_t ws = gprs_rlcmac_rlc_window_ws(dl_tbf->w); (gdb) n 272 LOGPTBFDL(dl_tbf, LOGL_DEBUG, "DL DATA TFI=%d received (V(Q)=%d .. V(R)=%d)\n", (gdb) print ws $1 = 64 (gdb) n 278 gprs_rlcmac_dl_tbf_t3190_start(dl_tbf); (gdb) print gprs_rlcmac_rlc_dl_window_v_q(dl_tbf->dlw) $2 = 0 (gdb) print gprs_rlcmac_rlc_dl_window_v_r(dl_tbf->dlw) $3 = 0 (gdb) n 281 for (block_idx = 0; block_idx < rlc->num_data_blocks; block_idx++) { (gdb) n 283 rdbi = &rlc->block_info[block_idx]; (gdb) n 285 LOGPTBFDL(dl_tbf, LOGL_DEBUG, (gdb) n 294 if (!gprs_rlcmac_rlc_dl_window_is_in_window(dl_tbf->dlw, rdbi->bsn)) { (gdb) print *rdbi $4 = {data_len = 20, bsn = 22, ti = 0, e = 1, cv = 255, pi = 0, spb = 0} (gdb) print gprs_rlcmac_rlc_dl_window_is_in_window(dl_tbf->dlw, rdbi->bsn) $5 = true (gdb) n 300 } else if (gprs_rlcmac_rlc_v_n_is_received(&dl_tbf->dlw->v_n, rdbi->bsn)) { (gdb) print gprs_rlcmac_rlc_v_n_is_received(&dl_tbf->dlw->v_n, rdbi->bsn) $6 = true (gdb) n 301 LOGPTBFDL(dl_tbf, LOGL_DEBUG, "BSN %d already received\n", rdbi->bsn); (gdb) print dl_tbf->dlw->v_n $7 = {v_n = {GPRS_RLCMAC_RLC_DL_BSN_RECEIVED <repeats 128 times>, GPRS_RLCMAC_RLC_DL_BSN_INVALID <repeats 896 times>}} (gdb) print *dl_tbf->dlw $9 = {window = {sns = 128, ws = 64}, dl_tbf = 0x613000014b60, v_r = 0, v_q = 0, v_n = {v_n = {GPRS_RLCMAC_RLC_DL_BSN_RECEIVED <repeats 128 times>, GPRS_RLCMAC_RLC_DL_BSN_INVALID <repeats 896 times>}}}
Related spec: TS 44.060 12.3 "Ack/Nack Description"
Files