the actual config file code (not just config files)
this was missing from commit a08a9acdb6
This commit is contained in:
parent
3c5cb256c2
commit
42581829ec
|
@ -113,6 +113,9 @@ int e1inp_driver_register(struct e1inp_driver *drv);
|
||||||
/* register a line with the E1 core */
|
/* register a line with the E1 core */
|
||||||
int e1inp_line_register(struct e1inp_line *line);
|
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 */
|
/* find a sign_link for given TEI and SAPI in a TS */
|
||||||
struct e1inp_sign_link *
|
struct e1inp_sign_link *
|
||||||
e1inp_lookup_sign_link(struct e1inp_ts *ts, u_int8_t tei,
|
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 */
|
/* 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);
|
struct subch_mux *e1inp_get_mux(u_int8_t e1_nr, u_int8_t ts_nr);
|
||||||
|
|
||||||
|
|
||||||
/* e1_config.c */
|
/* 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 ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin);
|
||||||
int ipaccess_setup(struct gsm_network *gsmnet);
|
int ipaccess_setup(struct gsm_network *gsmnet);
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,10 @@ struct gsm_bts_trx {
|
||||||
/* number of this TRX in the BTS */
|
/* number of this TRX in the BTS */
|
||||||
u_int8_t nr;
|
u_int8_t nr;
|
||||||
/* how do we talk RSL with this TRX? */
|
/* 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 e1inp_sign_link *rsl_link;
|
||||||
|
|
||||||
struct gsm_nm_state nm_state;
|
struct gsm_nm_state nm_state;
|
||||||
struct tlv_parsed nm_attr;
|
struct tlv_parsed nm_attr;
|
||||||
struct {
|
struct {
|
||||||
|
@ -293,6 +296,8 @@ struct gsm_bts {
|
||||||
enum gsm_bts_type type;
|
enum gsm_bts_type type;
|
||||||
enum gsm_band band;
|
enum gsm_band band;
|
||||||
/* how do we talk OML with this TRX? */
|
/* 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;
|
struct e1inp_sign_link *oml_link;
|
||||||
|
|
||||||
/* Abis network management O&M handle */
|
/* 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);
|
struct gsm_bts *start_bts);
|
||||||
|
|
||||||
char *gsm_band_name(enum gsm_band band);
|
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;
|
extern void *tall_bsc_ctx;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define HAVE_VA_COPY
|
||||||
|
|
||||||
/* this is only needed for compatibility with the old talloc */
|
/* this is only needed for compatibility with the old talloc */
|
||||||
typedef void TALLOC_CTX;
|
typedef void TALLOC_CTX;
|
||||||
|
|
||||||
|
|
|
@ -61,12 +61,6 @@ struct host {
|
||||||
|
|
||||||
/* There are some command levels which called from command node. */
|
/* There are some command levels which called from command node. */
|
||||||
enum node_type {
|
enum node_type {
|
||||||
GSMNET_NODE,
|
|
||||||
BTS_NODE,
|
|
||||||
TRX_NODE,
|
|
||||||
TS_NODE,
|
|
||||||
SUBSCR_NODE,
|
|
||||||
|
|
||||||
AUTH_NODE, /* Authentication mode of vty interface. */
|
AUTH_NODE, /* Authentication mode of vty interface. */
|
||||||
VIEW_NODE, /* View node. Default mode of vty interface. */
|
VIEW_NODE, /* View node. Default mode of vty interface. */
|
||||||
AUTH_ENABLE_NODE, /* Authentication mode for change enable. */
|
AUTH_ENABLE_NODE, /* Authentication mode for change enable. */
|
||||||
|
@ -74,6 +68,7 @@ enum node_type {
|
||||||
CONFIG_NODE, /* Config node. Default mode of config file. */
|
CONFIG_NODE, /* Config node. Default mode of config file. */
|
||||||
SERVICE_NODE, /* Service node. */
|
SERVICE_NODE, /* Service node. */
|
||||||
DEBUG_NODE, /* Debug node. */
|
DEBUG_NODE, /* Debug node. */
|
||||||
|
#if 0
|
||||||
AAA_NODE, /* AAA node. */
|
AAA_NODE, /* AAA node. */
|
||||||
KEYCHAIN_NODE, /* Key-chain node. */
|
KEYCHAIN_NODE, /* Key-chain node. */
|
||||||
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
|
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
|
||||||
|
@ -103,7 +98,14 @@ enum node_type {
|
||||||
SMUX_NODE, /* SNMP configuration node. */
|
SMUX_NODE, /* SNMP configuration node. */
|
||||||
DUMP_NODE, /* Packet dump node. */
|
DUMP_NODE, /* Packet dump node. */
|
||||||
FORWARDING_NODE, /* IP forwarding 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
|
/* Node which has some commands and prompt string and configuration
|
||||||
|
|
|
@ -55,27 +55,12 @@ static struct gsm_network *gsmnet;
|
||||||
/* MCC and MNC for the Location Area Identifier */
|
/* MCC and MNC for the Location Area Identifier */
|
||||||
static int MCC = 1;
|
static int MCC = 1;
|
||||||
static int MNC = 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 cardnr = 0;
|
||||||
static int release_l2 = 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_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
|
||||||
static enum gsm_band BAND = GSM_BAND_900;
|
|
||||||
static const char *database_name = "hlr.sqlite3";
|
static const char *database_name = "hlr.sqlite3";
|
||||||
extern int ipacc_rtp_direct;
|
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
|
/* The following definitions are for OM and NM packets that we cannot yet
|
||||||
* generate by code but we just pass on */
|
* 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) "
|
fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
|
||||||
"using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
|
"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);
|
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)
|
static int bootstrap_bts(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
bts->band = BAND;
|
switch (bts->type) {
|
||||||
bts->location_area_code = LAC;
|
case GSM_BTS_TYPE_NANOBTS_1800:
|
||||||
bts->c0->arfcn = ARFCN;
|
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 */
|
/* Control Channel Description */
|
||||||
memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bootstrap_network(void)
|
static int bootstrap_network(void)
|
||||||
{
|
{
|
||||||
|
struct gsm_bts *bts;
|
||||||
int rc;
|
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 */
|
/* initialize our data structures */
|
||||||
gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
|
gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
|
||||||
if (!gsmnet)
|
if (!gsmnet)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
gsmnet->name_long = "OpenBSC";
|
gsmnet->name_long = talloc_strdup(gsmnet, "OpenBSC");
|
||||||
gsmnet->name_short = "OpenBSC";
|
gsmnet->name_short = talloc_strdup(gsmnet, "OpenBSC");
|
||||||
|
|
||||||
if (db_init(database_name)) {
|
if (db_init(database_name)) {
|
||||||
printf("DB: Failed to init database. Please check the option settings.\n");
|
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");
|
printf("DB: Database prepared.\n");
|
||||||
|
|
||||||
telnet_init(gsmnet, 4242);
|
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);
|
register_signal_handler(SS_NM, nm_sig_cb, NULL);
|
||||||
|
|
||||||
/* E1 mISDN input setup */
|
llist_for_each_entry(bts, &gsmnet->bts_list, list) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
bootstrap_bts(bts);
|
bootstrap_bts(bts);
|
||||||
rc = e1_config(bts, cardnr, release_l2);
|
if (is_ipaccess_bts(bts))
|
||||||
if (rc < 0) {
|
rc = ipaccess_setup(bts);
|
||||||
fprintf(stderr, "Error during E1 config of BTS 0\n");
|
else
|
||||||
return rc;
|
rc = e1_reconfig_bts(bts);
|
||||||
}
|
|
||||||
|
|
||||||
if (bs11_has_bts1) {
|
if (rc < 0)
|
||||||
bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
|
exit (1);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ipaccess_setup(gsmnet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_pcap_file(char *file)
|
static void create_pcap_file(char *file)
|
||||||
|
@ -1178,22 +1103,15 @@ static void print_usage()
|
||||||
static void print_help()
|
static void print_help()
|
||||||
{
|
{
|
||||||
printf(" Some useful help...\n");
|
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(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
|
||||||
printf(" -s --disable-color\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(" -l --database db-name The database to use\n");
|
||||||
printf(" -a --authorize-everyone Allow everyone into the network.\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(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
|
||||||
printf(" -p --pcap file The filename of the pcap file\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(" -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(" -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)
|
static void handle_options(int argc, char** argv)
|
||||||
|
@ -1204,29 +1122,18 @@ static void handle_options(int argc, char** argv)
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
{"debug", 1, 0, 'd'},
|
{"debug", 1, 0, 'd'},
|
||||||
{"disable-color", 0, 0, 's'},
|
{"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'},
|
{"database", 1, 0, 'l'},
|
||||||
{"authorize-everyone", 0, 0, 'a'},
|
{"authorize-everyone", 0, 0, 'a'},
|
||||||
{"reject-cause", 1, 0, 'r'},
|
{"reject-cause", 1, 0, 'r'},
|
||||||
{"pcap", 1, 0, 'p'},
|
{"pcap", 1, 0, 'p'},
|
||||||
{"arfcn", 1, 0, 'f'},
|
|
||||||
{"bts-type", 1, 0, 't'},
|
|
||||||
{"cardnr", 1, 0, 'C'},
|
{"cardnr", 1, 0, 'C'},
|
||||||
{"release-l2", 0, 0, 'R'},
|
{"release-l2", 0, 0, 'R'},
|
||||||
{"timestamp", 0, 0, 'T'},
|
{"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'},
|
{"rtp-proxy", 0, 0, 'P'},
|
||||||
{"trx1", 0, 0, '1'},
|
|
||||||
{"second-bs11", 0, 0, '2'},
|
|
||||||
{0, 0, 0, 0}
|
{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);
|
long_options, &option_index);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
@ -1242,18 +1149,6 @@ static void handle_options(int argc, char** argv)
|
||||||
case 'd':
|
case 'd':
|
||||||
debug_parse_category_mask(optarg);
|
debug_parse_category_mask(optarg);
|
||||||
break;
|
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':
|
case 'l':
|
||||||
database_name = strdup(optarg);
|
database_name = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -1278,35 +1173,9 @@ static void handle_options(int argc, char** argv)
|
||||||
case 'T':
|
case 'T':
|
||||||
debug_timestamp(1);
|
debug_timestamp(1);
|
||||||
break;
|
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':
|
case 'P':
|
||||||
ipacc_rtp_direct = 0;
|
ipacc_rtp_direct = 0;
|
||||||
break;
|
break;
|
||||||
case '1':
|
|
||||||
bs11_has_trx1 = 1;
|
|
||||||
break;
|
|
||||||
case '2':
|
|
||||||
bs11_has_bts1 = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
/* ignore */
|
/* ignore */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -14,10 +14,106 @@
|
||||||
#define SAPI_OML 62
|
#define SAPI_OML 62
|
||||||
#define SAPI_RSL 0 /* 63 ? */
|
#define SAPI_RSL 0 /* 63 ? */
|
||||||
|
|
||||||
#define TEI_L2ML 127
|
/* The e1_reconfig_*() functions below tale the configuration present in the
|
||||||
#define TEI_OML 25
|
* bts/trx/ts data structures and ensure the E1 configuration reflects the
|
||||||
#define TEI_RSL 1
|
* 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 */
|
/* do some compiled-in configuration for our BTS/E1 setup */
|
||||||
int e1_config(struct gsm_bts *bts, int cardnr, int release_l2)
|
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);
|
return mi_setup(cardnr, line, release_l2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* configure pseudo E1 line in ip.access style and connect to BTS */
|
/* configure pseudo E1 line in ip.access style and connect to BTS */
|
||||||
int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin)
|
int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin)
|
||||||
|
|
|
@ -289,6 +289,9 @@ int _abis_nm_sendmsg(struct msgb *msg)
|
||||||
int e1inp_ts_config(struct e1inp_ts *ts, struct e1inp_line *line,
|
int e1inp_ts_config(struct e1inp_ts *ts, struct e1inp_line *line,
|
||||||
enum e1inp_ts_type type)
|
enum e1inp_ts_type type)
|
||||||
{
|
{
|
||||||
|
if (ts->type == type && ts->line && line)
|
||||||
|
return 0;
|
||||||
|
|
||||||
ts->type = type;
|
ts->type = type;
|
||||||
ts->line = line;
|
ts->line = line;
|
||||||
|
|
||||||
|
@ -322,6 +325,29 @@ static struct e1inp_line *e1inp_line_get(u_int8_t e1_nr)
|
||||||
return NULL;
|
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)
|
static struct e1inp_ts *e1inp_ts_get(u_int8_t e1_nr, u_int8_t ts_nr)
|
||||||
{
|
{
|
||||||
struct e1inp_line *e1i_line;
|
struct e1inp_line *e1i_line;
|
||||||
|
@ -386,6 +412,12 @@ e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type,
|
||||||
return link;
|
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 */
|
/* the E1 driver tells us he has received something on a TS */
|
||||||
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
|
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
|
||||||
u_int8_t tei, u_int8_t sapi)
|
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);
|
write_pcap_packet(PCAP_INPUT, sapi, tei, msg);
|
||||||
link = e1inp_lookup_sign_link(ts, tei, sapi);
|
link = e1inp_lookup_sign_link(ts, tei, sapi);
|
||||||
if (!link) {
|
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);
|
"tei %d, sapi %d\n", tei, sapi);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -487,19 +519,9 @@ int e1inp_driver_register(struct e1inp_driver *drv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register a line with the E1 core */
|
int e1inp_line_update(struct e1inp_line *line)
|
||||||
int e1inp_line_register(struct e1inp_line *line)
|
|
||||||
{
|
{
|
||||||
int i;
|
return mi_e1_line_update(line);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __attribute__((constructor)) void on_dso_load_e1_inp(void)
|
static __attribute__((constructor)) void on_dso_load_e1_inp(void)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <openbsc/gsm_data.h>
|
#include <openbsc/gsm_data.h>
|
||||||
#include <openbsc/talloc.h>
|
#include <openbsc/talloc.h>
|
||||||
|
@ -295,9 +296,15 @@ char *gsm_band_name(enum gsm_band band)
|
||||||
return "invalid";
|
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:
|
case 400:
|
||||||
return GSM_BAND_400;
|
return GSM_BAND_400;
|
||||||
case 850:
|
case 850:
|
||||||
|
|
|
@ -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 */
|
/* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */
|
||||||
ret = write(bfd->fd, id_req, sizeof(id_req));
|
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)
|
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;
|
line->driver = &ipaccess_driver;
|
||||||
|
|
||||||
return e1inp_line_register(line);
|
//return e1inp_line_register(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipaccess_setup(struct gsm_network *gsmnet)
|
int ipaccess_setup(struct gsm_network *gsmnet)
|
||||||
|
|
|
@ -49,12 +49,6 @@
|
||||||
#include <openbsc/e1_input.h>
|
#include <openbsc/e1_input.h>
|
||||||
#include <openbsc/talloc.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
|
#define TS1_ALLOC_SIZE 300
|
||||||
|
|
||||||
struct prim_name {
|
struct prim_name {
|
||||||
|
@ -383,7 +377,6 @@ struct e1inp_driver misdn_driver = {
|
||||||
|
|
||||||
static int mi_e1_setup(struct e1inp_line *line, int release_l2)
|
static int mi_e1_setup(struct e1inp_line *line, int release_l2)
|
||||||
{
|
{
|
||||||
struct mi_e1_handle *e1h = line->driver_data;
|
|
||||||
int ts, ret;
|
int ts, ret;
|
||||||
|
|
||||||
/* TS0 is CRC4, don't need any fd for it */
|
/* 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));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.family = AF_ISDN;
|
addr.family = AF_ISDN;
|
||||||
addr.dev = e1h->cardnr;
|
addr.dev = line->num;
|
||||||
switch (e1i_ts->type) {
|
switch (e1i_ts->type) {
|
||||||
case E1INP_TS_TYPE_SIGN:
|
case E1INP_TS_TYPE_SIGN:
|
||||||
addr.channel = 0;
|
addr.channel = 0;
|
||||||
|
@ -471,20 +464,23 @@ static int mi_e1_setup(struct e1inp_line *line, int release_l2)
|
||||||
return 0;
|
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;
|
struct mISDN_devinfo devinfo;
|
||||||
|
int sk, ret, cnt;
|
||||||
|
|
||||||
/* create the actual line instance */
|
if (!line->driver) {
|
||||||
e1h = talloc(tall_bsc_ctx, struct mi_e1_handle);
|
/* this must be the first update */
|
||||||
memset(e1h, 0, sizeof(*e1h));
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
e1h->cardnr = cardnr;
|
if (line->driver != &misdn_driver)
|
||||||
|
return -EINVAL;
|
||||||
line->driver = &misdn_driver;
|
|
||||||
line->driver_data = e1h;
|
|
||||||
|
|
||||||
/* open the ISDN card device */
|
/* open the ISDN card device */
|
||||||
sk = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
|
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");
|
//DEBUGP(DMI,"%d device%s found\n", cnt, (cnt==1)?"":"s");
|
||||||
printf("%d device%s found\n", cnt, (cnt==1)?"":"s");
|
printf("%d device%s found\n", cnt, (cnt==1)?"":"s");
|
||||||
#if 1
|
#if 1
|
||||||
devinfo.id = e1h->cardnr;
|
devinfo.id = line->num;
|
||||||
ret = ioctl(sk, IMGETDEVINFO, &devinfo);
|
ret = ioctl(sk, IMGETDEVINFO, &devinfo);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stdout, "error getting info for device %d: %s\n",
|
fprintf(stdout, "error getting info for device %d: %s\n",
|
||||||
e1h->cardnr, strerror(errno));
|
line->num, strerror(errno));
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
fprintf(stdout, " id: %d\n", devinfo.id);
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mi_e1_setup(line, release_l2);
|
ret = mi_e1_setup(line, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return e1inp_line_register(line);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __attribute__((constructor)) void on_dso_load_sms(void)
|
static __attribute__((constructor)) void on_dso_load_sms(void)
|
||||||
|
|
|
@ -1909,27 +1909,49 @@ char **cmd_complete_command(vector vline, struct vty *vty, int *status)
|
||||||
|
|
||||||
/* return parent node */
|
/* return parent node */
|
||||||
/* MUST eventually converge on CONFIG_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 (vty->node) {
|
||||||
|
case GSMNET_NODE:
|
||||||
switch (node) {
|
vty->node = CONFIG_NODE;
|
||||||
case BGP_VPNV4_NODE:
|
vty->index = NULL;
|
||||||
case BGP_IPV4_NODE:
|
|
||||||
case BGP_IPV4M_NODE:
|
|
||||||
case BGP_IPV6_NODE:
|
|
||||||
ret = BGP_NODE;
|
|
||||||
break;
|
break;
|
||||||
case KEYCHAIN_KEY_NODE:
|
case BTS_NODE:
|
||||||
ret = KEYCHAIN_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 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;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = CONFIG_NODE;
|
vty->node = CONFIG_NODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return vty->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute command by argument vline vector. */
|
/* 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 vtysh)
|
||||||
{
|
{
|
||||||
int ret, saved_ret, tried = 0;
|
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))) {
|
if (cmd_try_do_shortcut(vty->node, vector_slot(vline, 0))) {
|
||||||
vector shifted_vline;
|
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 */
|
/* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */
|
||||||
while (ret != CMD_SUCCESS && ret != CMD_WARNING
|
while (ret != CMD_SUCCESS && ret != CMD_WARNING
|
||||||
&& vty->node > CONFIG_NODE) {
|
&& vty->node > CONFIG_NODE) {
|
||||||
try_node = node_parent(try_node);
|
vty_go_parent(vty);
|
||||||
vty->node = try_node;
|
|
||||||
ret = cmd_execute_command_real(vline, vty, cmd);
|
ret = cmd_execute_command_real(vline, vty, cmd);
|
||||||
tried = 1;
|
tried = 1;
|
||||||
if (ret == CMD_SUCCESS || ret == CMD_WARNING) {
|
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
|
/* no command succeeded, reset the vty to the original node and
|
||||||
return the error for this node */
|
return the error for this node */
|
||||||
if (tried)
|
if (tried) {
|
||||||
vty->node = onode;
|
vty->node = onode;
|
||||||
|
vty->index = oindex;
|
||||||
|
}
|
||||||
return saved_ret;
|
return saved_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2232,7 +2257,7 @@ int config_from_file(struct vty *vty, FILE * fp)
|
||||||
while (ret != CMD_SUCCESS && ret != CMD_WARNING
|
while (ret != CMD_SUCCESS && ret != CMD_WARNING
|
||||||
&& ret != CMD_ERR_NOTHING_TODO
|
&& ret != CMD_ERR_NOTHING_TODO
|
||||||
&& vty->node != CONFIG_NODE) {
|
&& vty->node != CONFIG_NODE) {
|
||||||
vty->node = node_parent(vty->node);
|
vty_go_parent(vty);
|
||||||
ret = cmd_execute_command_strict(vline, vty, NULL);
|
ret = cmd_execute_command_strict(vline, vty, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2332,29 +2357,9 @@ DEFUN(config_exit,
|
||||||
vty->node = ENABLE_NODE;
|
vty->node = ENABLE_NODE;
|
||||||
vty_config_unlock(vty);
|
vty_config_unlock(vty);
|
||||||
break;
|
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:
|
case VTY_NODE:
|
||||||
vty->node = CONFIG_NODE;
|
vty->node = CONFIG_NODE;
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2375,22 +2380,6 @@ ALIAS(config_exit,
|
||||||
/* Nothing to do. */
|
/* Nothing to do. */
|
||||||
break;
|
break;
|
||||||
case CONFIG_NODE:
|
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:
|
case VTY_NODE:
|
||||||
vty_config_unlock(vty);
|
vty_config_unlock(vty);
|
||||||
vty->node = ENABLE_NODE;
|
vty->node = ENABLE_NODE;
|
||||||
|
@ -3350,8 +3339,7 @@ void cmd_init(int terminal)
|
||||||
|
|
||||||
/* Default host value settings. */
|
/* Default host value settings. */
|
||||||
host.name = NULL;
|
host.name = NULL;
|
||||||
//host.password = NULL;
|
host.password = NULL;
|
||||||
host.password = "foo";
|
|
||||||
host.enable = NULL;
|
host.enable = NULL;
|
||||||
host.logfile = NULL;
|
host.logfile = NULL;
|
||||||
host.config = NULL;
|
host.config = NULL;
|
||||||
|
|
|
@ -743,22 +743,6 @@ static void vty_end_config(struct vty *vty)
|
||||||
/* Nothing to do. */
|
/* Nothing to do. */
|
||||||
break;
|
break;
|
||||||
case CONFIG_NODE:
|
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:
|
case VTY_NODE:
|
||||||
vty_config_unlock(vty);
|
vty_config_unlock(vty);
|
||||||
vty->node = ENABLE_NODE;
|
vty->node = ENABLE_NODE;
|
||||||
|
@ -1125,18 +1109,6 @@ static void vty_stop_input(struct vty *vty)
|
||||||
/* Nothing to do. */
|
/* Nothing to do. */
|
||||||
break;
|
break;
|
||||||
case CONFIG_NODE:
|
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:
|
case VTY_NODE:
|
||||||
vty_config_unlock(vty);
|
vty_config_unlock(vty);
|
||||||
vty->node = ENABLE_NODE;
|
vty->node = ENABLE_NODE;
|
||||||
|
@ -1393,7 +1365,7 @@ vty_read_file(FILE *confp)
|
||||||
fprintf(stderr, "Ambiguous command.\n");
|
fprintf(stderr, "Ambiguous command.\n");
|
||||||
break;
|
break;
|
||||||
case CMD_ERR_NO_MATCH:
|
case CMD_ERR_NO_MATCH:
|
||||||
fprintf(stderr, "Ther is no such command.\n");
|
fprintf(stderr, "There is no such command.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Error occurred during reading below "
|
fprintf(stderr, "Error occurred during reading below "
|
||||||
|
@ -1675,10 +1647,8 @@ void vty_init()
|
||||||
install_element(ENABLE_NODE, &show_history_cmd);
|
install_element(ENABLE_NODE, &show_history_cmd);
|
||||||
|
|
||||||
install_default(VTY_NODE);
|
install_default(VTY_NODE);
|
||||||
#if 0
|
|
||||||
install_element(VTY_NODE, &vty_login_cmd);
|
install_element(VTY_NODE, &vty_login_cmd);
|
||||||
install_element(VTY_NODE, &no_vty_login_cmd);
|
install_element(VTY_NODE, &no_vty_login_cmd);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int vty_read_config_file(const char *file_name)
|
int vty_read_config_file(const char *file_name)
|
||||||
|
|
|
@ -164,13 +164,41 @@ DEFUN(show_bts, show_bts_cmd, "show bts [number]",
|
||||||
return CMD_SUCCESS;
|
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)
|
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, " timeslot %u%s", ts->nr, VTY_NEWLINE);
|
||||||
vty_out(vty, " phys_chan_config %s%s", gsm_pchan_name(ts->pchan),
|
if (ts->pchan != GSM_PCHAN_NONE)
|
||||||
VTY_NEWLINE);
|
vty_out(vty, " phys_chan_config %s%s",
|
||||||
vty_out(vty, " e1_subslot %u %u %u%s", ts->e1_link.e1_nr,
|
gsm_pchan_name(ts->pchan), VTY_NEWLINE);
|
||||||
ts->e1_link.e1_ts, ts->e1_link.e1_ts_ss, VTY_NEWLINE);
|
config_write_e1_link(vty, &ts->e1_link, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
|
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, " trx %u%s", trx->nr, VTY_NEWLINE);
|
||||||
vty_out(vty, " arfcn %u%s", trx->arfcn, 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);
|
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++)
|
for (i = 0; i < TRX_NR_TS; i++)
|
||||||
config_write_ts_single(vty, &trx->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))
|
if (is_ipaccess_bts(bts))
|
||||||
vty_out(vty, " ip.access unit_id %u %u%s",
|
vty_out(vty, " ip.access unit_id %u %u%s",
|
||||||
bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
|
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)
|
llist_for_each_entry(trx, &bts->trx_list, list)
|
||||||
config_write_trx_single(vty, trx);
|
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)
|
static int config_write_net(struct vty *vty)
|
||||||
{
|
{
|
||||||
vty_out(vty, "network%s", VTY_NEWLINE);
|
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, " 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, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
|
||||||
vty_out(vty, " long name '%s'%s", gsmnet->name_long, VTY_NEWLINE);
|
vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
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",
|
vty_out(vty, "TRX %u of BTS %u is on ARFCN %u%s",
|
||||||
trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
|
trx->nr, trx->bts->nr, trx->arfcn, VTY_NEWLINE);
|
||||||
vty_out(vty, " RF Nominal Power: %d dBm, reduced by %u dB, "
|
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);
|
trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
|
||||||
vty_out(vty, " NM State: ");
|
vty_out(vty, " NM State: ");
|
||||||
net_dump_nmstate(vty, &trx->nm_state);
|
net_dump_nmstate(vty, &trx->nm_state);
|
||||||
vty_out(vty, " Baseband Transceiver 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)
|
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",
|
vty_out(vty, "E1 Timeslot %2u of Line %u is Type %s%s",
|
||||||
ts->num, ts->line->num, e1inp_tstype_name(ts->type),
|
ts->num, ts->line->num, e1inp_tstype_name(ts->type),
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
|
@ -776,7 +812,7 @@ DEFUN(cfg_bts_band,
|
||||||
"Set the frequency band of this BTS\n")
|
"Set the frequency band of this BTS\n")
|
||||||
{
|
{
|
||||||
struct gsm_bts *bts = vty->index;
|
struct gsm_bts *bts = vty->index;
|
||||||
int band = gsm_band_parse(atoi(argv[0]));
|
int band = gsm_band_parse(argv[0]);
|
||||||
|
|
||||||
if (band < 0) {
|
if (band < 0) {
|
||||||
vty_out(vty, "%% BAND %d is not a valid GSM band%s",
|
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]);
|
int bsic = atoi(argv[0]);
|
||||||
|
|
||||||
if (bsic < 0 || bsic > 0x3f) {
|
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);
|
bsic, VTY_NEWLINE);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
@ -875,6 +911,31 @@ DEFUN(cfg_bts_unit_id,
|
||||||
return CMD_SUCCESS;
|
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 */
|
/* per TRX configuration */
|
||||||
DEFUN(cfg_trx,
|
DEFUN(cfg_trx,
|
||||||
cfg_trx_cmd,
|
cfg_trx_cmd,
|
||||||
|
@ -951,10 +1012,35 @@ DEFUN(cfg_trx_max_power_red,
|
||||||
return CMD_SUCCESS;
|
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 */
|
/* per TS configuration */
|
||||||
DEFUN(cfg_ts,
|
DEFUN(cfg_ts,
|
||||||
cfg_ts_cmd,
|
cfg_ts_cmd,
|
||||||
"timeslot TS_NR",
|
"timeslot <0-7>",
|
||||||
"Select a Timeslot to configure")
|
"Select a Timeslot to configure")
|
||||||
{
|
{
|
||||||
int ts_nr = atoi(argv[0]);
|
int ts_nr = atoi(argv[0]);
|
||||||
|
@ -994,14 +1080,12 @@ DEFUN(cfg_ts_pchan,
|
||||||
|
|
||||||
DEFUN(cfg_ts_e1_subslot,
|
DEFUN(cfg_ts_e1_subslot,
|
||||||
cfg_ts_e1_subslot_cmd,
|
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")
|
"E1 sub-slot connected to this on-air timeslot")
|
||||||
{
|
{
|
||||||
struct gsm_bts_trx_ts *ts = vty->index;
|
struct gsm_bts_trx_ts *ts = vty->index;
|
||||||
|
|
||||||
ts->e1_link.e1_nr = atoi(argv[0]);
|
parse_e1_link(&ts->e1_link, argv[0], argv[1], argv[2]);
|
||||||
ts->e1_link.e1_ts = atoi(argv[1]);
|
|
||||||
ts->e1_link.e1_ts_ss = atoi(argv[2]);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1158,6 +1242,7 @@ int bsc_vty_init(struct gsm_network *net)
|
||||||
install_element(CONFIG_NODE, &cfg_net_cmd);
|
install_element(CONFIG_NODE, &cfg_net_cmd);
|
||||||
install_node(&net_node, config_write_net);
|
install_node(&net_node, config_write_net);
|
||||||
install_default(GSMNET_NODE);
|
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_mnc_cmd);
|
||||||
install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
|
install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
|
||||||
install_element(GSMNET_NODE, &cfg_net_name_long_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_band_cmd);
|
||||||
install_element(BTS_NODE, &cfg_bts_lac_cmd);
|
install_element(BTS_NODE, &cfg_bts_lac_cmd);
|
||||||
install_element(BTS_NODE, &cfg_bts_tsc_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_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_element(BTS_NODE, &cfg_trx_cmd);
|
||||||
install_node(&trx_node, dummy_config_write);
|
install_node(&trx_node, dummy_config_write);
|
||||||
install_default(TRX_NODE);
|
install_default(TRX_NODE);
|
||||||
install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
|
install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
|
||||||
install_element(TRX_NODE, &cfg_trx_max_power_red_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_element(TRX_NODE, &cfg_ts_cmd);
|
||||||
install_node(&ts_node, dummy_config_write);
|
install_node(&ts_node, dummy_config_write);
|
||||||
|
|
Loading…
Reference in New Issue