diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2011-10-03 10:30:24 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2011-10-03 13:01:00 +0200 |
commit | af55442f848c2b3b41a122f9f0bb733feb39a1dd (patch) | |
tree | a423405f6d65cc012f815a3c4d159701207d26ad | |
parent | 1ac47658c4956e3c61b450fb4048b5dc85b35c94 (diff) |
[WIP] Added profiles with different slot layouts to use at basebands
-rw-r--r-- | src/osmo-bts-bb/Makefile.am | 2 | ||||
-rw-r--r-- | src/osmo-bts-bb/l1_if.c | 96 | ||||
-rw-r--r-- | src/osmo-bts-bb/l1_if.h | 23 | ||||
-rw-r--r-- | src/osmo-bts-bb/l1ctl.h | 2 | ||||
-rw-r--r-- | src/osmo-bts-bb/main.c | 30 | ||||
-rw-r--r-- | src/osmo-bts-bb/settings.c | 172 | ||||
-rw-r--r-- | src/osmo-bts-bb/settings.h | 11 |
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 */ |