From afdd9e1be521e4a4970e4cdadb479722a2435d50 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 7 Oct 2012 17:08:55 +0200 Subject: [PATCH] Fix: Don't use TIMING_ADVANCE_INDEX in assignment messages, if not used Some MS will leave packet transfer mode, if TAI is given, but no timing advance control messages are sent on PTCCH. This could results in permanent loss of larger packets. --- src/gprs_rlcmac.cpp | 40 ++++++++++++++++++++++++++++++---------- src/gprs_rlcmac.h | 7 ++++--- src/gprs_rlcmac_data.cpp | 10 +++++----- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index b5e0f352..1f981933 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -1290,7 +1290,7 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, uint8_t tfi, uint8_t usf, uint32_t tlli, uint8_t polling, uint32_t fn, uint8_t single_block, uint8_t alpha, - uint8_t gamma) + uint8_t gamma, int8_t ta_idx) { unsigned wp = 0; uint8_t plen; @@ -1353,8 +1353,12 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter bitvec_write_field(dest, wp,polling,1); // Polling Bit bitvec_write_field(dest, wp,!polling,1); // TA_VALID ??? - bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on - bitvec_write_field(dest, wp,0x0,4); // TIMING_ADVANCE_INDEX + if (ta_idx < 0) { + bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off + } else { + bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on + bitvec_write_field(dest, wp,ta_idx,4); // TIMING_ADVANCE_INDEX + } if (polling) { bitvec_write_field(dest, wp,0x1,1); // TBF Starting TIME present bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1' @@ -1381,7 +1385,12 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, } else bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter - bitvec_write_field(dest, wp, 0, 1); // TIMING_ADVANCE_INDEX_FLAG + if (ta_idx < 0) { + bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off + } else { + bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on + bitvec_write_field(dest, wp,ta_idx,4); // TIMING_ADVANCE_INDEX + } bitvec_write_field(dest, wp, 1, 1); // TBF_STARTING_TIME_FLAG bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1' bitvec_write_field(dest, wp,fn % 51,6); // T3 @@ -1402,7 +1411,8 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, } else bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter - bitvec_write_field(dest, wp, 0, 1); // TIMING_ADVANCE_INDEX_FLAG + /* note: there is no choise for TAI and no starting time */ + bitvec_write_field(dest, wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off bitvec_write_field(dest, wp, 0, 1); // TBF_STARTING_TIME_FLAG } } @@ -1414,7 +1424,7 @@ int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi, uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli, struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t alpha, - uint8_t gamma) + uint8_t gamma, int8_t ta_idx) { // TODO We should use our implementation of encode RLC/MAC Control messages. struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; @@ -1442,10 +1452,14 @@ void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi, bitvec_write_field(dest, wp,0x0,1); // Message escape bitvec_write_field(dest, wp,bts->initial_cs_ul-1, 2); // CHANNEL_CODING_COMMAND bitvec_write_field(dest, wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING - bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_VALUE = on bitvec_write_field(dest, wp,tbf->ta,6); // TIMING_ADVANCE_VALUE - bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off + if (ta_idx < 0) { + bitvec_write_field(dest, wp,0x0,1); // switch TIMING_ADVANCE_INDEX = off + } else { + bitvec_write_field(dest, wp,0x1,1); // switch TIMING_ADVANCE_INDEX = on + bitvec_write_field(dest, wp,ta_idx,4); // TIMING_ADVANCE_INDEX + } #if 1 bitvec_write_field(dest, wp,0x1,1); // Frequency Parameters information elements = present @@ -1489,7 +1503,7 @@ void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi, /* generate downlink assignment */ void 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 alpha, uint8_t gamma) + uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts) { // Packet downlink assignment TS 44.060 11.2.7 @@ -1520,7 +1534,13 @@ void write_packet_downlink_assignment(RlcMacDownlink_t * block, uint8_t old_tfi, block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.Exist_TIMING_ADVANCE_VALUE = 0x1; // TIMING_ADVANCE_VALUE = on block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.TIMING_ADVANCE_VALUE = tbf->ta; // TIMING_ADVANCE_VALUE - block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.Exist_IndexAndtimeSlot = 0x0; // TIMING_ADVANCE_INDEX = off + if (ta_idx < 0) { + block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.Exist_IndexAndtimeSlot = 0x0; // TIMING_ADVANCE_INDEX = off + } else { + block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.Exist_IndexAndtimeSlot = 0x1; // TIMING_ADVANCE_INDEX = on + block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.TIMING_ADVANCE_INDEX = ta_idx; // TIMING_ADVANCE_INDEX + block->u.Packet_Downlink_Assignment.Packet_Timing_Advance.TIMING_ADVANCE_TIMESLOT_NUMBER = ta_ts; // TIMING_ADVANCE_TS + } block->u.Packet_Downlink_Assignment.Exist_P0_and_BTS_PWR_CTRL_MODE = 0x0; // POWER CONTROL = off diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index c67a68bd..dbbd6739 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -323,16 +323,17 @@ int gprs_rlcmac_rcv_block(uint8_t trx, uint8_t ts, uint8_t *data, uint8_t len, int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, uint32_t ref_fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc, uint8_t tfi, uint8_t usf, uint32_t tlli, uint8_t polling, - uint32_t fn, uint8_t single_block, uint8_t alpha, uint8_t gamma); + uint32_t fn, uint8_t single_block, uint8_t alpha, uint8_t gamma, + int8_t ta_idx); void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi, uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli, struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t alpha, - uint8_t gamma); + uint8_t gamma, int8_t ta_idx); void 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 alpha, uint8_t gamma); + uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts); diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 5e7caf0d..c3e49d97 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -1065,7 +1065,7 @@ struct msgb *gprs_rlcmac_send_packet_uplink_assignment( write_packet_uplink_assignment(ass_vec, tbf->tfi, (tbf->direction == GPRS_RLCMAC_DL_TBF), tbf->tlli, tbf->tlli_valid, new_tbf, POLLING_ASSIGNMENT_UL, bts->alpha, - bts->gamma); + bts->gamma, -1); bitvec_pack(ass_vec, msgb_put(msg, 23)); RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++\n"); @@ -1158,12 +1158,12 @@ int gprs_rlcmac_rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) plen = write_immediate_assignment(immediate_assignment, 0, ra, Fn, qta >> 2, bts->trx[trx].arfcn, ts, bts->trx[trx].pdch[ts].tsc, 0, 0, 0, 0, sb_fn, 1, - bts->alpha, bts->gamma); + bts->alpha, bts->gamma, -1); else plen = write_immediate_assignment(immediate_assignment, 0, ra, Fn, tbf->ta, tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, tbf->dir.ul.usf[tbf->first_ts], 0, 0, 0, 0, - bts->alpha, bts->gamma); + bts->alpha, bts->gamma, -1); pcu_l1if_tx_agch(immediate_assignment, plen); bitvec_free(immediate_assignment); @@ -1751,7 +1751,7 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment( RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); write_packet_downlink_assignment(mac_control_block, tbf->tfi, (tbf->direction == GPRS_RLCMAC_DL_TBF), new_tbf, - poll_ass_dl, bts->alpha, bts->gamma); + poll_ass_dl, bts->alpha, bts->gamma, -1, 0); LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n"); encode_gsm_rlcmac_downlink(ass_vec, mac_control_block); LOGPC(DCSN1, LOGL_NOTICE, "\n"); @@ -1792,7 +1792,7 @@ static void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf, uint8_t poll, plen = write_immediate_assignment(immediate_assignment, 1, 125, (tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta, tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, 0, tbf->tlli, poll, - tbf->poll_fn, 0, bts->alpha, bts->gamma); + tbf->poll_fn, 0, bts->alpha, bts->gamma, -1); pcu_l1if_tx_pch(immediate_assignment, plen, imsi); bitvec_free(immediate_assignment); }