aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-10-17 19:41:11 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-10-30 21:20:45 +0100
commitb6acfdaa24851e1aa95bfc4611709737aaafa5f1 (patch)
tree77ccb6c9ba4d387381fd82e3768189a6e7a334a7
parent67ed34eedb59320095396ff2f65f360c046d88c5 (diff)
bts: Introduce a singleton for the BTS and use it in the code
Compared to the previous code there will be a branch to get the global pointer so the code will be slightly slower than the previous version but it allows us to start creating objects but still use the code from C. It is best approach I have found so far. One downside of C++ is that by default talloc will not be used (unless we override the new operator to use talloc. Right now we need to memset the C data structure by hand. The benefit of enforcing a better structure should is more important though.
-rw-r--r--src/Makefile.am3
-rw-r--r--src/bts.cpp45
-rw-r--r--src/bts.h39
-rw-r--r--src/gprs_rlcmac.h3
-rw-r--r--src/pcu_l1_if.cpp21
-rw-r--r--src/pcu_main.cpp8
-rw-r--r--src/pcu_vty.c24
-rw-r--r--src/sysmo_sock.cpp2
-rw-r--r--tests/alloc/AllocTest.cpp2
-rw-r--r--tests/emu/pcu_emu.cpp18
10 files changed, 116 insertions, 49 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index f0fb7bd..012f8a9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,7 +42,8 @@ libgprs_la_SOURCES = \
bitvector.cpp \
pcu_l1_if.cpp \
pcu_vty.c \
- tbf.cpp
+ tbf.cpp \
+ bts.cpp
if ENABLE_SYSMOBTS
libgprs_la_SOURCES += \
diff --git a/src/bts.cpp b/src/bts.cpp
new file mode 100644
index 0000000..0609a5f
--- /dev/null
+++ b/src/bts.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 by Holger Hans Peter Freyther
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 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 Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <bts.h>
+#include <string.h>
+
+static BTS s_bts;
+
+BTS* BTS::main_bts()
+{
+ return &s_bts;
+}
+
+struct gprs_rlcmac_bts *BTS::bts_data()
+{
+ return &m_bts;
+}
+
+struct gprs_rlcmac_bts *bts_main_data()
+{
+ return BTS::main_bts()->bts_data();
+}
+
+BTS::BTS()
+{
+ memset(&m_bts, 0, sizeof(m_bts));
+ m_bts.bts = this;
+}
diff --git a/src/bts.h b/src/bts.h
index f17b3b7..9a5b570 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -31,6 +31,7 @@ extern "C" {
#include <stdint.h>
struct gprs_rlcmac_tbf;
+struct BTS;
/*
* PDCH instance
@@ -54,7 +55,10 @@ struct gprs_rlcmac_trx {
struct gprs_rlcmac_tbf *dl_tbf[32]; /* array of DL TBF, by DL TFI */
};
-
+/**
+ * This is the data from C. As soon as our minimal compiler is gcc 4.7
+ * we can start to compile pcu_vty.c with c++ and remove the split.
+ */
struct gprs_rlcmac_bts {
uint8_t bsic;
uint8_t fc_interval;
@@ -80,4 +84,37 @@ struct gprs_rlcmac_bts {
uint32_t alloc_algorithm_curst; /* options to customize algorithm */
uint8_t force_two_phase;
uint8_t alpha, gamma;
+
+ /**
+ * Point back to the C++ object. This is used during the transition
+ * period.
+ */
+ struct BTS *bts;
+};
+
+#ifdef __cplusplus
+/**
+ * I represent a GSM BTS. I have one or more TRX, I know the current
+ * GSM time and I have controllers that help with allocating resources
+ * on my TRXs.
+ */
+struct BTS {
+public:
+ BTS();
+
+ static BTS* main_bts();
+
+ struct gprs_rlcmac_bts *bts_data();
+
+private:
+ struct gprs_rlcmac_bts m_bts;
};
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ struct gprs_rlcmac_bts *bts_main_data();
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index 2bc88cb..4b9119b 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -43,8 +43,7 @@ extern "C" {
struct gprs_rlcmac_tbf;
-
-extern struct gprs_rlcmac_bts *gprs_rlcmac_bts;
+struct gprs_rlcmac_bts;
#ifdef __cplusplus
/*
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index e70de55..8239247 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -138,7 +138,7 @@ void pcu_l1if_tx_pdtch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn,
uint32_t fn, uint8_t block_nr)
{
#ifdef ENABLE_SYSMODSP
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
if (bts->trx[trx].fl1h)
l1if_pdch_req(bts->trx[trx].fl1h, ts, 0, fn, arfcn, block_nr,
@@ -154,7 +154,7 @@ void pcu_l1if_tx_ptcch(msgb *msg, uint8_t trx, uint8_t ts, uint16_t arfcn,
uint32_t fn, uint8_t block_nr)
{
#ifdef ENABLE_SYSMODSP
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
if (bts->trx[trx].fl1h)
l1if_pdch_req(bts->trx[trx].fl1h, ts, 1, fn, arfcn, block_nr,
@@ -196,7 +196,8 @@ void pcu_l1if_tx_pch(bitvec * block, int plen, const char *imsi)
extern "C" int pcu_rx_data_ind_pdtch(uint8_t trx, uint8_t ts, uint8_t *data,
uint8_t len, uint32_t fn, int8_t rssi)
{
- return gprs_rlcmac_rcv_block(gprs_rlcmac_bts, trx, ts, data, len, fn, rssi);
+ return gprs_rlcmac_rcv_block(bts_main_data(),
+ trx, ts, data, len, fn, rssi);
}
static int pcu_rx_data_ind(struct gsm_pcu_if_data *data_ind)
@@ -249,7 +250,8 @@ static int pcu_rx_data_cnf(struct gsm_pcu_if_data *data_cnf)
extern "C" int pcu_rx_rts_req_pdtch(uint8_t trx, uint8_t ts, uint16_t arfcn,
uint32_t fn, uint8_t block_nr)
{
- return gprs_rlcmac_rcv_rts_block(gprs_rlcmac_bts, trx, ts, arfcn, fn, block_nr);
+ return gprs_rlcmac_rcv_rts_block(bts_main_data(),
+ trx, ts, arfcn, fn, block_nr);
}
static int pcu_rx_rts_req(struct gsm_pcu_if_rts_req *rts_req)
@@ -293,7 +295,7 @@ static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind)
switch (rach_ind->sapi) {
case PCU_IF_SAPI_RACH:
- rc = gprs_rlcmac_rcv_rach(gprs_rlcmac_bts,
+ rc = gprs_rlcmac_rcv_rach(bts_main_data(),
rach_ind->ra, rach_ind->fn,
rach_ind->qta);
break;
@@ -330,7 +332,7 @@ int flush_pdch(struct gprs_rlcmac_pdch *pdch, uint8_t trx, uint8_t ts)
static int pcu_rx_info_ind(struct gsm_pcu_if_info_ind *info_ind)
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
struct gprs_bssgp_pcu *pcu;
struct gprs_rlcmac_pdch *pdch;
struct in_addr ia;
@@ -505,6 +507,7 @@ bssgp_failed:
static int pcu_rx_time_ind(struct gsm_pcu_if_time_ind *time_ind)
{
+ struct gprs_rlcmac_bts *bts = bts_main_data();
struct gprs_rlcmac_tbf *tbf;
struct gprs_rlcmac_sba *sba, *sba2;
uint32_t elapsed;
@@ -525,7 +528,7 @@ static int pcu_rx_time_ind(struct gsm_pcu_if_time_ind *time_ind)
elapsed = (frame_number + 2715648 - tbf->poll_fn)
% 2715648;
if (elapsed >= 20 && elapsed < 2715400)
- gprs_rlcmac_poll_timeout(gprs_rlcmac_bts, tbf);
+ gprs_rlcmac_poll_timeout(bts, tbf);
}
}
llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) {
@@ -533,7 +536,7 @@ static int pcu_rx_time_ind(struct gsm_pcu_if_time_ind *time_ind)
elapsed = (frame_number + 2715648 - tbf->poll_fn)
% 2715648;
if (elapsed >= 20 && elapsed < 2715400)
- gprs_rlcmac_poll_timeout(gprs_rlcmac_bts, tbf);
+ gprs_rlcmac_poll_timeout(bts, tbf);
}
}
llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) {
@@ -552,7 +555,7 @@ static int pcu_rx_pag_req(struct gsm_pcu_if_pag_req *pag_req)
LOGP(DL1IF, LOGL_DEBUG, "Paging request received: chan_needed=%d "
"length=%d\n", pag_req->chan_needed, pag_req->identity_lv[0]);
- return gprs_rlcmac_add_paging(gprs_rlcmac_bts, pag_req->chan_needed,
+ return gprs_rlcmac_add_paging(bts_main_data(), pag_req->chan_needed,
pag_req->identity_lv);
}
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index 4ea4252..a3b75ac 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -34,7 +34,6 @@ extern "C" {
#include <osmocom/vty/logging.h>
}
-struct gprs_rlcmac_bts *gprs_rlcmac_bts;
extern struct gprs_nsvc *nsvc;
uint16_t spoof_mcc = 0, spoof_mnc = 0;
static int config_given = 0;
@@ -164,10 +163,7 @@ int main(int argc, char *argv[])
return -ENOMEM;
bv_tall_ctx = tall_pcu_ctx;
- bts = gprs_rlcmac_bts = talloc_zero(tall_pcu_ctx,
- struct gprs_rlcmac_bts);
- if (!gprs_rlcmac_bts)
- return -ENOMEM;
+ bts = bts_main_data();
bts->fc_interval = 1;
bts->initial_cs_dl = bts->initial_cs_ul = 1;
bts->cs1 = 1;
@@ -256,8 +252,6 @@ int main(int argc, char *argv[])
flush_timing_advance();
- talloc_free(gprs_rlcmac_bts);
-
talloc_report_full(tall_pcu_ctx, stderr);
talloc_free(tall_pcu_ctx);
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index cdf808f..66a351f 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -77,7 +77,7 @@ gDEFUN(ournode_end, ournode_end_cmd, "end",
static int config_write_pcu(struct vty *vty)
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
vty_out(vty, "pcu%s", VTY_NEWLINE);
vty_out(vty, " flow-control-interval %d%s", bts->fc_interval,
@@ -122,7 +122,7 @@ DEFUN(cfg_pcu_fc_interval,
"Interval between sending subsequent Flow Control PDUs\n"
"Interval time in seconds\n")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->fc_interval = atoi(argv[0]);
@@ -135,7 +135,7 @@ DEFUN(cfg_pcu_cs,
"Set the Coding Scheme to be used, (overrides BTS config)\n"
"Initial CS used\nAlternative uplink CS")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
uint8_t cs = atoi(argv[0]);
bts->force_cs = 1;
@@ -153,7 +153,7 @@ DEFUN(cfg_pcu_no_cs,
"no cs",
NO_STR "Don't force given Coding Scheme, (use BTS config)\n")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->force_cs = 0;
@@ -169,7 +169,7 @@ DEFUN(cfg_pcu_queue_lifetime,
"queue lifetime <1-65534>",
QUEUE_STR LIFETIME_STR "Lifetime in centi-seconds")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
uint8_t csec = atoi(argv[0]);
bts->force_llc_lifetime = csec;
@@ -182,7 +182,7 @@ DEFUN(cfg_pcu_queue_lifetime_inf,
"queue lifetime infinite",
QUEUE_STR LIFETIME_STR "Infinite lifetime")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->force_llc_lifetime = 0xffff;
@@ -195,7 +195,7 @@ DEFUN(cfg_pcu_no_queue_lifetime,
NO_STR QUEUE_STR "Disable lifetime limit of LLC frame (use value given "
"by SGSN)\n")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->force_llc_lifetime = 0;
@@ -209,7 +209,7 @@ DEFUN(cfg_pcu_alloc,
"PACCH\nSingle slot is assigned only\nMultiple slots are assigned for "
"semi-duplex operation")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
switch (argv[0][0]) {
case 'a':
@@ -228,7 +228,7 @@ DEFUN(cfg_pcu_two_phase,
"two-phase-access",
"Force two phase access when MS requests single phase access\n")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->force_two_phase = 1;
@@ -240,7 +240,7 @@ DEFUN(cfg_pcu_no_two_phase,
"no two-phase-access",
NO_STR "Only use two phase access when requested my MS\n")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->force_two_phase = 0;
@@ -254,7 +254,7 @@ DEFUN(cfg_pcu_alpha,
"NOTE: Be sure to set Alpha value at System information 13 too.\n"
"Alpha in units of 0.1\n")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->alpha = atoi(argv[0]);
@@ -267,7 +267,7 @@ DEFUN(cfg_pcu_gamma,
"Gamma parameter for MS power control in units of dB (see TS 05.08)\n"
"Gamma in even unit of dBs\n")
{
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->gamma = atoi(argv[0]) / 2;
diff --git a/src/sysmo_sock.cpp b/src/sysmo_sock.cpp
index 591c105..2852c0e 100644
--- a/src/sysmo_sock.cpp
+++ b/src/sysmo_sock.cpp
@@ -81,7 +81,7 @@ int pcu_sock_send(struct msgb *msg)
static void pcu_sock_close(struct pcu_sock_state *state, int lost)
{
struct osmo_fd *bfd = &state->conn_bfd;
- struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
uint8_t trx, ts;
LOGP(DL1IF, LOGL_NOTICE, "PCU socket has %s connection\n",
diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp
index 3d58f50..3b75763 100644
--- a/tests/alloc/AllocTest.cpp
+++ b/tests/alloc/AllocTest.cpp
@@ -33,7 +33,6 @@ extern "C" {
/* globals used by the code */
void *tall_pcu_ctx;
-struct gprs_rlcmac_bts *gprs_rlcmac_bts;
int16_t spoof_mnc = 0, spoof_mcc = 0;
static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count)
@@ -47,7 +46,6 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count)
memset(&bts, 0, sizeof(bts));
bts.alloc_algorithm = alloc_algorithm_a;
- gprs_rlcmac_bts = &bts;
struct gprs_rlcmac_trx *trx = &bts.trx[0];
trx->pdch[2].enable = 1;
diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp
index 4b58a8b..ed0abbe 100644
--- a/tests/emu/pcu_emu.cpp
+++ b/tests/emu/pcu_emu.cpp
@@ -39,7 +39,6 @@ static int current_test;
/* Extern data to please the underlying code */
void *tall_pcu_ctx;
-struct gprs_rlcmac_bts *gprs_rlcmac_bts;
int16_t spoof_mnc = 0, spoof_mcc = 0;
extern void test_replay_gprs_attach(struct gprs_bssgp_pcu *pcu);
@@ -63,13 +62,9 @@ struct gprs_test all_tests[] = {
test_pdp_activation_data),
};
-struct gprs_rlcmac_bts *create_bts()
+static void init_main_bts()
{
- struct gprs_rlcmac_bts *bts;
-
- bts = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_bts);
- if (!bts)
- return NULL;
+ struct gprs_rlcmac_bts *bts = bts_main_data();
bts->fc_interval = 100;
bts->initial_cs_dl = bts->initial_cs_ul = 1;
bts->cs1 = 1;
@@ -85,8 +80,6 @@ struct gprs_rlcmac_bts *create_bts()
if (!bts->alloc_algorithm)
bts->alloc_algorithm = alloc_algorithm_b;
-
- return bts;
}
static void bvci_unblocked(struct gprs_bssgp_pcu *pcu)
@@ -124,11 +117,8 @@ int main(int argc, char **argv)
vty_init(&pcu_vty_info);
pcu_vty_init(&gprs_log_info);
- gprs_rlcmac_bts = create_bts();
- if (!gprs_rlcmac_bts)
- abort();
-
- create_and_connect_bssgp(gprs_rlcmac_bts, INADDR_LOOPBACK, 23000);
+ init_main_bts();
+ create_and_connect_bssgp(bts_main_data(), INADDR_LOOPBACK, 23000);
for (;;)
osmo_select_main(0);