aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2011-10-03 10:30:24 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2011-10-03 13:01:00 +0200
commitaf55442f848c2b3b41a122f9f0bb733feb39a1dd (patch)
treea423405f6d65cc012f815a3c4d159701207d26ad
parent1ac47658c4956e3c61b450fb4048b5dc85b35c94 (diff)
[WIP] Added profiles with different slot layouts to use at basebands
-rw-r--r--src/osmo-bts-bb/Makefile.am2
-rw-r--r--src/osmo-bts-bb/l1_if.c96
-rw-r--r--src/osmo-bts-bb/l1_if.h23
-rw-r--r--src/osmo-bts-bb/l1ctl.h2
-rw-r--r--src/osmo-bts-bb/main.c30
-rw-r--r--src/osmo-bts-bb/settings.c172
-rw-r--r--src/osmo-bts-bb/settings.h11
7 files changed, 266 insertions, 70 deletions
diff --git a/src/osmo-bts-bb/Makefile.am b/src/osmo-bts-bb/Makefile.am
index f8791365..5a707d83 100644
--- a/src/osmo-bts-bb/Makefile.am
+++ b/src/osmo-bts-bb/Makefile.am
@@ -4,5 +4,5 @@ LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS)
bin_PROGRAMS = osmobts
-osmobts_SOURCES = main.c oml.c bts_model.c l1_if.c l1ctl.c
+osmobts_SOURCES = main.c oml.c bts_model.c l1_if.c l1ctl.c settings.c
osmobts_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD)
diff --git a/src/osmo-bts-bb/l1_if.c b/src/osmo-bts-bb/l1_if.c
index 184ae628..c1149e3f 100644
--- a/src/osmo-bts-bb/l1_if.c
+++ b/src/osmo-bts-bb/l1_if.c
@@ -48,8 +48,9 @@
#include "l1ctl.h"
#include "l1_if.h"
#include "oml.h"
+#include "settings.h"
-extern int tx_only;
+extern int layout;
static struct msgb *osmo_l1if_alloc(uint8_t msg_type)
{
@@ -175,34 +176,32 @@ int l1if_data_req_cb(struct osmo_prim_hdr *oph, void *ctx)
static int l1if_reset_cnf(struct osmo_l1ctl *l1ctl, struct msgb *msg)
{
- enum baseband_role bb_role = l1ctl->bb_role;
+ int i = l1ctl->bb_role;
struct osmo_l1_if *l1if = l1ctl->l1_if;
struct gsm_bts_trx *trx = l1if->trx;
int on = 1; // FIXME: handle failure (wrong firmware)
- if (bb_role == BASEBAND_TX) {
- LOGP(DL1C, LOGL_INFO, "Reset of TX baseband complete\n");
- l1if->reset_cnf_tx = 1;
- }
- if (bb_role == BASEBAND_RX) {
- LOGP(DL1C, LOGL_INFO, "Reset of RX baseband complete\n");
- l1if->reset_cnf_rx = 1;
- }
- if (!l1if->reset_cnf_tx || (!l1if->reset_cnf_rx && !tx_only)) {
- LOGP(DL1C, LOGL_INFO, "Waiting for other baseband\n");
- return 0;
+ LOGP(DL1C, LOGL_INFO, "Reset of baseband %d complete.\n", i + 1);
+ l1if->reset_cnf[i] = 1;
+
+ for (i = 0; i < l1if->num_phones; i++) {
+ if (!l1if->reset_cnf[i]) {
+ LOGP(DL1C, LOGL_INFO, "Waiting for more basebands.\n");
+ return 0;
+ }
}
+ LOGP(DL1C, LOGL_INFO, "All basebands answered to reset.\n");
if (on) {
- int i;
+ int s;
/* signal availability */
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
oml_mo_tx_sw_act_rep(&trx->mo);
oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
- for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
- oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
+ for (s = 0; s < ARRAY_SIZE(trx->ts); s++)
+ oml_mo_state_chg(&trx->ts[s].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
} else {
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
@@ -217,29 +216,20 @@ int l1if_reset(struct gsm_bts_trx *trx)
struct msgb *msg;
struct l1ctl_reset *res;
uint8_t type = L1CTL_RES_T_FULL;
+ int i;
- msg = osmo_l1if_alloc(L1IF_RESET_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx Reset Req (%u) of TX baseband\n", type);
- res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
- res->type = type;
+ for (i = 0; i < l1if->num_phones; i++) {
+ msg = osmo_l1if_alloc(L1IF_RESET_REQ);
+ if (!msg)
+ return -1;
- l1ctl_send(&l1if->l1ctl_tx, msg);
+ LOGP(DL1C, LOGL_INFO, "Tx Reset Req (%u) of baseband %d\n",
+ type, i + 1);
+ res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
+ res->type = type;
- if (tx_only)
- return 0;
-
- msg = osmo_l1if_alloc(L1IF_RESET_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx Reset Req (%u) of RX baseband\n", type);
- res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
- res->type = type;
-
- l1ctl_send(&l1if->l1ctl_rx, msg);
+ l1ctl_send(&l1if->l1ctl[i], msg);
+ }
return 0;
}
@@ -281,6 +271,7 @@ int l1if_open(struct gsm_bts_trx *trx, const char *socket_path)
struct osmo_l1_if *l1if;
char pathname[128];
int rc;
+ int i;
osmo_signal_register_handler(SS_GLOBAL, l1if_signal_cbfn, NULL);
@@ -288,23 +279,19 @@ int l1if_open(struct gsm_bts_trx *trx, const char *socket_path)
if (!l1if)
return -ENOMEM;
l1if->trx = trx;
- l1if->l1ctl_tx.bb_role = BASEBAND_TX;
- l1if->l1ctl_tx.l1_if = l1if;
- sprintf(pathname, "%s.tx", socket_path);
- LOGP(DL1C, LOGL_INFO, "Open connection to TX baseband.\n");
- rc = l1socket_open(&l1if->l1ctl_tx, pathname);
- if (rc) {
- talloc_free(l1if);
- return rc;
- }
- if (!tx_only) {
- l1if->l1ctl_rx.bb_role = BASEBAND_RX;
- l1if->l1ctl_rx.l1_if = l1if;
- sprintf(pathname, "%s.rx", socket_path);
- LOGP(DL1C, LOGL_INFO, "Open connection to RX baseband.\n");
- rc = l1socket_open(&l1if->l1ctl_rx, pathname);
+ l1if->num_phones = set_num_phones(layout);
+ for (i = 0; i < l1if->num_phones; i++) {
+ l1if->l1ctl[i].bb_role = i;
+ l1if->l1ctl[i].l1_if = l1if;
+ l1if->d_mask[i] = set_get_tx_mask(layout, i);
+ l1if->u_mask[i] = set_get_rx_mask(layout, i);
+ sprintf(pathname, "%s.%d", socket_path, i + 1);
+ LOGP(DL1C, LOGL_INFO, "Open connection to baseband %d.\n",
+ i + 1);
+ rc = l1socket_open(&l1if->l1ctl[i], pathname);
if (rc) {
- l1socket_close(&l1if->l1ctl_tx);
+ while (i--)
+ l1socket_close(&l1if->l1ctl[i]);
talloc_free(l1if);
return rc;
}
@@ -318,9 +305,10 @@ int l1if_open(struct gsm_bts_trx *trx, const char *socket_path)
int l1if_close(struct gsm_bts_trx *trx)
{
struct osmo_l1_if *l1if = trx_l1_if(trx);
+ int i;
- l1socket_close(&l1if->l1ctl_tx);
- l1socket_close(&l1if->l1ctl_rx);
+ for (i = 0; i < l1if->num_phones; i++)
+ l1socket_close(&l1if->l1ctl[i]);
talloc_free(l1if);
osmo_signal_unregister_handler(SS_GLOBAL, l1if_signal_cbfn, NULL);
return 0;
diff --git a/src/osmo-bts-bb/l1_if.h b/src/osmo-bts-bb/l1_if.h
index bdd33bcc..e2d42958 100644
--- a/src/osmo-bts-bb/l1_if.h
+++ b/src/osmo-bts-bb/l1_if.h
@@ -2,13 +2,20 @@
#define _BB_L1_IF_H
enum l1if_prim {
- L1IF_RESET_REQ,
+ L1IF_NULL = 0,
+ L1IF_RESET_REQ, /* reset baseband */
L1IF_RESET_IND,
L1IF_RESET_CNF,
- L1IF_SETUP_REQ,
+ L1IF_SETUP_REQ, /* e.g.: set sync parameters */
L1IF_SETUP_CNF,
- L1IF_BCCH_REQ,
- L1IF_RACH_IND,
+ L1IF_BCCH_REQ, /* set system information messages */
+ L1IF_RACH_IND, /* receive channel request */
+ L1IF_DATA_REQ, /* exchange data */
+ L1IF_DATA_IND,
+ L1IF_DATA_CNF,
+ L1IF_DATA_FLUSH, /* flush pending data */
+ L1IF_TRAFFIC_REQ, /* exchange traffic data */
+ L1IF_TRAFFIC_IND,
};
struct l1if_hdr {
@@ -18,11 +25,15 @@ struct l1if_hdr {
struct osmo_l1_if {
struct gsm_bts_trx *trx;
- struct osmo_l1ctl l1ctl_tx, l1ctl_rx;
- int reset_cnf_tx, reset_cnf_rx;
+ int num_phones;
+ struct osmo_l1ctl l1ctl[8];
+ int reset_cnf[8];
+ uint8_t u_mask[8];
+ uint8_t d_mask[8];
};
int l1if_setup(struct gsm_bts_trx *trx);
+int l1if_data_req_cb(struct osmo_prim_hdr *oph, void *ctx);
int l1if_reset(struct gsm_bts_trx *trx);
int l1if_recv(struct osmo_l1ctl *l1ctl, struct msgb *msg);
int l1if_open(struct gsm_bts_trx *trx, const char *socket_path);
diff --git a/src/osmo-bts-bb/l1ctl.h b/src/osmo-bts-bb/l1ctl.h
index b1402fb0..46499fdd 100644
--- a/src/osmo-bts-bb/l1ctl.h
+++ b/src/osmo-bts-bb/l1ctl.h
@@ -10,7 +10,7 @@ enum baseband_role {
struct osmo_l1ctl {
- enum baseband_role bb_role;
+ int bb_role;
struct osmo_l1_if *l1_if;
struct osmo_wqueue l2_wq;
};
diff --git a/src/osmo-bts-bb/main.c b/src/osmo-bts-bb/main.c
index 2b755837..72477ff1 100644
--- a/src/osmo-bts-bb/main.c
+++ b/src/osmo-bts-bb/main.c
@@ -19,6 +19,7 @@
*
*/
+#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
@@ -34,6 +35,7 @@
#include "l1ctl.h"
#include "l1_if.h"
+#include "settings.h"
#include <net/if.h>
@@ -53,7 +55,7 @@ int level_set = 0;
uint16_t ref_arfcn = 0;
int ref_set = 0;
static char *layer2_socket_path = "/tmp/osmocom_l2";
-int tx_only = 0;
+int layout = 0;
static int daemonize = 0;
void *l23_ctx = NULL;
static struct gsm_bts *bts;
@@ -115,7 +117,7 @@ static void print_usage(const char *app)
printf("Usage: %s -r <arfcn> [option]\n", app);
printf(" -h --help this text\n");
printf(" -s --socket Path to the unix domain socket (default /tmp/osmocom_l2)\n");
- printf(" -t --tx-only Use only one baseband to transmit BCCH only\n");
+ printf(" -l --layout <layout> Specify slot layout. Use 'help' to get a list.\n");
printf(" -r --ref-arfcn Set channel number of reference BTS for clocking\n");
printf(" -d --debug Change debug flags. (default %s)\n", debugs);
printf(" -s --disable-color Don't use colors in stderr log output\n");
@@ -139,7 +141,7 @@ static void handle_options(int argc, char **argv)
static struct option long_options[] = {
{ "help", 0, 0, 'h' },
{ "socket", 1, 0, 's' },
- { "tx-only", 0, 0, 't' },
+ { "layout", 0, 0, 'l' },
{ "ref-arfcn", 1, 0, 'r' },
{ "debug", 1, 0, 'd' },
{ "disable-color", 0, 0, 'C' },
@@ -150,7 +152,7 @@ static void handle_options(int argc, char **argv)
{0, 0, 0, 0},
};
- c = getopt_long(argc, argv, "hs:tr:d:CTe:i:D",
+ c = getopt_long(argc, argv, "hs:l:r:d:CTe:i:D",
long_options, &option_index);
if (c == -1)
break;
@@ -162,8 +164,18 @@ static void handle_options(int argc, char **argv)
case 's':
layer2_socket_path = talloc_strdup(l23_ctx, optarg);
break;
- case 't':
- tx_only = 1;
+ case 'l':
+ if (!strcmp(optarg, "help")) {
+ set_show_layouts();
+ exit(0);
+ }
+ layout = set_layout_by_name(optarg);
+ if (layout < 0) {
+ fprintf(stderr, "Given layout '%s' not found. "
+ "Use 'help' to list all layouts\n",
+ optarg);
+ exit(-EINVAL);
+ }
break;
case 'r':
ref_arfcn = atoi(optarg);
@@ -228,8 +240,6 @@ int main(int argc, char **argv)
bts_logo();
- get_mac();
-
tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context");
tall_msgb_ctx = talloc_named_const(tall_bts_ctx, 1, "msgb");
msgb_set_talloc_ctx(tall_msgb_ctx);
@@ -249,6 +259,8 @@ int main(int argc, char **argv)
handle_options(argc, argv);
+ set_show_layout(layout);
+
if (!ref_set) {
fprintf(stderr, "Error: ARFCN for reference clock not specified. Use '-h' for help.\n");
exit(1);
@@ -260,6 +272,8 @@ int main(int argc, char **argv)
if (!level_set)
log_set_log_level(osmo_stderr_target, LOGL_INFO);
+ get_mac();
+
if (bts_init(bts) < 0) {
fprintf(stderr, "unable to to open bts\n");
exit(1);
diff --git a/src/osmo-bts-bb/settings.c b/src/osmo-bts-bb/settings.c
new file mode 100644
index 00000000..b298f785
--- /dev/null
+++ b/src/osmo-bts-bb/settings.c
@@ -0,0 +1,172 @@
+/* Cell layout and configuration */
+
+/* (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * 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 <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include "settings.h"
+
+struct cell_layout {
+ char *name; /* name of layout */
+ uint8_t slot_mask; /* slots to be supported for BTS */
+ char *desc; /* description */
+ uint8_t dl[8]; /* which baseband transmits on which slot */
+ uint8_t ul[8]; /* which baseband receives on which slot */
+};
+
+static struct cell_layout cell_layouts[] = {
+ { "bcch", 0x01, "Send BCCH only, TX on slots 0..5.",
+ {1, 1, 1, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0}},
+ { "4slots", 0xc3, "Use two phones, TX on all slots, RX on 4 slots",
+ {1, 1, 2, 2, 2, 2, 1, 1},
+ {1, 1, 0, 0, 2, 2, 0, 0}},
+ { "6slots", 0x3f, "Use two phones, TX on 6 slots, RX on 6 slots",
+ {1, 1, 2, 2, 2, 2, 0, 0},
+ {1, 1, 1, 1, 2, 2, 0, 0}},
+ { "8slots", 0xff, "Use three phones, TX and RX on all slots",
+ {1, 1, 3, 3, 2, 2, 3, 3},
+ {1, 1, 1, 1, 2, 2, 2, 2}},
+ { NULL, 0x00, NULL,
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0}},
+};
+
+int set_show_layout(int i)
+{
+ int s, p;
+ uint8_t d_mask, u_mask;
+
+ printf("Layout name: '%s'\n", cell_layouts[i].name);
+ printf("Description: %s\n", cell_layouts[i].desc);
+ printf("Slots used for BTS:");
+ for (s = 0; s < 8; s++) {
+ if ((cell_layouts[i].slot_mask & (1 << s)))
+ printf(" %d", s);
+ }
+ printf("\n");
+ for (p = 1; ; p++) {
+ d_mask = 0;
+ u_mask = 0;
+ for (s = 0; s < 8; s++) {
+ if (cell_layouts[i].dl[s] == p)
+ d_mask |= (1 << s);
+ if (cell_layouts[i].ul[s] == p)
+ u_mask |= (1 << s);
+ }
+ if (d_mask == 0 && u_mask == 0)
+ break;
+ if (d_mask) {
+ printf("Phone %d provides TX slots:", p);
+ for (s = 0; s < 8; s++) {
+ if ((d_mask & (1 << s)))
+ printf(" %d", s);
+ }
+ printf("\n");
+ }
+ if (u_mask) {
+ printf("Phone %d provides RX slots:", p);
+ for (s = 0; s < 8; s++) {
+ if ((u_mask & (1 << s)))
+ printf(" %d", s);
+ }
+ printf("\n");
+ }
+ }
+
+ return p - 1; /* number of phones */
+}
+
+int set_show_layouts(void)
+{
+ int i;
+
+ printf("List of all layouts:\n");
+ for (i = 0; cell_layouts[i].name; i++) {
+ printf("\n");
+ set_show_layout(i);
+ }
+
+ return 0;
+}
+
+int set_layout_by_name(const char *name)
+{
+ int i;
+
+ for (i = 0; cell_layouts[i].name; i++) {
+ if (!strcmp(cell_layouts[i].name, name))
+ break;
+ }
+
+ if (!cell_layouts[i].name)
+ return -1;
+
+ return i;
+}
+
+int set_num_phones(int i)
+{
+ int s, p;
+ uint8_t d_mask, u_mask;
+
+ for (p = 1; ; p++) {
+ d_mask = 0;
+ u_mask = 0;
+ for (s = 0; s < 8; s++) {
+ if (cell_layouts[i].dl[s] == p)
+ d_mask |= (1 << s);
+ if (cell_layouts[i].ul[s] == p)
+ u_mask |= (1 << s);
+ }
+ if (d_mask == 0 && u_mask == 0)
+ break;
+ }
+
+ return p - 1; /* number of phones */
+}
+
+uint8_t set_get_tx_mask(int i, int p)
+{
+ uint8_t mask = 0;
+ int s;
+
+ for (s = 0; s < 8; s++) {
+ if (cell_layouts[i].dl[s] == p)
+ mask |= (1 << s);
+ }
+
+ return mask;
+}
+
+uint8_t set_get_rx_mask(int i, int p)
+{
+ uint8_t mask = 0;
+ int s;
+
+ for (s = 0; s < 8; s++) {
+ if (cell_layouts[i].ul[s] == p)
+ mask |= (1 << s);
+ }
+
+ return mask;
+}
+
diff --git a/src/osmo-bts-bb/settings.h b/src/osmo-bts-bb/settings.h
new file mode 100644
index 00000000..bfb6a465
--- /dev/null
+++ b/src/osmo-bts-bb/settings.h
@@ -0,0 +1,11 @@
+#ifndef _SETTINGS_H
+#define _SETTINGS_H
+
+int set_show_layout(int i);
+int set_show_layouts(void);
+int set_layout_by_name(const char *name);
+int set_num_phones(int i);
+uint8_t set_get_tx_mask(int i, int p);
+uint8_t set_get_rx_mask(int i, int p);
+
+#endif /* _SETTINGS_H */