diff options
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/bts.cpp | 12 | ||||
-rw-r--r-- | src/bts.h | 10 | ||||
-rw-r--r-- | src/gprs_rlcmac.h | 19 | ||||
-rw-r--r-- | src/gprs_rlcmac_data.cpp | 14 | ||||
-rw-r--r-- | src/gprs_rlcmac_sched.cpp | 2 | ||||
-rw-r--r-- | src/pcu_l1_if.cpp | 4 | ||||
-rw-r--r-- | src/poll_controller.cpp | 4 | ||||
-rw-r--r-- | src/sba.cpp | 34 | ||||
-rw-r--r-- | src/sba.h | 65 | ||||
-rw-r--r-- | src/tbf.h | 1 |
11 files changed, 117 insertions, 51 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 813dfbe9..d1cbd4b4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -84,7 +84,8 @@ noinst_HEADERS = \ bts.h \ poll_controller.h \ encoding.h \ - ta.h + ta.h \ + sba.h osmo_pcu_SOURCES = pcu_main.cpp diff --git a/src/bts.cpp b/src/bts.cpp index 3d0fc335..353451c6 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -64,6 +64,7 @@ struct gprs_rlcmac_bts *bts_main_data() BTS::BTS() : m_cur_fn(0) , m_pollController(*this) + , m_sba(*this) { memset(&m_bts, 0, sizeof(m_bts)); m_bts.bts = this; @@ -165,10 +166,10 @@ void gprs_rlcmac_pdch::disable() m_is_enabled = 0; } -void gprs_rlcmac_pdch::free_resources(uint8_t trx, uint8_t ts) +/* TODO: kill the parameter and make a pdch belong to a trx.. to a bts.. */ +void gprs_rlcmac_pdch::free_resources(BTS *bts, uint8_t trx, uint8_t ts) { struct gprs_rlcmac_paging *pag; - struct gprs_rlcmac_sba *sba, *sba2; /* we are not enabled. there should be no resources */ if (!is_enabled()) @@ -181,12 +182,7 @@ void gprs_rlcmac_pdch::free_resources(uint8_t trx, uint8_t ts) while ((pag = dequeue_paging())) talloc_free(pag); - llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) { - if (sba->trx == trx && sba->ts == ts) { - llist_del(&sba->list); - talloc_free(sba); - } - } + bts->sba()->free_resources(trx, ts); } struct gprs_rlcmac_paging *gprs_rlcmac_pdch::dequeue_paging() @@ -28,6 +28,7 @@ extern "C" { } #include "poll_controller.h" +#include "sba.h" #include "ta.h" #endif @@ -47,7 +48,7 @@ struct gprs_rlcmac_pdch { void add_paging(struct gprs_rlcmac_paging *pag); /* TODO: the PDCH should know the trx/ts it belongs to */ - void free_resources(uint8_t trx, uint8_t ts); + void free_resources(BTS *bts, uint8_t trx, uint8_t ts); bool is_enabled() const; @@ -123,6 +124,7 @@ public: static BTS* main_bts(); struct gprs_rlcmac_bts *bts_data(); + SBAController *sba(); TimingAdvance *timing_advance(); /** TODO: change the number to unsigned */ @@ -136,6 +138,7 @@ private: int m_cur_fn; struct gprs_rlcmac_bts m_bts; PollController m_pollController; + SBAController m_sba; TimingAdvance m_ta; private: @@ -153,6 +156,11 @@ inline TimingAdvance *BTS::timing_advance() { return &m_ta; } + +inline SBAController *BTS::sba() +{ + return &m_sba; +} #endif #ifdef __cplusplus diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 2232e976..3a2569c3 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -56,17 +56,6 @@ struct gprs_rlcmac_paging { }; /* - * single block allocation entry - */ -struct gprs_rlcmac_sba { - struct llist_head list; - uint8_t trx; - uint8_t ts; - uint32_t fn; - uint8_t ta; -}; - -/* * coding scheme info */ struct gprs_rlcmac_cs { @@ -96,12 +85,6 @@ int gprs_rlcmac_rssi_rep(struct gprs_rlcmac_tbf *tbf); int gprs_rlcmac_dl_bw(struct gprs_rlcmac_tbf *tbf, uint16_t octets); -int sba_alloc(struct gprs_rlcmac_bts *bts, uint8_t *_trx, uint8_t *_ts, uint32_t *_fn, uint8_t ta); - -struct gprs_rlcmac_sba *sba_find(uint8_t trx, uint8_t ts, uint32_t fn); - -uint32_t sched_sba(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr); - /* TS 44.060 Section 10.4.7 Table 10.4.7.1: Payload Type field */ enum gprs_rlcmac_block_type { GPRS_RLCMAC_DATA_BLOCK = 0x0, @@ -118,8 +101,6 @@ int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf); int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf); -int gprs_rlcmac_sba_timeout(struct gprs_rlcmac_sba *sba); - 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, diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 9eba6bf6..ac83f571 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -382,7 +382,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF " "in packet ressource request of single " "block, so we provide one:\n"); - sba = sba_find(trx, ts, fn); + sba = bts->bts->sba()->find(trx, ts, fn); if (!sba) { LOGP(DRLCMAC, LOGL_NOTICE, "MS requests UL TBF " "in packet ressource request of single " @@ -436,7 +436,7 @@ int gprs_rlcmac_rcv_control_block(struct gprs_rlcmac_bts *bts, 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 = sba_find(trx, ts, fn); + sba = bts->bts->sba()->find(trx, ts, fn); if (!sba) { LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement " "in packet ressource request of single " @@ -684,7 +684,7 @@ struct msgb *gprs_rlcmac_send_uplink_ack(struct gprs_rlcmac_bts *bts, "final uplink ack...\n", tbf->tfi); return NULL; } - if (sba_find(tbf->trx_no, tbf->control_ts, (fn + 13) % 2715648)) { + if (bts->bts->sba()->find(tbf->trx_no, tbf->control_ts, (fn + 13) % 2715648)) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " "scheduled for single block allocation...\n"); return NULL; @@ -961,7 +961,7 @@ struct msgb *gprs_rlcmac_send_packet_uplink_assignment( "assignment...\n", tbf->tfi); return NULL; } - if (sba_find(tbf->trx_no, tbf->control_ts, (fn + 13) % 2715648)) { + if (bts->bts->sba()->find(tbf->trx_no, tbf->control_ts, (fn + 13) % 2715648)) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already scheduled for " "single block allocation...\n"); return NULL; @@ -1047,7 +1047,7 @@ int gprs_rlcmac_rcv_rach(struct gprs_rlcmac_bts *bts, if (qta > 252) qta = 252; if (sb) { - rc = sba_alloc(bts, &trx, &ts, &sb_fn, qta >> 2); + rc = bts->bts->sba()->alloc(&trx, &ts, &sb_fn, qta >> 2); if (rc < 0) return rc; LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] RACH qbit-ta=%d " @@ -1421,7 +1421,7 @@ tx_block: LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be " "sheduled in this TS %d, waiting for " "TS %d\n", ts, tbf->control_ts); - else if (sba_find(tbf->trx_no, ts, (fn + 13) % 2715648)) + else if (bts->bts->sba()->find(tbf->trx_no, ts, (fn + 13) % 2715648)) LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be " "sheduled, because single block alllocation " "already exists\n"); @@ -1633,7 +1633,7 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment( "assignment...\n", tbf->tfi); return NULL; } - if (sba_find(tbf->trx_no, tbf->control_ts, (fn + 13) % 2715648)) { + if (bts->bts->sba()->find(tbf->trx_no, tbf->control_ts, (fn + 13) % 2715648)) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " "scheduled for single block allocation...\n"); return NULL; diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index d364adfe..42110931 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -244,7 +244,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts, ? "UL" : "DL", poll_tbf->tfi); /* use free USF */ /* else. check for sba */ - else if ((sba_fn = sched_sba(trx, ts, fn, block_nr) != 0xffffffff)) + else if ((sba_fn = bts->bts->sba()->sched(trx, ts, fn, block_nr) != 0xffffffff)) LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d " "TS=%d FN=%d block_nr=%d scheduling free USF for " "single block allocation at FN=%d\n", trx, ts, fn, diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index f2d51022..89d3eb2f 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -321,7 +321,7 @@ bssgp_failed: for (trx = 0; trx < 8; trx++) { bts->trx[trx].arfcn = info_ind->trx[trx].arfcn; for (ts = 0; ts < 8; ts++) - bts->trx[trx].pdch[ts].free_resources(trx, ts); + bts->trx[trx].pdch[ts].free_resources(bts->bts, trx, ts); } gprs_bssgp_destroy_or_exit(); return 0; @@ -456,7 +456,7 @@ bssgp_failed: } else { if (pdch->is_enabled()) { pcu_tx_act_req(trx, ts, 0); - pdch->free_resources(trx, ts); + pdch->free_resources(bts->bts, trx, ts); pdch->disable(); } } diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp index 59eef762..461b1a2b 100644 --- a/src/poll_controller.cpp +++ b/src/poll_controller.cpp @@ -51,11 +51,11 @@ void PollController::expireTimedout(int frame_number) gprs_rlcmac_poll_timeout(bts, tbf); } } - llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) { + llist_for_each_entry_safe(sba, sba2, &m_bts.sba()->m_sbas, list) { elapsed = (frame_number + 2715648 - sba->fn) % 2715648; if (elapsed >= 20 && elapsed < 2715400) { /* sba will be freed here */ - gprs_rlcmac_sba_timeout(sba); + m_bts.sba()->timeout(sba); } } diff --git a/src/sba.cpp b/src/sba.cpp index f0026490..4b856e00 100644 --- a/src/sba.cpp +++ b/src/sba.cpp @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <sba.h> #include <gprs_rlcmac.h> #include <gprs_debug.h> #include <bts.h> @@ -35,9 +36,13 @@ extern void *tall_pcu_ctx; * This offset must be a multiple of 13. */ #define AGCH_START_OFFSET 52 -LLIST_HEAD(gprs_rlcmac_sbas); +SBAController::SBAController(BTS &bts) + : m_bts(bts) +{ + INIT_LLIST_HEAD(&m_sbas); +} -int sba_alloc(struct gprs_rlcmac_bts *bts, +int SBAController::alloc( uint8_t *_trx, uint8_t *_ts, uint32_t *_fn, uint8_t ta) { @@ -52,7 +57,7 @@ int sba_alloc(struct gprs_rlcmac_bts *bts, for (trx = 0; trx < 8; trx++) { for (ts = 0; ts < 8; ts++) { - pdch = &bts->trx[trx].pdch[ts]; + pdch = &m_bts.bts_data()->trx[trx].pdch[ts]; if (!pdch->is_enabled()) continue; break; @@ -73,7 +78,7 @@ int sba_alloc(struct gprs_rlcmac_bts *bts, sba->fn = fn; sba->ta = ta; - llist_add(&sba->list, &gprs_rlcmac_sbas); + llist_add(&sba->list, &m_sbas); *_trx = trx; *_ts = ts; @@ -81,11 +86,11 @@ int sba_alloc(struct gprs_rlcmac_bts *bts, return 0; } -struct gprs_rlcmac_sba *sba_find(uint8_t trx, uint8_t ts, uint32_t fn) +gprs_rlcmac_sba *SBAController::find(uint8_t trx, uint8_t ts, uint32_t fn) { struct gprs_rlcmac_sba *sba; - llist_for_each_entry(sba, &gprs_rlcmac_sbas, list) { + llist_for_each_entry(sba, &m_sbas, list) { if (sba->trx == trx && sba->ts == ts && sba->fn == fn) return sba; } @@ -93,7 +98,7 @@ struct gprs_rlcmac_sba *sba_find(uint8_t trx, uint8_t ts, uint32_t fn) return NULL; } -uint32_t sched_sba(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr) +uint32_t SBAController::sched(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr) { uint32_t sba_fn; struct gprs_rlcmac_sba *sba; @@ -103,14 +108,14 @@ uint32_t sched_sba(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr) if ((block_nr % 3) == 2) sba_fn ++; sba_fn = sba_fn % 2715648; - sba = sba_find(trx, ts, sba_fn); + sba = find(trx, ts, sba_fn); if (sba) return sba_fn; return 0xffffffff; } -int gprs_rlcmac_sba_timeout(struct gprs_rlcmac_sba *sba) +int SBAController::timeout(struct gprs_rlcmac_sba *sba) { LOGP(DRLCMAC, LOGL_NOTICE, "Poll timeout for SBA\n"); llist_del(&sba->list); @@ -119,3 +124,14 @@ int gprs_rlcmac_sba_timeout(struct gprs_rlcmac_sba *sba) return 0; } +void SBAController::free_resources(uint8_t trx, uint8_t ts) +{ + struct gprs_rlcmac_sba *sba, *sba2; + + llist_for_each_entry_safe(sba, sba2, &m_sbas, list) { + if (sba->trx == trx && sba->ts == ts) { + llist_del(&sba->list); + talloc_free(sba); + } + } +} diff --git a/src/sba.h b/src/sba.h new file mode 100644 index 00000000..c25aa14f --- /dev/null +++ b/src/sba.h @@ -0,0 +1,65 @@ +/* + * + * Copyright (C) 2012 Ivan Klyuchnikov + * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu> + * Copyright (C) 2013 by Holger Hans Peter Freyther + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#pragma once + +#include <stdint.h> + +extern "C" { +#include <osmocom/core/linuxlist.h> +} + +class BTS; +class PollController; +struct gprs_rlcmac_sba; + +/* + * single block allocation entry + */ +struct gprs_rlcmac_sba { + struct llist_head list; + uint8_t trx; + uint8_t ts; + uint32_t fn; + uint8_t ta; +}; + +/** + * I help to manage SingleBlockAssignment (SBA). + * + * TODO: Add a flush method.. + */ +class SBAController { + friend class PollController; +public: + SBAController(BTS &bts); + + int alloc(uint8_t *_trx, uint8_t *_ts, uint32_t *_fn, uint8_t ta); + gprs_rlcmac_sba *find(uint8_t trx, uint8_t ts, uint32_t fn); + + uint32_t sched(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr); + + int timeout(struct gprs_rlcmac_sba *sba); + void free_resources(uint8_t trx, uint8_t ts); + +private: + BTS &m_bts; + llist_head m_sbas; +}; @@ -84,7 +84,6 @@ enum gprs_rlcmac_tbf_direction { extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ extern struct llist_head gprs_rlcmac_dl_tbfs; /* list of downlink TBFs */ -extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ struct gprs_rlcmac_tbf { |