aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am3
-rw-r--r--src/bts.cpp12
-rw-r--r--src/bts.h10
-rw-r--r--src/gprs_rlcmac.h19
-rw-r--r--src/gprs_rlcmac_data.cpp14
-rw-r--r--src/gprs_rlcmac_sched.cpp2
-rw-r--r--src/pcu_l1_if.cpp4
-rw-r--r--src/poll_controller.cpp4
-rw-r--r--src/sba.cpp34
-rw-r--r--src/sba.h65
-rw-r--r--src/tbf.h1
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()
diff --git a/src/bts.h b/src/bts.h
index 3a264f76..deaadcd7 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -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;
+};
diff --git a/src/tbf.h b/src/tbf.h
index 5464dd4f..5715f257 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -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 {