From fcbc70211208323b22ab9805cdf19769cce72d23 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 26 Oct 2013 17:38:37 +0200 Subject: pdch: Move the giant switch/case of gprs_rlcmac_rcv_control_block Move the dispatch into the PDCH. This needs to be split up further into understandable blocks. --- src/bts.cpp | 254 +++++++++++++++++++++++++++++++++++++++++++- src/bts.h | 3 + src/decoding.cpp | 15 +++ src/decoding.h | 3 + src/gprs_rlcmac.h | 4 - src/gprs_rlcmac_data.cpp | 267 ----------------------------------------------- 6 files changed, 274 insertions(+), 272 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 95672143..3c7ce407 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -571,6 +571,258 @@ int gprs_rlcmac_pdch::rcv_data_block_acknowledged(struct gprs_rlcmac_bts *bts, return 0; } +/* Received Uplink RLC control block. */ +int gprs_rlcmac_pdch::rcv_control_block(struct gprs_rlcmac_bts *bts, + bitvec *rlc_block, uint8_t trx, uint8_t ts, + uint32_t fn) +{ + int8_t tfi = 0; /* must be signed */ + uint32_t tlli = 0; + struct gprs_rlcmac_tbf *tbf; + struct gprs_rlcmac_sba *sba; + int rc; + + RlcMacUplink_t * ul_control_block = (RlcMacUplink_t *)talloc_zero(tall_pcu_ctx, RlcMacUplink_t); + LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++\n"); + decode_gsm_rlcmac_uplink(rlc_block, ul_control_block); + LOGPC(DCSN1, LOGL_NOTICE, "\n"); + LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n"); + switch (ul_control_block->u.MESSAGE_TYPE) { + case MT_PACKET_CONTROL_ACK: + tlli = ul_control_block->u.Packet_Control_Acknowledgement.TLLI; + tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with " + "unknown FN=%u TLL=0x%08x (TRX %d TS %d)\n", + fn, tlli, trx, ts); + break; + } + tfi = tbf->tfi; + if (tlli != tbf->tlli) { + LOGP(DRLCMAC, LOGL_INFO, "Phone changed TLLI to " + "0x%08x\n", tlli); + tbf->tlli = tlli; + } + LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Control Ack\n", tbf->tfi, tbf->tlli); + tbf->poll_state = GPRS_RLCMAC_POLL_NONE; + + /* check if this control ack belongs to packet uplink ack */ + if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) { + LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); + tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; + debug_diagram(bts->bts, tbf->diag, "got CTL-ACK (fin)"); + if ((tbf->state_flags & + (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) { + tbf->state_flags &= + ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ACK); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink " + "ack for UL TBF=%d\n", tbf->tfi); + } + tbf_free(tbf); + break; + } + if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) { + LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] DOWNLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); + /* reset N3105 */ + tbf->n3105 = 0; + tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + debug_diagram(bts->bts, tbf->diag, "got CTL-ACK DL-ASS"); + if (tbf->direction == GPRS_RLCMAC_UL_TBF) + tbf = bts->bts->tbf_by_tlli(tbf->tlli, + GPRS_RLCMAC_DL_TBF); + if (!tbf) { + LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but DL " + "TBF is gone\n"); + break; + } + tbf_new_state(tbf, GPRS_RLCMAC_FLOW); + /* stop pending assignment timer */ + tbf_timer_stop(tbf); + if ((tbf->state_flags & + (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) { + tbf->state_flags &= + ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink " + "assignment for DL TBF=%d\n", tbf->tfi); + } + tbf_assign_control_ts(tbf); + break; + } + if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) { + LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] UPLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); + /* reset N3105 */ + tbf->n3105 = 0; + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; + debug_diagram(bts->bts, tbf->diag, "got CTL-AC UL-ASS"); + if (tbf->direction == GPRS_RLCMAC_DL_TBF) + tbf = bts->bts->tbf_by_tlli(tbf->tlli, + GPRS_RLCMAC_UL_TBF); + if (!tbf) { + LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but UL " + "TBF is gone\n"); + break; + } + tbf_new_state(tbf, GPRS_RLCMAC_FLOW); + if ((tbf->state_flags & + (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) { + tbf->state_flags &= + ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink " + "assignment for UL TBF=%d\n", tbf->tfi); + } + tbf_assign_control_ts(tbf); + break; + } + LOGP(DRLCMAC, LOGL_ERROR, "Error: received PACET CONTROL ACK " + "at no request\n"); + break; + case MT_PACKET_DOWNLINK_ACK_NACK: + tfi = ul_control_block->u.Packet_Downlink_Ack_Nack.DOWNLINK_TFI; + tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with " + "unknown FN=%u TFI=%d (TRX %d TS %d)\n", + fn, tfi, trx, ts); + break; + } + if (tbf->tfi != tfi) { + LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with " + "wrong TFI=%d, ignoring!\n", tfi); + break; + } + tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK); + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { + tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink ack " + "for DL TBF=%d\n", tbf->tfi); + } + /* reset N3105 */ + tbf->n3105 = 0; + /* stop timer T3191 */ + tbf_timer_stop(tbf); + tlli = tbf->tlli; + LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Downlink Ack/Nack\n", tbf->tfi, tbf->tlli); + tbf->poll_state = GPRS_RLCMAC_POLL_NONE; + debug_diagram(bts->bts, tbf->diag, "got DL-ACK"); + + rc = gprs_rlcmac_downlink_ack(tbf, + ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.FINAL_ACK_INDICATION, + ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER, + ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP); + if (rc == 1) { + tbf_free(tbf); + break; + } + /* check for channel request */ + if (ul_control_block->u.Packet_Downlink_Ack_Nack.Exist_Channel_Request_Description) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " + "message, so we provide one:\n"); + tbf_alloc_ul(bts, tbf->trx_no, tbf->ms_class, tbf->tlli, tbf->ta, tbf); + /* schedule uplink assignment */ + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; + } + break; + case MT_PACKET_RESOURCE_REQUEST: + if (ul_control_block->u.Packet_Resource_Request.ID.UnionType) { + tlli = ul_control_block->u.Packet_Resource_Request.ID.u.TLLI; + tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); + if (tbf) { + LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " + "TLLI=0x%08x while UL TBF=%d still " + "exists. Killing pending DL TBF\n", + tlli, tbf->tfi); + tbf_free(tbf); + tbf = NULL; + } + if (!tbf) { + uint8_t ms_class = 0; + struct gprs_rlcmac_tbf *dl_tbf; + uint8_t ta; + + if ((dl_tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) { + LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " + "TLLI=0x%08x while DL TBF=%d still exists. " + "Killing pending DL TBF\n", tlli, + dl_tbf->tfi); + tbf_free(dl_tbf); + } + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF " + "in packet ressource request of single " + "block, so we provide one:\n"); + sba = bts->bts->sba()->find(trx, ts, fn); + if (!sba) { + LOGP(DRLCMAC, LOGL_NOTICE, "MS requests UL TBF " + "in packet ressource request of single " + "block, but there is no resource request " + "scheduled!\n"); + rc = bts->bts->timing_advance()->recall(tlli); + if (rc >= 0) + ta = rc; + else + ta = 0; + } else { + ta = sba->ta; + bts->bts->timing_advance()->remember(tlli, ta); + llist_del(&sba->list); + talloc_free(sba); + } + if (ul_control_block->u.Packet_Resource_Request.Exist_MS_Radio_Access_capability) + ms_class = Decoding::get_ms_class_by_capability(&ul_control_block->u.Packet_Resource_Request.MS_Radio_Access_capability); + if (!ms_class) + LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n"); + tbf = tbf_alloc_ul(bts, trx, ms_class, tlli, ta, NULL); + if (!tbf) + break; + /* set control ts to current MS's TS, until assignment complete */ + LOGP(DRLCMAC, LOGL_DEBUG, "Change control TS to %d until assinment is complete.\n", ts); + tbf->control_ts = ts; + /* schedule uplink assignment */ + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; + debug_diagram(bts->bts, tbf->diag, "Res. REQ"); + break; + } + tfi = tbf->tfi; + } else { + if (ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.UnionType) { + tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.DOWNLINK_TFI; + tbf = tbf_by_tfi(bts, tfi, trx, GPRS_RLCMAC_DL_TBF); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TBF=%d\n", tlli); + break; + } + } else { + tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.UPLINK_TFI; + tbf = tbf_by_tfi(bts, tfi, trx, GPRS_RLCMAC_UL_TBF); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TBF=%d\n", tlli); + break; + } + } + tlli = tbf->tlli; + } + LOGP(DRLCMAC, LOGL_ERROR, "RX: [PCU <- BTS] %s TFI: %u TLLI: 0x%08x FIXME: Packet ressource request\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf->tlli); + break; + case MT_PACKET_MEASUREMENT_REPORT: + sba = bts->bts->sba()->find(trx, ts, fn); + if (!sba) { + LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement " + "in packet ressource request of single " + "block, but there is no resource request " + "scheduled!\n"); + } else { + bts->bts->timing_advance()->remember(ul_control_block->u.Packet_Measurement_Report.TLLI, sba->ta); + llist_del(&sba->list); + talloc_free(sba); + } + gprs_rlcmac_meas_rep(&ul_control_block->u.Packet_Measurement_Report); + break; + default: + LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] unknown control block received\n"); + } + talloc_free(ul_control_block); + return 1; +} + /* received RLC/MAC block from L1 */ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int8_t rssi) @@ -590,7 +842,7 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int8_t if (!block) return -ENOMEM; bitvec_unpack(block, data); - rc = gprs_rlcmac_rcv_control_block(bts, block, trx_no, ts_no, fn); + rc = rcv_control_block(bts, block, trx_no, ts_no, fn); bitvec_free(block); break; case GPRS_RLCMAC_CONTROL_BLOCK_OPT: diff --git a/src/bts.h b/src/bts.h index 7eabfbc8..541b9b20 100644 --- a/src/bts.h +++ b/src/bts.h @@ -76,6 +76,9 @@ private: int rcv_data_block_acknowledged(struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts, uint8_t *data, uint8_t len, int8_t rssi); + int rcv_control_block(struct gprs_rlcmac_bts *bts, + bitvec *rlc_block, uint8_t trx, uint8_t ts, + uint32_t fn); #endif }; diff --git a/src/decoding.cpp b/src/decoding.cpp index 596b66eb..e7ec99ab 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -68,3 +68,18 @@ int Decoding::tlli_from_ul_data(const uint8_t *data, uint8_t len, return 0; } +uint8_t Decoding::get_ms_class_by_capability(MS_Radio_Access_capability_t *cap) +{ + int i; + + for (i = 0; i < cap->Count_MS_RA_capability_value; i++) { + if (!cap->MS_RA_capability_value[i].u.Content.Exist_Multislot_capability) + continue; + if (!cap->MS_RA_capability_value[i].u.Content.Multislot_capability.Exist_GPRS_multislot_class) + continue; + return cap->MS_RA_capability_value[i].u.Content.Multislot_capability.GPRS_multislot_class; + } + + return 0; +} + diff --git a/src/decoding.h b/src/decoding.h index 47983a2a..0590eb40 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -19,10 +19,13 @@ */ #pragma once +#include + #include class Decoding { public: static int tlli_from_ul_data(const uint8_t *data, uint8_t len, uint32_t *tlli); + static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap); }; diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index af15e77a..4fe5067a 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -98,10 +98,6 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf int gprs_rlcmac_rcv_rach(struct gprs_rlcmac_bts *bts, uint8_t ra, uint32_t Fn, int16_t qta); -int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, - bitvec *rlc_block, uint8_t trx, uint8_t ts, - uint32_t fn); - struct msgb *gprs_rlcmac_send_packet_uplink_assignment( struct gprs_rlcmac_tbf *tbf, uint32_t fn); diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index f2887b2a..1f81201b 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -159,273 +159,6 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf return 0; } -static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap) -{ - int i; - - for (i = 0; i < cap->Count_MS_RA_capability_value; i++) { - if (!cap->MS_RA_capability_value[i].u.Content.Exist_Multislot_capability) - continue; - if (!cap->MS_RA_capability_value[i].u.Content.Multislot_capability.Exist_GPRS_multislot_class) - continue; - return cap->MS_RA_capability_value[i].u.Content.Multislot_capability.GPRS_multislot_class; - } - - return 0; -} - -/* Received Uplink RLC control block. */ -int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, - bitvec *rlc_block, uint8_t trx, uint8_t ts, - uint32_t fn) -{ - int8_t tfi = 0; /* must be signed */ - uint32_t tlli = 0; - struct gprs_rlcmac_tbf *tbf; - struct gprs_rlcmac_sba *sba; - int rc; - - RlcMacUplink_t * ul_control_block = (RlcMacUplink_t *)talloc_zero(tall_pcu_ctx, RlcMacUplink_t); - LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++\n"); - decode_gsm_rlcmac_uplink(rlc_block, ul_control_block); - LOGPC(DCSN1, LOGL_NOTICE, "\n"); - LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n"); - switch (ul_control_block->u.MESSAGE_TYPE) { - case MT_PACKET_CONTROL_ACK: - tlli = ul_control_block->u.Packet_Control_Acknowledgement.TLLI; - tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts); - if (!tbf) { - LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with " - "unknown FN=%u TLL=0x%08x (TRX %d TS %d)\n", - fn, tlli, trx, ts); - break; - } - tfi = tbf->tfi; - if (tlli != tbf->tlli) { - LOGP(DRLCMAC, LOGL_INFO, "Phone changed TLLI to " - "0x%08x\n", tlli); - tbf->tlli = tlli; - } - LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Control Ack\n", tbf->tfi, tbf->tlli); - tbf->poll_state = GPRS_RLCMAC_POLL_NONE; - - /* check if this control ack belongs to packet uplink ack */ - if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) { - LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); - tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; - debug_diagram(bts->bts, tbf->diag, "got CTL-ACK (fin)"); - if ((tbf->state_flags & - (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) { - tbf->state_flags &= - ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ACK); - LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink " - "ack for UL TBF=%d\n", tbf->tfi); - } - tbf_free(tbf); - break; - } - if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) { - LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] DOWNLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); - /* reset N3105 */ - tbf->n3105 = 0; - tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; - debug_diagram(bts->bts, tbf->diag, "got CTL-ACK DL-ASS"); - if (tbf->direction == GPRS_RLCMAC_UL_TBF) - tbf = bts->bts->tbf_by_tlli(tbf->tlli, - GPRS_RLCMAC_DL_TBF); - if (!tbf) { - LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but DL " - "TBF is gone\n"); - break; - } - tbf_new_state(tbf, GPRS_RLCMAC_FLOW); - /* stop pending assignment timer */ - tbf_timer_stop(tbf); - if ((tbf->state_flags & - (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) { - tbf->state_flags &= - ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS); - LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink " - "assignment for DL TBF=%d\n", tbf->tfi); - } - tbf_assign_control_ts(tbf); - break; - } - if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) { - LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] UPLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); - /* reset N3105 */ - tbf->n3105 = 0; - tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; - debug_diagram(bts->bts, tbf->diag, "got CTL-AC UL-ASS"); - if (tbf->direction == GPRS_RLCMAC_DL_TBF) - tbf = bts->bts->tbf_by_tlli(tbf->tlli, - GPRS_RLCMAC_UL_TBF); - if (!tbf) { - LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but UL " - "TBF is gone\n"); - break; - } - tbf_new_state(tbf, GPRS_RLCMAC_FLOW); - if ((tbf->state_flags & - (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) { - tbf->state_flags &= - ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS); - LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink " - "assignment for UL TBF=%d\n", tbf->tfi); - } - tbf_assign_control_ts(tbf); - break; - } - LOGP(DRLCMAC, LOGL_ERROR, "Error: received PACET CONTROL ACK " - "at no request\n"); - break; - case MT_PACKET_DOWNLINK_ACK_NACK: - tfi = ul_control_block->u.Packet_Downlink_Ack_Nack.DOWNLINK_TFI; - tbf = bts->bts->tbf_by_poll_fn(fn, trx, ts); - if (!tbf) { - LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with " - "unknown FN=%u TFI=%d (TRX %d TS %d)\n", - fn, tfi, trx, ts); - break; - } - if (tbf->tfi != tfi) { - LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with " - "wrong TFI=%d, ignoring!\n", tfi); - break; - } - tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { - tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); - LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink ack " - "for DL TBF=%d\n", tbf->tfi); - } - /* reset N3105 */ - tbf->n3105 = 0; - /* stop timer T3191 */ - tbf_timer_stop(tbf); - tlli = tbf->tlli; - LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Downlink Ack/Nack\n", tbf->tfi, tbf->tlli); - tbf->poll_state = GPRS_RLCMAC_POLL_NONE; - debug_diagram(bts->bts, tbf->diag, "got DL-ACK"); - - rc = gprs_rlcmac_downlink_ack(tbf, - ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.FINAL_ACK_INDICATION, - ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER, - ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP); - if (rc == 1) { - tbf_free(tbf); - break; - } - /* check for channel request */ - if (ul_control_block->u.Packet_Downlink_Ack_Nack.Exist_Channel_Request_Description) { - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " - "message, so we provide one:\n"); - tbf_alloc_ul(bts, tbf->trx_no, tbf->ms_class, tbf->tlli, tbf->ta, tbf); - /* schedule uplink assignment */ - tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; - } - break; - case MT_PACKET_RESOURCE_REQUEST: - if (ul_control_block->u.Packet_Resource_Request.ID.UnionType) { - tlli = ul_control_block->u.Packet_Resource_Request.ID.u.TLLI; - tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); - if (tbf) { - LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " - "TLLI=0x%08x while UL TBF=%d still " - "exists. Killing pending DL TBF\n", - tlli, tbf->tfi); - tbf_free(tbf); - tbf = NULL; - } - if (!tbf) { - uint8_t ms_class = 0; - struct gprs_rlcmac_tbf *dl_tbf; - uint8_t ta; - - if ((dl_tbf = bts->bts->tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) { - LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " - "TLLI=0x%08x while DL TBF=%d still exists. " - "Killing pending DL TBF\n", tlli, - dl_tbf->tfi); - tbf_free(dl_tbf); - } - LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF " - "in packet ressource request of single " - "block, so we provide one:\n"); - sba = bts->bts->sba()->find(trx, ts, fn); - if (!sba) { - LOGP(DRLCMAC, LOGL_NOTICE, "MS requests UL TBF " - "in packet ressource request of single " - "block, but there is no resource request " - "scheduled!\n"); - rc = bts->bts->timing_advance()->recall(tlli); - if (rc >= 0) - ta = rc; - else - ta = 0; - } else { - ta = sba->ta; - bts->bts->timing_advance()->remember(tlli, ta); - llist_del(&sba->list); - talloc_free(sba); - } - if (ul_control_block->u.Packet_Resource_Request.Exist_MS_Radio_Access_capability) - ms_class = get_ms_class_by_capability(&ul_control_block->u.Packet_Resource_Request.MS_Radio_Access_capability); - if (!ms_class) - LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n"); - tbf = tbf_alloc_ul(bts, trx, ms_class, tlli, ta, NULL); - if (!tbf) - break; - /* set control ts to current MS's TS, until assignment complete */ - LOGP(DRLCMAC, LOGL_DEBUG, "Change control TS to %d until assinment is complete.\n", ts); - tbf->control_ts = ts; - /* schedule uplink assignment */ - tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; - debug_diagram(bts->bts, tbf->diag, "Res. REQ"); - break; - } - tfi = tbf->tfi; - } else { - if (ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.UnionType) { - tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.DOWNLINK_TFI; - tbf = tbf_by_tfi(bts, tfi, trx, GPRS_RLCMAC_DL_TBF); - if (!tbf) { - LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TBF=%d\n", tlli); - break; - } - } else { - tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.UPLINK_TFI; - tbf = tbf_by_tfi(bts, tfi, trx, GPRS_RLCMAC_UL_TBF); - if (!tbf) { - LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TBF=%d\n", tlli); - break; - } - } - tlli = tbf->tlli; - } - LOGP(DRLCMAC, LOGL_ERROR, "RX: [PCU <- BTS] %s TFI: %u TLLI: 0x%08x FIXME: Packet ressource request\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf->tlli); - break; - case MT_PACKET_MEASUREMENT_REPORT: - sba = bts->bts->sba()->find(trx, ts, fn); - if (!sba) { - LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement " - "in packet ressource request of single " - "block, but there is no resource request " - "scheduled!\n"); - } else { - bts->bts->timing_advance()->remember(ul_control_block->u.Packet_Measurement_Report.TLLI, sba->ta); - llist_del(&sba->list); - talloc_free(sba); - } - gprs_rlcmac_meas_rep(&ul_control_block->u.Packet_Measurement_Report); - break; - default: - LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] unknown control block received\n"); - } - talloc_free(ul_control_block); - return 1; -} - #ifdef DEBUG_DL_ASS_IDLE char debug_imsi[16]; #endif -- cgit v1.2.3