dexter has submitted this change. ( https://gerrit.osmocom.org/c/osmo-pcu/+/31148 )
Change subject: pcu_l1_if.cpp: handle TLLI based IMMEDIATE ASSIGNMENT confirmation ......................................................................
pcu_l1_if.cpp: handle TLLI based IMMEDIATE ASSIGNMENT confirmation
The IMMEDIATE ASSIGNMENT for downlink TBFs must be confirmed by the receiving end (BSC/BTS) in order to set the timers in the PCU correctly.
When the PCU is used in a BSC co-located scheme (Ericsson RBS). The TLLI is used as an identifier to confirm a specific IMMEDIATE ASSIGNMENT.
Change-Id: Icf7ca34500984239ee877ee71fd9c126b5eb3480 Related: OS#5198 --- M src/bts.cpp M src/bts.h M src/pcu_l1_if.cpp 3 files changed, 61 insertions(+), 11 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved
diff --git a/src/bts.cpp b/src/bts.cpp index d06c9d0..33ad4a6 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -668,13 +668,10 @@ return best_first_tfi; }
-int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t fn) +static int tlli_from_imm_ass(uint32_t *tlli, const uint8_t *data, uint32_t fn) { - struct gprs_rlcmac_dl_tbf *dl_tbf; const struct gsm48_imm_ass *imm_ass = (struct gsm48_imm_ass *)data; uint8_t plen; - uint32_t tlli; - GprsMs *ms;
/* Move to IA Rest Octets: TS 44.018 9.1.18 "The L2 pseudo length of * this message is the sum of lengths of all information elements @@ -692,12 +689,41 @@ }
/* get TLLI from downlink assignment */ - tlli = (uint32_t)((*data++) & 0xf) << 28; - tlli |= (*data++) << 20; - tlli |= (*data++) << 12; - tlli |= (*data++) << 4; - tlli |= (*data++) >> 4; + *tlli = (uint32_t)((*data++) & 0xf) << 28; + *tlli |= (*data++) << 20; + *tlli |= (*data++) << 12; + *tlli |= (*data++) << 4; + *tlli |= (*data++) >> 4;
+ return 0; +} + +int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t tlli, uint32_t fn) +{ + struct gprs_rlcmac_dl_tbf *dl_tbf; + GprsMs *ms; + int rc; + + /* NOTE: A confirmation for a downlink IMMEDIATE ASSIGNMENT can be received using two different methods. + * One way is to send the whole IMMEDIATE ASSIGNMENT back to the PCU and the TLLI, which we use as + * reference is extracted from the rest octets of this message. Alternatively the TLLI may be sent as + * confirmation directly. */ + + /* Extract TLLI from the presented IMMEDIATE ASSIGNMENT + * (if present and only when TLLI that is supplied as function parameter is valid.) */ + if (data && tlli == GSM_RESERVED_TMSI) { + rc = tlli_from_imm_ass(&tlli, data, fn); + if (rc != 0) + return -EINVAL; + } + + /* Make sure TLLI is valid */ + if (tlli == GSM_RESERVED_TMSI) { + LOGP(DTBFDL, LOGL_ERROR, "FN=%u Got IMM.ASS confirm, but TLLI is invalid!\n", fn); + return -EINVAL; + } + + /* Find related TBF and send confirmation signal to FSM */ ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); if (!ms) { LOGP(DTBFDL, LOGL_ERROR, "FN=%u Got IMM.ASS confirm for unknown MS with TLLI=%08x\n", fn, tlli); diff --git a/src/bts.h b/src/bts.h index 61c5e43..5efbdad 100644 --- a/src/bts.h +++ b/src/bts.h @@ -315,7 +315,7 @@
int bts_rcv_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip); int bts_rcv_ptcch_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params *rip); -int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t fn); +int bts_rcv_imm_ass_cnf(struct gprs_rlcmac_bts *bts, const uint8_t *data, uint32_t tlli, uint32_t fn);
void bts_send_gsmtap(struct gprs_rlcmac_bts *bts, enum pcu_gsmtap_category categ, bool uplink, uint8_t trx_no, diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 69629db..02f56ac 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -512,7 +512,7 @@ switch (data_cnf->sapi) { case PCU_IF_SAPI_PCH: if (data_cnf->data[2] == GSM48_MT_RR_IMM_ASS) - bts_rcv_imm_ass_cnf(bts, data_cnf->data, data_cnf->fn); + bts_rcv_imm_ass_cnf(bts, data_cnf->data, GSM_RESERVED_TMSI, data_cnf->fn); break; default: LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with " @@ -523,6 +523,26 @@ return rc; }
+static int pcu_rx_data_cnf_dt(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_data_cnf_dt *data_cnf_dt) +{ + int rc = 0; + int current_fn = bts_current_frame_number(bts); + + LOGP(DL1IF, LOGL_DEBUG, "Data confirm received: sapi=%d fn=%d cur_fn=%d\n", + data_cnf_dt->sapi, data_cnf_dt->fn, current_fn); + + switch (data_cnf_dt->sapi) { + case PCU_IF_SAPI_PCH: + bts_rcv_imm_ass_cnf(bts, NULL, data_cnf_dt->tlli, data_cnf_dt->fn); + break; + default: + LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with unsupported sapi %d\n", data_cnf_dt->sapi); + rc = -EINVAL; + } + + return rc; +} + // FIXME: remove this, when changed from c++ to c. int pcu_rx_rts_req_pdtch(struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr) @@ -1133,6 +1153,10 @@ CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_cnf); rc = pcu_rx_data_cnf(bts, &pcu_prim->u.data_cnf); break; + case PCU_IF_MSG_DATA_CNF_DT: + CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_cnf_dt); + rc = pcu_rx_data_cnf_dt(bts, &pcu_prim->u.data_cnf_dt); + break; case PCU_IF_MSG_RTS_REQ: CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.rts_req); rc = pcu_rx_rts_req(bts, &pcu_prim->u.rts_req);
7 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one.