aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2009-08-08 16:12:58 +0200
committerHarald Welte <laforge@netfilter.org>2009-08-08 16:12:58 +0200
commit42581829ec2a79ef82c813b8212da76f514aa4f4 (patch)
tree0fb73c2964b6a6a97e998cd361389fa8887c1eca /openbsc
parent3c5cb256c2937d3671fda0daeb2c324105b0627c (diff)
the actual config file code (not just config files)
this was missing from commit a08a9acdb6bff0ee4fdf0f58b78b6525017a1f9f
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/e1_input.h9
-rw-r--r--openbsc/include/openbsc/gsm_data.h7
-rw-r--r--openbsc/include/openbsc/talloc.h2
-rw-r--r--openbsc/include/vty/command.h16
-rw-r--r--openbsc/src/bsc_hack.c207
-rw-r--r--openbsc/src/e1_config.c103
-rw-r--r--openbsc/src/e1_input.c48
-rw-r--r--openbsc/src/gsm_data.c11
-rw-r--r--openbsc/src/input/ipaccess.c4
-rw-r--r--openbsc/src/input/misdn.c40
-rw-r--r--openbsc/src/vty/command.c104
-rw-r--r--openbsc/src/vty/vty.c32
-rw-r--r--openbsc/src/vty_interface.c124
13 files changed, 381 insertions, 326 deletions
diff --git a/openbsc/include/openbsc/e1_input.h b/openbsc/include/openbsc/e1_input.h
index 132672364..1e8da56fe 100644
--- a/openbsc/include/openbsc/e1_input.h
+++ b/openbsc/include/openbsc/e1_input.h
@@ -113,6 +113,9 @@ int e1inp_driver_register(struct e1inp_driver *drv);
/* register a line with the E1 core */
int e1inp_line_register(struct e1inp_line *line);
+/* ensure a certain line exists, return pointer to it */
+struct e1inp_line *e1inp_line_get_create(u_int8_t e1_nr);
+
/* find a sign_link for given TEI and SAPI in a TS */
struct e1inp_sign_link *
e1inp_lookup_sign_link(struct e1inp_ts *ts, u_int8_t tei,
@@ -148,8 +151,12 @@ void e1_set_pcap_fd(int fd);
/* called by TRAU muxer to obtain the destination mux entity */
struct subch_mux *e1inp_get_mux(u_int8_t e1_nr, u_int8_t ts_nr);
+
/* e1_config.c */
-int e1_config(struct gsm_bts *bts, int cardnr, int release_l2);
+int e1_reconfig_ts(struct gsm_bts_trx_ts *ts);
+int e1_reconfig_trx(struct gsm_bts_trx *trx);
+int e1_reconfig_bts(struct gsm_bts *bts);
+
int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin);
int ipaccess_setup(struct gsm_network *gsmnet);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 663c8698b..8af07816f 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -200,7 +200,10 @@ struct gsm_bts_trx {
/* number of this TRX in the BTS */
u_int8_t nr;
/* how do we talk RSL with this TRX? */
+ struct gsm_e1_subslot rsl_e1_link;
+ u_int8_t rsl_tei;
struct e1inp_sign_link *rsl_link;
+
struct gsm_nm_state nm_state;
struct tlv_parsed nm_attr;
struct {
@@ -293,6 +296,8 @@ struct gsm_bts {
enum gsm_bts_type type;
enum gsm_band band;
/* how do we talk OML with this TRX? */
+ struct gsm_e1_subslot oml_e1_link;
+ u_int8_t oml_tei;
struct e1inp_sign_link *oml_link;
/* Abis network management O&M handle */
@@ -404,7 +409,7 @@ struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
struct gsm_bts *start_bts);
char *gsm_band_name(enum gsm_band band);
-enum gsm_band gsm_band_parse(int mhz);
+enum gsm_band gsm_band_parse(const char *mhz);
extern void *tall_bsc_ctx;
diff --git a/openbsc/include/openbsc/talloc.h b/openbsc/include/openbsc/talloc.h
index a4b33c3ed..f7f7643b8 100644
--- a/openbsc/include/openbsc/talloc.h
+++ b/openbsc/include/openbsc/talloc.h
@@ -29,6 +29,8 @@
#include <stdio.h>
#include <stdarg.h>
+#define HAVE_VA_COPY
+
/* this is only needed for compatibility with the old talloc */
typedef void TALLOC_CTX;
diff --git a/openbsc/include/vty/command.h b/openbsc/include/vty/command.h
index 1be05aa8e..21fb6a1af 100644
--- a/openbsc/include/vty/command.h
+++ b/openbsc/include/vty/command.h
@@ -61,12 +61,6 @@ struct host {
/* There are some command levels which called from command node. */
enum node_type {
- GSMNET_NODE,
- BTS_NODE,
- TRX_NODE,
- TS_NODE,
- SUBSCR_NODE,
-
AUTH_NODE, /* Authentication mode of vty interface. */
VIEW_NODE, /* View node. Default mode of vty interface. */
AUTH_ENABLE_NODE, /* Authentication mode for change enable. */
@@ -74,6 +68,7 @@ enum node_type {
CONFIG_NODE, /* Config node. Default mode of config file. */
SERVICE_NODE, /* Service node. */
DEBUG_NODE, /* Debug node. */
+#if 0
AAA_NODE, /* AAA node. */
KEYCHAIN_NODE, /* Key-chain node. */
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
@@ -103,7 +98,14 @@ enum node_type {
SMUX_NODE, /* SNMP configuration node. */
DUMP_NODE, /* Packet dump node. */
FORWARDING_NODE, /* IP forwarding node. */
- VTY_NODE /* Vty node. */
+#endif
+ VTY_NODE, /* Vty node. */
+
+ GSMNET_NODE,
+ BTS_NODE,
+ TRX_NODE,
+ TS_NODE,
+ SUBSCR_NODE,
};
/* Node which has some commands and prompt string and configuration
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index 9e0a26096..0759f2626 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -55,27 +55,12 @@ static struct gsm_network *gsmnet;
/* MCC and MNC for the Location Area Identifier */
static int MCC = 1;
static int MNC = 1;
-static int LAC = 1;
-static int TSC = HARDCODED_TSC;
-static int BSIC = HARDCODED_BSIC;
-static int ARFCN = HARDCODED_ARFCN;
static int cardnr = 0;
static int release_l2 = 0;
-static int bs11_has_trx1 = 0;
-static int bs11_has_bts1 = 0;
static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
-static enum gsm_band BAND = GSM_BAND_900;
static const char *database_name = "hlr.sqlite3";
extern int ipacc_rtp_direct;
-struct nano_bts_id {
- struct llist_head entry;
- int site_id;
- int bts_id;
-};
-
-static LLIST_HEAD(nanobts_ids);
-
/* The following definitions are for OM and NM packets that we cannot yet
* generate by code but we just pass on */
@@ -986,7 +971,8 @@ static void bootstrap_rsl(struct gsm_bts_trx *trx)
{
fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
"using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
- trx->bts->nr, trx->nr, MCC, MNC, BSIC, TSC);
+ trx->bts->nr, trx->nr, gsmnet->country_code,
+ gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
set_system_infos(trx);
}
@@ -1016,9 +1002,25 @@ void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
static int bootstrap_bts(struct gsm_bts *bts)
{
- bts->band = BAND;
- bts->location_area_code = LAC;
- bts->c0->arfcn = ARFCN;
+ switch (bts->type) {
+ case GSM_BTS_TYPE_NANOBTS_1800:
+ if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
+ fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
+ return -EINVAL;
+ }
+ break;
+ case GSM_BTS_TYPE_BS11:
+ case GSM_BTS_TYPE_NANOBTS_900:
+ /* Assume we have a P-GSM900 here */
+ if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
+ fprintf(stderr, "GSM900 channel must be between 1-124.\n");
+ return -EINVAL;
+ }
+ break;
+ case GSM_BTS_TYPE_UNKNOWN:
+ fprintf(stderr, "Unknown BTS. Please specify\n");
+ return -EINVAL;
+ }
/* Control Channel Description */
memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
@@ -1031,66 +1033,21 @@ static int bootstrap_bts(struct gsm_bts *bts)
paging_init(bts);
- if (bts->type == GSM_BTS_TYPE_BS11) {
- struct gsm_bts_trx *trx = bts->c0;
- set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
- set_ts_e1link(&trx->ts[1], 0, 2, 1);
- set_ts_e1link(&trx->ts[2], 0, 2, 2);
- set_ts_e1link(&trx->ts[3], 0, 2, 3);
- set_ts_e1link(&trx->ts[4], 0, 3, 0);
- set_ts_e1link(&trx->ts[5], 0, 3, 1);
- set_ts_e1link(&trx->ts[6], 0, 3, 2);
- set_ts_e1link(&trx->ts[7], 0, 3, 3);
-
- /* TRX 1 */
- trx = gsm_bts_trx_num(bts, 1);
- if (trx) {
- trx = gsm_bts_trx_num(bts, 1);
- set_ts_e1link(&trx->ts[0], 0, 4, 0);
- set_ts_e1link(&trx->ts[1], 0, 4, 1);
- set_ts_e1link(&trx->ts[2], 0, 4, 2);
- set_ts_e1link(&trx->ts[3], 0, 4, 3);
- set_ts_e1link(&trx->ts[4], 0, 5, 0);
- set_ts_e1link(&trx->ts[5], 0, 5, 1);
- set_ts_e1link(&trx->ts[6], 0, 5, 2);
- set_ts_e1link(&trx->ts[7], 0, 5, 3);
- }
- }
-
return 0;
}
static int bootstrap_network(void)
{
+ struct gsm_bts *bts;
int rc;
- switch(BTS_TYPE) {
- case GSM_BTS_TYPE_NANOBTS_1800:
- if (ARFCN < 512 || ARFCN > 885) {
- fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
- return -EINVAL;
- }
- break;
- case GSM_BTS_TYPE_BS11:
- case GSM_BTS_TYPE_NANOBTS_900:
- /* Assume we have a P-GSM900 here */
- if (ARFCN < 1 || ARFCN > 124) {
- fprintf(stderr, "GSM900 channel must be between 1-124.\n");
- return -EINVAL;
- }
- break;
- case GSM_BTS_TYPE_UNKNOWN:
- fprintf(stderr, "Unknown BTS. Please use the --bts-type switch\n");
- return -EINVAL;
- }
-
/* initialize our data structures */
gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
if (!gsmnet)
return -ENOMEM;
- gsmnet->name_long = "OpenBSC";
- gsmnet->name_short = "OpenBSC";
+ gsmnet->name_long = talloc_strdup(gsmnet, "OpenBSC");
+ gsmnet->name_short = talloc_strdup(gsmnet, "OpenBSC");
if (db_init(database_name)) {
printf("DB: Failed to init database. Please check the option settings.\n");
@@ -1105,56 +1062,24 @@ static int bootstrap_network(void)
printf("DB: Database prepared.\n");
telnet_init(gsmnet, 4242);
+ rc = vty_read_config_file("openbsc.cfg");
+ if (rc < 0)
+ return rc;
register_signal_handler(SS_NM, nm_sig_cb, NULL);
- /* E1 mISDN input setup */
- if (BTS_TYPE == GSM_BTS_TYPE_BS11) {
- struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
-
- if (bs11_has_trx1) {
- struct gsm_bts_trx *trx1;
- trx1 = gsm_bts_trx_alloc(bts);
- trx1->arfcn = ARFCN + 2;
- }
+ llist_for_each_entry(bts, &gsmnet->bts_list, list) {
bootstrap_bts(bts);
- rc = e1_config(bts, cardnr, release_l2);
- if (rc < 0) {
- fprintf(stderr, "Error during E1 config of BTS 0\n");
- return rc;
- }
-
- if (bs11_has_bts1) {
- bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
- if (bs11_has_trx1) {
- struct gsm_bts_trx *trx1;
- trx1 = gsm_bts_trx_alloc(bts);
- trx1->arfcn = ARFCN + 2;
- }
- bootstrap_bts(bts);
- rc = e1_config(bts, cardnr+1, release_l2);
- if (rc < 0)
- fprintf(stderr, "Error during E1 config of BTS 1\n");
- }
- return rc;
- } else {
- struct nano_bts_id *bts_id;
- struct gsm_bts *bts;
-
- if (llist_empty(&nanobts_ids)) {
- fprintf(stderr, "You need to specify -i DEVICE_1 -i DEVICE_2 for nanoBTS.\n");
- return -EINVAL;
- }
-
- llist_for_each_entry(bts_id, &nanobts_ids, entry) {
- bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
- bootstrap_bts(bts);
- bts->ip_access.site_id = bts_id->site_id;
- bts->ip_access.bts_id = 0;
- }
+ if (is_ipaccess_bts(bts))
+ rc = ipaccess_setup(bts);
+ else
+ rc = e1_reconfig_bts(bts);
- return ipaccess_setup(gsmnet);
+ if (rc < 0)
+ exit (1);
}
+
+ return 0;
}
static void create_pcap_file(char *file)
@@ -1178,22 +1103,15 @@ static void print_usage()
static void print_help()
{
printf(" Some useful help...\n");
+ printf(" -h --help this text\n");
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
printf(" -s --disable-color\n");
- printf(" -n --network-code number(MNC) \n");
- printf(" -c --country-code number (MCC) \n");
- printf(" -L --location-area-code number (LAC) \n");
- printf(" -f --arfcn number The frequency ARFCN\n");
printf(" -l --database db-name The database to use\n");
printf(" -a --authorize-everyone Allow everyone into the network.\n");
printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
printf(" -p --pcap file The filename of the pcap file\n");
- printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
- printf(" -i --bts-id=NUMBER The known nanoBTS device numbers. Can be specified multiple times.\n");
printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
- printf(" -2 --second-bs11 Configure + Use a second BS-11\n");
- printf(" -h --help this text\n");
}
static void handle_options(int argc, char** argv)
@@ -1204,29 +1122,18 @@ static void handle_options(int argc, char** argv)
{"help", 0, 0, 'h'},
{"debug", 1, 0, 'd'},
{"disable-color", 0, 0, 's'},
- {"network-code", 1, 0, 'n'},
- {"country-code", 1, 0, 'c'},
- {"location-area-code", 1, 0, 'L'},
{"database", 1, 0, 'l'},
{"authorize-everyone", 0, 0, 'a'},
{"reject-cause", 1, 0, 'r'},
{"pcap", 1, 0, 'p'},
- {"arfcn", 1, 0, 'f'},
- {"bts-type", 1, 0, 't'},
{"cardnr", 1, 0, 'C'},
{"release-l2", 0, 0, 'R'},
{"timestamp", 0, 0, 'T'},
- {"band", 0, 0, 'b'},
- {"bts-id", 1, 0, 'i'},
- {"tsc", 1, 0, 'S'},
- {"bsic", 1, 0, 'B'},
{"rtp-proxy", 0, 0, 'P'},
- {"trx1", 0, 0, '1'},
- {"second-bs11", 0, 0, '2'},
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:S:B:P12",
+ c = getopt_long(argc, argv, "hd:sl:ar:p:C:RTP",
long_options, &option_index);
if (c == -1)
break;
@@ -1242,18 +1149,6 @@ static void handle_options(int argc, char** argv)
case 'd':
debug_parse_category_mask(optarg);
break;
- case 'n':
- MNC = atoi(optarg);
- break;
- case 'c':
- MCC = atoi(optarg);
- break;
- case 'L':
- LAC = atoi(optarg);
- break;
- case 'f':
- ARFCN = atoi(optarg);
- break;
case 'l':
database_name = strdup(optarg);
break;
@@ -1278,35 +1173,9 @@ static void handle_options(int argc, char** argv)
case 'T':
debug_timestamp(1);
break;
- case 'b':
- BAND = gsm_band_parse(atoi(optarg));
- break;
- case 'i': {
- struct nano_bts_id *bts_id = talloc_zero(tall_bsc_ctx, struct nano_bts_id);
- if (!bts_id) {
- fprintf(stderr, "Failed to allocate bts id\n");
- exit(-1);
- }
-
- bts_id->site_id = atoi(optarg);
- llist_add(&bts_id->entry, &nanobts_ids);
- break;
- case 'S':
- TSC = atoi(optarg);
- break;
- case 'B':
- BSIC = atoi(optarg);
- break;
case 'P':
ipacc_rtp_direct = 0;
break;
- case '1':
- bs11_has_trx1 = 1;
- break;
- case '2':
- bs11_has_bts1 = 1;
- break;
- }
default:
/* ignore */
break;
diff --git a/openbsc/src/e1_config.c b/openbsc/src/e1_config.c
index 898780374..e7431327b 100644
--- a/openbsc/src/e1_config.c
+++ b/openbsc/src/e1_config.c
@@ -14,10 +14,106 @@
#define SAPI_OML 62
#define SAPI_RSL 0 /* 63 ? */
-#define TEI_L2ML 127
-#define TEI_OML 25
-#define TEI_RSL 1
+/* The e1_reconfig_*() functions below tale the configuration present in the
+ * bts/trx/ts data structures and ensure the E1 configuration reflects the
+ * timeslot/subslot/TEI configuration */
+int e1_reconfig_ts(struct gsm_bts_trx_ts *ts)
+{
+ struct gsm_e1_subslot *e1_link = &ts->e1_link;
+ struct e1inp_line *line;
+ struct e1inp_ts *e1_ts;
+
+ printf("e1_reconfig_ts(%u,%u,%u)\n", ts->trx->bts->nr, ts->trx->nr, ts->nr);
+
+ if (!e1_link->e1_ts)
+ return 0;
+
+ line = e1inp_line_get_create(e1_link->e1_nr);
+ if (!line)
+ return -ENOMEM;
+
+ switch (ts->pchan) {
+ case GSM_PCHAN_TCH_F:
+ case GSM_PCHAN_TCH_H:
+ e1_ts = &line->ts[e1_link->e1_ts-1];
+ e1inp_ts_config(e1_ts, line, E1INP_TS_TYPE_TRAU);
+ subch_demux_activate(&e1_ts->trau.demux, e1_link->e1_ts_ss);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int e1_reconfig_trx(struct gsm_bts_trx *trx)
+{
+ struct gsm_e1_subslot *e1_link = &trx->rsl_e1_link;
+ struct e1inp_ts *sign_ts;
+ struct e1inp_line *line;
+ struct e1inp_sign_link *rsl_link;
+ int i;
+
+ if (!e1_link->e1_ts)
+ return -EINVAL;
+
+ /* RSL Link */
+ line = e1inp_line_get_create(e1_link->e1_nr);
+ if (!line)
+ return -ENOMEM;
+ sign_ts = &line->ts[e1_link->e1_ts-1];
+ e1inp_ts_config(sign_ts, line, E1INP_TS_TYPE_SIGN);
+ rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
+ trx, trx->rsl_tei, SAPI_RSL);
+ if (!rsl_link)
+ return -ENOMEM;
+ if (trx->rsl_link)
+ e1inp_sign_link_destroy(trx->rsl_link);
+ trx->rsl_link = rsl_link;
+
+ for (i = 0; i < TRX_NR_TS; i++)
+ e1_reconfig_ts(&trx->ts[i]);
+
+ return 0;
+}
+
+int e1_reconfig_bts(struct gsm_bts *bts)
+{
+ struct gsm_e1_subslot *e1_link = &bts->oml_e1_link;
+ struct e1inp_ts *sign_ts;
+ struct e1inp_line *line;
+ struct e1inp_sign_link *oml_link;
+ struct gsm_bts_trx *trx;
+ int rc;
+
+ printf("e1_reconfig_bts(%u)\n", bts->nr);
+
+ if (!e1_link->e1_ts)
+ return -EINVAL;
+
+ /* OML link */
+ line = e1inp_line_get_create(e1_link->e1_nr);
+ if (!line)
+ return -ENOMEM;
+ sign_ts = &line->ts[e1_link->e1_ts-1];
+ e1inp_ts_config(sign_ts, line, E1INP_TS_TYPE_SIGN);
+ oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML,
+ bts->c0, bts->oml_tei, SAPI_OML);
+ if (!oml_link)
+ return -ENOMEM;
+ if (bts->oml_link)
+ e1inp_sign_link_destroy(bts->oml_link);
+ bts->oml_link = oml_link;
+
+ llist_for_each_entry(trx, &bts->trx_list, list)
+ e1_reconfig_trx(trx);
+
+ /* notify E1 input something has changed */
+ return e1inp_line_update(line);
+}
+
+#if 0
/* do some compiled-in configuration for our BTS/E1 setup */
int e1_config(struct gsm_bts *bts, int cardnr, int release_l2)
{
@@ -102,6 +198,7 @@ int e1_config(struct gsm_bts *bts, int cardnr, int release_l2)
return mi_setup(cardnr, line, release_l2);
}
+#endif
/* configure pseudo E1 line in ip.access style and connect to BTS */
int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin)
diff --git a/openbsc/src/e1_input.c b/openbsc/src/e1_input.c
index 7531755c2..4bc15e5f7 100644
--- a/openbsc/src/e1_input.c
+++ b/openbsc/src/e1_input.c
@@ -289,6 +289,9 @@ int _abis_nm_sendmsg(struct msgb *msg)
int e1inp_ts_config(struct e1inp_ts *ts, struct e1inp_line *line,
enum e1inp_ts_type type)
{
+ if (ts->type == type && ts->line && line)
+ return 0;
+
ts->type = type;
ts->line = line;
@@ -322,6 +325,29 @@ static struct e1inp_line *e1inp_line_get(u_int8_t e1_nr)
return NULL;
}
+struct e1inp_line *e1inp_line_get_create(u_int8_t e1_nr)
+{
+ struct e1inp_line *line;
+ int i;
+
+ line = e1inp_line_get(e1_nr);
+ if (line)
+ return line;
+
+ line = talloc_zero(tall_bsc_ctx, struct e1inp_line);
+ if (!line)
+ return NULL;
+
+ line->num = e1_nr;
+ for (i = 0; i < NUM_E1_TS; i++) {
+ line->ts[i].num = i+1;
+ line->ts[i].line = line;
+ }
+ llist_add_tail(&line->list, &e1inp_line_list);
+
+ return line;
+}
+
static struct e1inp_ts *e1inp_ts_get(u_int8_t e1_nr, u_int8_t ts_nr)
{
struct e1inp_line *e1i_line;
@@ -386,6 +412,12 @@ e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
return link;
}
+void e1inp_sign_link_destroy(struct e1inp_sign_link *link)
+{
+ llist_del(&link->list);
+ talloc_free(link);
+}
+
/* the E1 driver tells us he has received something on a TS */
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
u_int8_t tei, u_int8_t sapi)
@@ -399,7 +431,7 @@ int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
write_pcap_packet(PCAP_INPUT, sapi, tei, msg);
link = e1inp_lookup_sign_link(ts, tei, sapi);
if (!link) {
- fprintf(stderr, "didn't find singalling link for "
+ fprintf(stderr, "didn't find signalling link for "
"tei %d, sapi %d\n", tei, sapi);
return -EINVAL;
}
@@ -487,19 +519,9 @@ int e1inp_driver_register(struct e1inp_driver *drv)
return 0;
}
-/* register a line with the E1 core */
-int e1inp_line_register(struct e1inp_line *line)
+int e1inp_line_update(struct e1inp_line *line)
{
- int i;
-
- for (i = 0; i < NUM_E1_TS; i++) {
- line->ts[i].num = i+1;
- line->ts[i].line = line;
- }
-
- llist_add_tail(&line->list, &e1inp_line_list);
-
- return 0;
+ return mi_e1_line_update(line);
}
static __attribute__((constructor)) void on_dso_load_e1_inp(void)
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index 370c41097..edf1b3d05 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include <ctype.h>
#include <openbsc/gsm_data.h>
#include <openbsc/talloc.h>
@@ -295,9 +296,15 @@ char *gsm_band_name(enum gsm_band band)
return "invalid";
}
-enum gsm_band gsm_band_parse(int mhz)
+enum gsm_band gsm_band_parse(const char* mhz)
{
- switch (mhz) {
+ while (*mhz && !isdigit(*mhz))
+ mhz++;
+
+ if (*mhz == '\0')
+ return -EINVAL;
+
+ switch (atoi(mhz)) {
case 400:
return GSM_BAND_400;
case 850:
diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c
index cee53cc13..05786dab4 100644
--- a/openbsc/src/input/ipaccess.c
+++ b/openbsc/src/input/ipaccess.c
@@ -461,7 +461,7 @@ static int listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
/* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */
ret = write(bfd->fd, id_req, sizeof(id_req));
- return e1inp_line_register(line);
+ //return e1inp_line_register(line);
}
static int rsl_listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
@@ -574,7 +574,7 @@ int ipaccess_connect(struct e1inp_line *line, struct sockaddr_in *sa)
line->driver = &ipaccess_driver;
- return e1inp_line_register(line);
+ //return e1inp_line_register(line);
}
int ipaccess_setup(struct gsm_network *gsmnet)
diff --git a/openbsc/src/input/misdn.c b/openbsc/src/input/misdn.c
index 2ec74b8ea..bd655d12e 100644
--- a/openbsc/src/input/misdn.c
+++ b/openbsc/src/input/misdn.c
@@ -49,12 +49,6 @@
#include <openbsc/e1_input.h>
#include <openbsc/talloc.h>
-/* data structure for one E1 interface with A-bis */
-struct mi_e1_handle {
- /* The mISDN card number of the card we use */
- int cardnr;
-};
-
#define TS1_ALLOC_SIZE 300
struct prim_name {
@@ -383,7 +377,6 @@ struct e1inp_driver misdn_driver = {
static int mi_e1_setup(struct e1inp_line *line, int release_l2)
{
- struct mi_e1_handle *e1h = line->driver_data;
int ts, ret;
/* TS0 is CRC4, don't need any fd for it */
@@ -422,7 +415,7 @@ static int mi_e1_setup(struct e1inp_line *line, int release_l2)
memset(&addr, 0, sizeof(addr));
addr.family = AF_ISDN;
- addr.dev = e1h->cardnr;
+ addr.dev = line->num;
switch (e1i_ts->type) {
case E1INP_TS_TYPE_SIGN:
addr.channel = 0;
@@ -471,20 +464,23 @@ static int mi_e1_setup(struct e1inp_line *line, int release_l2)
return 0;
}
-int mi_setup(int cardnr, struct e1inp_line *line, int release_l2)
+int mi_e1_line_update(struct e1inp_line *line)
{
- struct mi_e1_handle *e1h;
- int sk, ret, cnt;
struct mISDN_devinfo devinfo;
+ int sk, ret, cnt;
- /* create the actual line instance */
- e1h = talloc(tall_bsc_ctx, struct mi_e1_handle);
- memset(e1h, 0, sizeof(*e1h));
-
- e1h->cardnr = cardnr;
+ if (!line->driver) {
+ /* this must be the first update */
+ line->driver = &misdn_driver;
+ } else {
+ /* this is a subsequent update */
+ /* FIXME: first close all sockets */
+ fprintf(stderr, "incremental line updates not supported yet\n");
+ return 0;
+ }
- line->driver = &misdn_driver;
- line->driver_data = e1h;
+ if (line->driver != &misdn_driver)
+ return -EINVAL;
/* open the ISDN card device */
sk = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
@@ -504,11 +500,11 @@ int mi_setup(int cardnr, struct e1inp_line *line, int release_l2)
//DEBUGP(DMI,"%d device%s found\n", cnt, (cnt==1)?"":"s");
printf("%d device%s found\n", cnt, (cnt==1)?"":"s");
#if 1
- devinfo.id = e1h->cardnr;
+ devinfo.id = line->num;
ret = ioctl(sk, IMGETDEVINFO, &devinfo);
if (ret < 0) {
fprintf(stdout, "error getting info for device %d: %s\n",
- e1h->cardnr, strerror(errno));
+ line->num, strerror(errno));
return -ENODEV;
}
fprintf(stdout, " id: %d\n", devinfo.id);
@@ -524,11 +520,11 @@ int mi_setup(int cardnr, struct e1inp_line *line, int release_l2)
return -EINVAL;
}
- ret = mi_e1_setup(line, release_l2);
+ ret = mi_e1_setup(line, 1);
if (ret)
return ret;
- return e1inp_line_register(line);
+ return 0;
}
static __attribute__((constructor)) void on_dso_load_sms(void)
diff --git a/openbsc/src/vty/command.c b/openbsc/src/vty/command.c
index 16e0dfb36..f03dcbb4e 100644
--- a/openbsc/src/vty/command.c
+++ b/openbsc/src/vty/command.c
@@ -1909,27 +1909,49 @@ char **cmd_complete_command(vector vline, struct vty *vty, int *status)
/* return parent node */
/* MUST eventually converge on CONFIG_NODE */
-enum node_type node_parent(enum node_type node)
+enum node_type vty_go_parent(struct vty *vty)
{
- enum node_type ret;
+ assert(vty->node > CONFIG_NODE);
- assert(node > CONFIG_NODE);
-
- switch (node) {
- case BGP_VPNV4_NODE:
- case BGP_IPV4_NODE:
- case BGP_IPV4M_NODE:
- case BGP_IPV6_NODE:
- ret = BGP_NODE;
+ switch (vty->node) {
+ case GSMNET_NODE:
+ vty->node = CONFIG_NODE;
+ vty->index = NULL;
+ break;
+ case BTS_NODE:
+ vty->node = GSMNET_NODE;
+ {
+ /* set vty->index correctly ! */
+ struct gsm_bts *bts = vty->index;
+ vty->index = bts->network;
+ }
+ break;
+ case TRX_NODE:
+ vty->node = BTS_NODE;
+ {
+ /* set vty->index correctly ! */
+ struct gsm_bts_trx *trx = vty->index;
+ vty->index = trx->bts;
+ }
break;
- case KEYCHAIN_KEY_NODE:
- ret = KEYCHAIN_NODE;
+ case TS_NODE:
+ vty->node = TRX_NODE;
+ {
+ /* set vty->index correctly ! */
+ struct gsm_bts_trx_ts *ts = vty->index;
+ vty->index = ts->trx;
+ }
+ break;
+ case SUBSCR_NODE:
+ vty->node = VIEW_NODE;
+ subscr_put(vty->index);
+ vty->index = NULL;
break;
default:
- ret = CONFIG_NODE;
+ vty->node = CONFIG_NODE;
}
- return ret;
+ return vty->node;
}
/* Execute command by argument vline vector. */
@@ -2052,9 +2074,11 @@ cmd_execute_command(vector vline, struct vty *vty, struct cmd_element **cmd,
int vtysh)
{
int ret, saved_ret, tried = 0;
- enum node_type onode, try_node;
+ enum node_type onode;
+ void *oindex;
- onode = try_node = vty->node;
+ onode = vty->node;
+ oindex = vty->index;
if (cmd_try_do_shortcut(vty->node, vector_slot(vline, 0))) {
vector shifted_vline;
@@ -2085,8 +2109,7 @@ cmd_execute_command(vector vline, struct vty *vty, struct cmd_element **cmd,
/* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */
while (ret != CMD_SUCCESS && ret != CMD_WARNING
&& vty->node > CONFIG_NODE) {
- try_node = node_parent(try_node);
- vty->node = try_node;
+ vty_go_parent(vty);
ret = cmd_execute_command_real(vline, vty, cmd);
tried = 1;
if (ret == CMD_SUCCESS || ret == CMD_WARNING) {
@@ -2096,8 +2119,10 @@ cmd_execute_command(vector vline, struct vty *vty, struct cmd_element **cmd,
}
/* no command succeeded, reset the vty to the original node and
return the error for this node */
- if (tried)
+ if (tried) {
vty->node = onode;
+ vty->index = oindex;
+ }
return saved_ret;
}
@@ -2232,7 +2257,7 @@ int config_from_file(struct vty *vty, FILE * fp)
while (ret != CMD_SUCCESS && ret != CMD_WARNING
&& ret != CMD_ERR_NOTHING_TODO
&& vty->node != CONFIG_NODE) {
- vty->node = node_parent(vty->node);
+ vty_go_parent(vty);
ret = cmd_execute_command_strict(vline, vty, NULL);
}
@@ -2332,29 +2357,9 @@ DEFUN(config_exit,
vty->node = ENABLE_NODE;
vty_config_unlock(vty);
break;
- case INTERFACE_NODE:
- case ZEBRA_NODE:
- case BGP_NODE:
- case RIP_NODE:
- case RIPNG_NODE:
- case OSPF_NODE:
- case OSPF6_NODE:
- case ISIS_NODE:
- case KEYCHAIN_NODE:
- case MASC_NODE:
- case RMAP_NODE:
case VTY_NODE:
vty->node = CONFIG_NODE;
break;
- case BGP_VPNV4_NODE:
- case BGP_IPV4_NODE:
- case BGP_IPV4M_NODE:
- case BGP_IPV6_NODE:
- vty->node = BGP_NODE;
- break;
- case KEYCHAIN_KEY_NODE:
- vty->node = KEYCHAIN_NODE;
- break;
default:
break;
}
@@ -2375,22 +2380,6 @@ ALIAS(config_exit,
/* Nothing to do. */
break;
case CONFIG_NODE:
- case INTERFACE_NODE:
- case ZEBRA_NODE:
- case RIP_NODE:
- case RIPNG_NODE:
- case BGP_NODE:
- case BGP_VPNV4_NODE:
- case BGP_IPV4_NODE:
- case BGP_IPV4M_NODE:
- case BGP_IPV6_NODE:
- case RMAP_NODE:
- case OSPF_NODE:
- case OSPF6_NODE:
- case ISIS_NODE:
- case KEYCHAIN_NODE:
- case KEYCHAIN_KEY_NODE:
- case MASC_NODE:
case VTY_NODE:
vty_config_unlock(vty);
vty->node = ENABLE_NODE;
@@ -3350,8 +3339,7 @@ void cmd_init(int terminal)
/* Default host value settings. */
host.name = NULL;
- //host.password = NULL;
- host.password = "foo";
+ host.password = NULL;
host.enable = NULL;
host.logfile = NULL;
host.config = NULL;
diff --git a/openbsc/src/vty/vty.c b/openbsc/src/vty/vty.c
index 5472fa05a..b403a7b2c 100644
--- a/openbsc/src/vty/vty.c
+++ b/openbsc/src/vty/vty.c
@@ -743,22 +743,6 @@ static void vty_end_config(struct vty *vty)
/* Nothing to do. */
break;
case CONFIG_NODE:
- case INTERFACE_NODE:
- case ZEBRA_NODE:
- case RIP_NODE:
- case RIPNG_NODE:
- case BGP_NODE:
- case BGP_VPNV4_NODE:
- case BGP_IPV4_NODE:
- case BGP_IPV4M_NODE:
- case BGP_IPV6_NODE:
- case RMAP_NODE:
- case OSPF_NODE:
- case OSPF6_NODE:
- case ISIS_NODE:
- case KEYCHAIN_NODE:
- case KEYCHAIN_KEY_NODE:
- case MASC_NODE:
case VTY_NODE:
vty_config_unlock(vty);
vty->node = ENABLE_NODE;
@@ -1125,18 +1109,6 @@ static void vty_stop_input(struct vty *vty)
/* Nothing to do. */
break;
case CONFIG_NODE:
- case INTERFACE_NODE:
- case ZEBRA_NODE:
- case RIP_NODE:
- case RIPNG_NODE:
- case BGP_NODE:
- case RMAP_NODE:
- case OSPF_NODE:
- case OSPF6_NODE:
- case ISIS_NODE:
- case KEYCHAIN_NODE:
- case KEYCHAIN_KEY_NODE:
- case MASC_NODE:
case VTY_NODE:
vty_config_unlock(vty);
vty->node = ENABLE_NODE;
@@ -1393,7 +1365,7 @@ vty_read_file(FILE *confp)
fprintf(stderr, "Ambiguous command.\n");
break;
case CMD_ERR_NO_MATCH:
- fprintf(stderr, "Ther is no such command.\n");
+ fprintf(stderr, "There is no such command.\n");
break;
}
fprintf(stderr, "Error occurred during reading below "
@@ -1675,10 +1647,8 @@ void vty_init()
install_element(ENABLE_NODE, &show_history_cmd);
install_default(VTY_NODE);
-#if 0
install_element(VTY_NODE, &vty_login_cmd);
install_element(VTY_NODE, &no_vty_login_cmd);
-#endif
}
int vty_read_config_file(const char *file_name)
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 45b2c7469..b4aa9f4f5 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -164,13 +164,41 @@ DEFUN(show_bts, show_bts_cmd, "show bts [number]",
return CMD_SUCCESS;
}
+/* utility functions */
+static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
+ const char *ts, const char *ss)
+{
+ e1_link->e1_nr = atoi(line);
+ e1_link->e1_ts = atoi(ts);
+ if (!strcmp(ss, "full"))
+ e1_link->e1_ts_ss = 255;
+ else
+ e1_link->e1_ts_ss = atoi(ss);
+}
+
+static void config_write_e1_link(struct vty *vty, struct gsm_e1_subslot *e1_link,
+ const char *prefix)
+{
+ if (!e1_link->e1_ts)
+ return;
+
+ if (e1_link->e1_ts_ss == 255)
+ vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s",
+ prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE);
+ else
+ vty_out(vty, "%se1 line %u timeslot %u sub-slot %u%s",
+ prefix, e1_link->e1_nr, e1_link->e1_ts,
+ e1_link->e1_ts_ss, VTY_NEWLINE);
+}
+
+
static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
{
- vty_out(vty, " ts %u%s", ts->nr, VTY_NEWLINE);
- vty_out(vty, " phys_chan_config %s%s", gsm_pchan_name(ts->pchan),
- VTY_NEWLINE);
- vty_out(vty, " e1_subslot %u %u %u%s", ts->e1_link.e1_nr,
- ts->e1_link.e1_ts, ts->e1_link.e1_ts_ss, VTY_NEWLINE);
+ vty_out(vty, " timeslot %u%s", ts->nr, VTY_NEWLINE);
+ if (ts->pchan != GSM_PCHAN_NONE)
+ vty_out(vty, " phys_chan_config %s%s",
+ gsm_pchan_name(ts->pchan), VTY_NEWLINE);
+ config_write_e1_link(vty, &ts->e1_link, " ");
}
static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
@@ -180,6 +208,8 @@ static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
+ config_write_e1_link(vty, &trx->rsl_e1_link, " rsl ");
+ vty_out(vty, " rsl e1 tei %u%s", trx->rsl_tei, VTY_NEWLINE);
for (i = 0; i < TRX_NR_TS; i++)
config_write_ts_single(vty, &trx->ts[i]);
@@ -199,6 +229,10 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
if (is_ipaccess_bts(bts))
vty_out(vty, " ip.access unit_id %u %u%s",
bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
+ else {
+ config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
+ vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
+ }
llist_for_each_entry(trx, &bts->trx_list, list)
config_write_trx_single(vty, trx);
@@ -217,10 +251,10 @@ static int config_write_bts(struct vty *v)
static int config_write_net(struct vty *vty)
{
vty_out(vty, "network%s", VTY_NEWLINE);
- vty_out(vty, " country code %u%s", gsmnet->country_code, VTY_NEWLINE);
+ vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
- vty_out(vty, " short name '%s'%s", gsmnet->name_short, VTY_NEWLINE);
- vty_out(vty, " long name '%s'%s", gsmnet->name_long, VTY_NEWLINE);
+ vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
+ vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -230,9 +264,9 @@ static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
- "resulting BS power: %d dBm\n",
+ "resulting BS power: %d dBm%s",
trx->nominal_power, trx->max_power_red,
- trx->nominal_power - trx->max_power_red);
+ trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
vty_out(vty, " NM State: ");
net_dump_nmstate(vty, &trx->nm_state);
vty_out(vty, " Baseband Transceiver NM State: ");
@@ -550,6 +584,8 @@ DEFUN(show_e1line,
static void e1ts_dump_vty(struct vty *vty, struct e1inp_ts *ts)
{
+ if (ts->type == E1INP_TS_TYPE_NONE)
+ return;
vty_out(vty, "E1 Timeslot %2u of Line %u is Type %s%s",
ts->num, ts->line->num, e1inp_tstype_name(ts->type),
VTY_NEWLINE);
@@ -776,7 +812,7 @@ DEFUN(cfg_bts_band,
"Set the frequency band of this BTS\n")
{
struct gsm_bts *bts = vty->index;
- int band = gsm_band_parse(atoi(argv[0]));
+ int band = gsm_band_parse(argv[0]);
if (band < 0) {
vty_out(vty, "%% BAND %d is not a valid GSM band%s",
@@ -834,7 +870,7 @@ DEFUN(cfg_bts_bsic,
int bsic = atoi(argv[0]);
if (bsic < 0 || bsic > 0x3f) {
- vty_out(vty, "%% TSC %d is not in the valid range (0-255)%s",
+ vty_out(vty, "%% BSIC %d is not in the valid range (0-255)%s",
bsic, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -875,6 +911,31 @@ DEFUN(cfg_bts_unit_id,
return CMD_SUCCESS;
}
+DEFUN(cfg_bts_oml_e1,
+ cfg_bts_oml_e1_cmd,
+ "oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
+ "E1 interface to be used for OML\n")
+{
+ struct gsm_bts *bts = vty->index;
+
+ parse_e1_link(&bts->oml_e1_link, argv[0], argv[1], argv[2]);
+
+ return CMD_SUCCESS;
+}
+
+
+DEFUN(cfg_bts_oml_e1_tei,
+ cfg_bts_oml_e1_tei_cmd,
+ "oml e1 tei <0-63>",
+ "Set the TEI to be used for OML")
+{
+ struct gsm_bts *bts = vty->index;
+
+ bts->oml_tei = atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
/* per TRX configuration */
DEFUN(cfg_trx,
cfg_trx_cmd,
@@ -951,10 +1012,35 @@ DEFUN(cfg_trx_max_power_red,
return CMD_SUCCESS;
}
+DEFUN(cfg_trx_rsl_e1,
+ cfg_trx_rsl_e1_cmd,
+ "rsl e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
+ "E1 interface to be used for RSL\n")
+{
+ struct gsm_bts_trx *trx = vty->index;
+
+ parse_e1_link(&trx->rsl_e1_link, argv[0], argv[1], argv[2]);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_trx_rsl_e1_tei,
+ cfg_trx_rsl_e1_tei_cmd,
+ "rsl e1 tei <0-63>",
+ "Set the TEI to be used for RSL")
+{
+ struct gsm_bts_trx *trx = vty->index;
+
+ trx->rsl_tei = atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+
/* per TS configuration */
DEFUN(cfg_ts,
cfg_ts_cmd,
- "timeslot TS_NR",
+ "timeslot <0-7>",
"Select a Timeslot to configure")
{
int ts_nr = atoi(argv[0]);
@@ -994,14 +1080,12 @@ DEFUN(cfg_ts_pchan,
DEFUN(cfg_ts_e1_subslot,
cfg_ts_e1_subslot_cmd,
- "e1_subslot E1_IF <1-31> <0-4>",
+ "e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
"E1 sub-slot connected to this on-air timeslot")
{
struct gsm_bts_trx_ts *ts = vty->index;
- ts->e1_link.e1_nr = atoi(argv[0]);
- ts->e1_link.e1_ts = atoi(argv[1]);
- ts->e1_link.e1_ts_ss = atoi(argv[2]);
+ parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
return CMD_SUCCESS;
}
@@ -1158,6 +1242,7 @@ int bsc_vty_init(struct gsm_network *net)
install_element(CONFIG_NODE, &cfg_net_cmd);
install_node(&net_node, config_write_net);
install_default(GSMNET_NODE);
+ install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
@@ -1169,13 +1254,18 @@ int bsc_vty_init(struct gsm_network *net)
install_element(BTS_NODE, &cfg_bts_band_cmd);
install_element(BTS_NODE, &cfg_bts_lac_cmd);
install_element(BTS_NODE, &cfg_bts_tsc_cmd);
+ install_element(BTS_NODE, &cfg_bts_bsic_cmd);
install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
+ install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
+ install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
install_element(BTS_NODE, &cfg_trx_cmd);
install_node(&trx_node, dummy_config_write);
install_default(TRX_NODE);
install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
install_element(TRX_NODE, &cfg_trx_max_power_red_cmd);
+ install_element(TRX_NODE, &cfg_trx_rsl_e1_cmd);
+ install_element(TRX_NODE, &cfg_trx_rsl_e1_tei_cmd);
install_element(TRX_NODE, &cfg_ts_cmd);
install_node(&ts_node, dummy_config_write);