diff options
Diffstat (limited to 'src/gprs_bssgp_pcu.cpp')
-rw-r--r-- | src/gprs_bssgp_pcu.cpp | 121 |
1 files changed, 3 insertions, 118 deletions
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 4833af8a..3432bca8 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -21,6 +21,7 @@ #include <gprs_rlcmac.h> #include <gprs_bssgp_pcu.h> #include <pcu_l1_if.h> +#include <tbf.h> static struct gprs_bssgp_pcu the_pcu = { 0, }; @@ -103,12 +104,9 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) { struct bssgp_ud_hdr *budh; - int8_t tfi; /* must be signed */ - uint32_t tlli; uint8_t *data; uint16_t len; - struct gprs_rlcmac_tbf *tbf; char imsi[16] = "000"; budh = (struct bssgp_ud_hdr *)msgb_bssgph(msg); @@ -123,7 +121,7 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) data = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_LLC_PDU); len = TLVP_LEN(tp, BSSGP_IE_LLC_PDU); - if (len > sizeof(tbf->llc_frame)) + if (len > sizeof(gprs_rlcmac_tbf::llc_frame)) { LOGP(DBSSGP, LOGL_NOTICE, "BSSGP TLLI=0x%08x Rx UL-UD IE_LLC_PDU too large\n", tlli); return bssgp_tx_status(BSSGP_CAUSE_COND_IE_ERR, NULL, msg); @@ -154,120 +152,7 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) LOGP(DBSSGP, LOGL_INFO, "LLC [SGSN -> PCU] = TLLI: 0x%08x IMSI: %s len: %d\n", tlli, imsi, len); - /* check for existing TBF */ - if ((tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) { - LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli); - if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) { - LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state " - "(T3193), so reuse TBF\n"); - memcpy(tbf->llc_frame, data, len); - tbf->llc_length = len; - memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl)); /* reset - rlc states */ - tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; /* keep - to flags */ - tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); - if (!tbf->ms_class && ms_class) - tbf->ms_class = ms_class; - tbf_update(tbf); - gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL); - } else { - /* the TBF exists, so we must write it in the queue - * we prepend lifetime in front of PDU */ - struct timeval *tv; - struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv), - "llc_pdu_queue"); - if (!llc_msg) - return -ENOMEM; - tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv)); - if (the_pcu.bts->force_llc_lifetime) - delay_csec = the_pcu.bts->force_llc_lifetime; - /* keep timestap at 0 for infinite delay */ - if (delay_csec != 0xffff) { - /* calculate timestamp of timeout */ - gettimeofday(tv, NULL); - tv->tv_usec += (delay_csec % 100) * 10000; - tv->tv_sec += delay_csec / 100; - if (tv->tv_usec > 999999) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } - } - memcpy(msgb_put(llc_msg, len), data, len); - msgb_enqueue(&tbf->llc_queue, llc_msg); - /* set ms class for updating TBF */ - if (!tbf->ms_class && ms_class) - tbf->ms_class = ms_class; - } - } else { - uint8_t trx, ta, ss; - int8_t use_trx; - struct gprs_rlcmac_tbf *old_tbf; - int rc; - - /* check for uplink data, so we copy our informations */ - tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); - if (tbf && tbf->dir.ul.contention_resolution_done - && !tbf->dir.ul.final_ack_sent) { - use_trx = tbf->trx; - ta = tbf->ta; - ss = 0; - old_tbf = tbf; - } else { - use_trx = -1; - /* we already have an uplink TBF, so we use that TA */ - if (tbf) - ta = tbf->ta; - else { - /* recall TA */ - rc = recall_timing_advance(tlli); - if (rc < 0) { - LOGP(DRLCMAC, LOGL_NOTICE, "TA unknown" - ", assuming 0\n"); - ta = 0; - } else - ta = rc; - } - ss = 1; /* PCH assignment only allows one timeslot */ - old_tbf = NULL; - } - - // Create new TBF (any TRX) - tfi = tfi_find_free(the_pcu.bts, GPRS_RLCMAC_DL_TBF, &trx, use_trx); - if (tfi < 0) { - LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); - /* FIXME: send reject */ - return -EBUSY; - } - /* set number of downlink slots according to multislot class */ - tbf = tbf_alloc(the_pcu.bts, tbf, GPRS_RLCMAC_DL_TBF, tfi, trx, ms_class, - ss); - if (!tbf) { - LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); - /* FIXME: send reject */ - return -EBUSY; - } - tbf->tlli = tlli; - tbf->tlli_valid = 1; - tbf->ta = ta; - - LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] START TFI: %d TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); - - /* new TBF, so put first frame */ - memcpy(tbf->llc_frame, data, len); - tbf->llc_length = len; - - /* trigger downlink assignment and set state to ASSIGN. - * we don't use old_downlink, so the possible uplink is used - * to trigger downlink assignment. if there is no uplink, - * AGCH is used. */ - gprs_rlcmac_trigger_downlink_assignment(tbf, old_tbf, imsi); - } - - /* store IMSI for debugging purpose */ - strncpy(tbf->meas.imsi, imsi, sizeof(tbf->meas.imsi) - 1); - - return 0; + return tbf_handle(the_pcu.bts, tlli, imsi, ms_class, delay_csec, data, len); } int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, struct tlv_parsed *tp) |