Merge branch 'master' into sms
diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h
index 47baafb..3dc5531 100644
--- a/openbsc/include/openbsc/abis_nm.h
+++ b/openbsc/include/openbsc/abis_nm.h
@@ -482,6 +482,12 @@
NM_CHANC_BCCH = 0x06,
NM_CHANC_BCCH_CBCH = 0x07,
NM_CHANC_SDCCH_CBCH = 0x08,
+ /* ip.access */
+ NM_CHANC_IPAC_bPDCH = 0x0b, /* PBCCH + PCCCH + PDTCH/F + PACCH/F + PTCCH/F */
+ NM_CHANC_IPAC_cPDCH = 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
+ NM_CHANC_IPAC_PDCH = 0x0d, /* PDTCH/F + PACCH/F + PTCCH/F */
+ NM_CHANC_IPAC_TCHFull_PDCH = 0x80,
+ NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81,
};
/* Section 9.4.16: Event Type */
@@ -672,6 +678,9 @@
int abis_nm_software_activate(struct gsm_bts *bts, const char *fname,
gsm_cbfn *cbfn, void *cb_data);
+int abis_nm_conn_mdrop_link(struct gsm_bts *bts, u_int8_t e1_port0, u_int8_t ts0,
+ u_int8_t e1_port1, u_int8_t ts1);
+
/* Siemens / BS-11 specific */
int abis_nm_bs11_reset_resource(struct gsm_bts *bts);
int abis_nm_bs11_db_transmission(struct gsm_bts *bts, int begin);
diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h
index a2a01d3..201c77f 100644
--- a/openbsc/include/openbsc/abis_rsl.h
+++ b/openbsc/include/openbsc/abis_rsl.h
@@ -333,6 +333,7 @@
#define RSL_ERR_TALKER_ACC_FAIL 0x03
#define RSL_ERR_OM_INTERVENTION 0x07
#define RSL_ERR_NORMAL_UNSPEC 0x0f
+#define RSL_ERR_T_MSRFPCI_EXP 0x18
/* resource unavailable */
#define RSL_ERR_EQUIPMENT_FAIL 0x20
#define RSL_ERR_RR_UNAVAIL 0x21
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 50d24b6..52dec90 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -54,6 +54,11 @@
#define HARDCODED_TSC 7
#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */
+/* for multi-drop config */
+#define HARDCODED_BTS0_TS 1
+#define HARDCODED_BTS1_TS 6
+#define HARDCODED_BTS2_TS 11
+
enum gsm_hooks {
GSM_HOOK_NM_SWLOAD,
GSM_HOOK_RR_PAGING,
diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c
index dec4b29..0eb8657 100644
--- a/openbsc/src/abis_nm.c
+++ b/openbsc/src/abis_nm.c
@@ -357,18 +357,47 @@
/* ip.access specifics */
[NM_ATT_IPACC_DST_IP] = { TLV_TYPE_FIXED, 4 },
[NM_ATT_IPACC_DST_IP_PORT] = { TLV_TYPE_FIXED, 2 },
+ [NM_ATT_IPACC_STREAM_ID] = { TLV_TYPE_TV, },
+ [NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_TV, },
+ [NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
+ [NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
+ [NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
+ [NM_ATT_IPACC_IN_SERV_TIME] = { TLV_TYPE_FIXED, 4 },
+ [NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_PAGING_CFG] = { TLV_TYPE_FIXED, 2 },
+ [NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_NV_FLAGS] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_FIXED, 2 },
[NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
- [NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
- [NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
- [NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
- [NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_CUR_SW_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_TIMING_BUS] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_CGI] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_RAC] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_OBJ_VERSION] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NSEI] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_BVCI] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NSVCI] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NS_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_BSSGP_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_NS_LINK_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_RLC_CFG] = { TLV_TYPE_TL16V },
[NM_ATT_IPACC_ALM_THRESH_LIST]= { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_TIB_CONTROL] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_SUPP_FEATURES] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_CODING_SCHEMES] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_RLC_CFG_2] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_HEARTB_TOUT] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_UPTIME] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_RLC_CFG_3] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_SSL_CFG] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V },
+ [NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
//[0x95] = { TLV_TYPE_FIXED, 2 },
[0x85] = { TLV_TYPE_TV },
@@ -937,6 +966,9 @@
case NM_MT_BS11_LMT_SESSION:
return abis_nm_rx_lmt_event(mb);
break;
+ case NM_MT_CONN_MDROP_LINK_ACK:
+ DEBUGP(DNM, "CONN MDROP LINK ACK\n");
+ break;
}
return 0;
@@ -1731,6 +1763,32 @@
return abis_nm_sendmsg(bts, msg);
}
+int abis_nm_conn_mdrop_link(struct gsm_bts *bts, u_int8_t e1_port0, u_int8_t ts0,
+ u_int8_t e1_port1, u_int8_t ts1)
+{
+ struct abis_om_hdr *oh;
+ struct msgb *msg = nm_msgb_alloc();
+ u_int8_t *attr;
+
+ DEBUGP(DNM, "CONNECT MDROP LINK E1=(%u,%u) -> E1=(%u, %u)\n",
+ e1_port0, ts0, e1_port1, ts1);
+
+ oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
+ fill_om_fom_hdr(oh, 6, NM_MT_CONN_MDROP_LINK,
+ NM_OC_SITE_MANAGER, 0x00, 0x00, 0x00);
+
+ attr = msgb_put(msg, 3);
+ attr[0] = NM_ATT_MDROP_LINK;
+ attr[1] = e1_port0;
+ attr[2] = ts0;
+
+ attr = msgb_put(msg, 3);
+ attr[0] = NM_ATT_MDROP_NEXT;
+ attr[1] = e1_port1;
+ attr[2] = ts1;
+
+ return abis_nm_sendmsg(bts, msg);
+}
int abis_nm_event_reports(struct gsm_bts *bts, int on)
{
@@ -2121,7 +2179,7 @@
bs11_sw->win_size,
bs11_sw->forced,
&bs11_swload_cbfn, bs11_sw);
- free(fle);
+ talloc_free(fle);
} else {
/* activate the SWL */
rc = abis_nm_software_activate(bs11_sw->bts,
@@ -2175,7 +2233,7 @@
/* start download the next file of our file list */
rc = abis_nm_software_load(bts, fle->fname, win_size, forced,
bs11_swload_cbfn, bs11_sw);
- free(fle);
+ talloc_free(fle);
return rc;
}
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index eb43bd5..1a2c58b 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -321,6 +321,7 @@
[RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
[RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
[RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
+ [RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
[RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
[RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
[RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
@@ -1089,7 +1090,8 @@
arfcn = lchan->ts->trx->arfcn;
subch = lchan->nr;
- lchan->ms_power = lchan->bs_power = 0x0f; /* 30dB reduction */
+ lchan->ms_power = ms_pwr_ctl_lvl(bts, 20 /* dBm == 100mW */);
+ lchan->bs_power = 0x0f; /* 30dB reduction */
lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
@@ -1188,7 +1190,7 @@
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
u_int8_t *rlm_cause = rllh->data;
- DEBUGPC(DRLL, "cause=0x%02x", rlm_cause[1]);
+ DEBUGPC(DRLL, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
return rsl_chan_release(msg->lchan);
@@ -1232,24 +1234,22 @@
}
break;
case RSL_MT_REL_IND:
- DEBUGPC(DRLL, "RELEASE INDICATION ");
+ DEBUGPC(DRLL, "RELEASE INDICATION\n");
break;
case RSL_MT_REL_CONF:
- DEBUGPC(DRLL, "RELEASE CONFIRMATION ");
+ DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
break;
case RSL_MT_ERROR_IND:
- DEBUGPC(DRLL, "ERROR INDICATION ");
rc = rsl_rx_rll_err_ind(msg);
break;
case RSL_MT_UNIT_DATA_IND:
- DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x ",
+ DEBUGPC(DRLL, "unimplemented Abis RLL message type 0x%02x\n",
rllh->c.msg_type);
break;
default:
- DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x ",
+ DEBUGPC(DRLL, "unknown Abis RLL message type 0x%02x\n",
rllh->c.msg_type);
}
- DEBUGPC(DRLL, "\n");
return rc;
}
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index b762f8c..82cb788 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -62,6 +62,7 @@
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";
@@ -503,6 +504,23 @@
static void bootstrap_om_bs11(struct gsm_bts *bts)
{
struct gsm_bts_trx *trx = bts->c0;
+ int base_ts;
+
+ switch (bts->nr) {
+ case 0:
+ /* First BTS uses E1 TS 01,02,03,04,05 */
+ base_ts = HARDCODED_BTS0_TS - 1;
+ break;
+ case 1:
+ /* Second BTS uses E1 TS 06,07,08,09,10 */
+ base_ts = HARDCODED_BTS1_TS - 1;
+ break;
+ case 2:
+ /* Third BTS uses E1 TS 11,12,13,14,15 */
+ base_ts = HARDCODED_BTS2_TS - 1;
+ default:
+ return;
+ }
/* stop sending event reports */
abis_nm_event_reports(bts, 0);
@@ -525,47 +543,47 @@
abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
/* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
- abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
+ abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
/* Use TEI 1 for signalling */
- abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
+ abis_nm_establish_tei(bts, 0, 0, base_ts+1, 0xff, 0x01);
abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
/* SET CHANNEL ATTRIBUTE TS1 */
abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
- abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
+ abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+2, 1);
/* SET CHANNEL ATTRIBUTE TS2 */
abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
- abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
+ abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+2, 2);
/* SET CHANNEL ATTRIBUTE TS3 */
abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
- abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
+ abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+2, 3);
/* SET CHANNEL ATTRIBUTE TS4 */
abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
- abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
+ abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+3, 0);
/* SET CHANNEL ATTRIBUTE TS5 */
abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
- abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
+ abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+3, 1);
/* SET CHANNEL ATTRIBUTE TS6 */
abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
- abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
+ abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+3, 2);
/* SET CHANNEL ATTRIBUTE TS7 */
abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
- abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
+ abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+3, 3);
trx = gsm_bts_trx_num(bts, 1);
if (trx) {
@@ -581,53 +599,53 @@
trx1_attr_radio[3] = arfcn_low;
/* Connect signalling of TRX1 to e1_0/ts1/64kbps */
- abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
+ abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
/* FIXME: TRX ATTRIBUTE */
abis_nm_set_radio_attr(trx, trx1_attr_radio,
sizeof(trx1_attr_radio));
/* Use TEI 2 for signalling */
- abis_nm_establish_tei(bts, 1, 0, 1, 0xff, 0x02);
+ abis_nm_establish_tei(bts, 1, 0, base_ts+1, 0xff, 0x02);
- /* SET CHANNEL ATTRIBUTE TS1 */
- abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
- /* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/a */
- abis_nm_conn_terr_traf(&trx->ts[1], 0, 4, 0);
+ /* SET CHANNEL ATTRIBUTE TS0 */
+ abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_TCHFull);
+ /* Connect traffic of bts0/trx0/ts0 to e1_0/ts4/a */
+ abis_nm_conn_terr_traf(&trx->ts[0], 0, base_ts+4, 0);
/* SET CHANNEL ATTRIBUTE TS1 */
abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/b */
- abis_nm_conn_terr_traf(&trx->ts[1], 0, 4, 1);
+ abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+4, 1);
/* SET CHANNEL ATTRIBUTE TS2 */
abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts2 to e1_0/ts4/c */
- abis_nm_conn_terr_traf(&trx->ts[2], 0, 4, 2);
+ abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+4, 2);
/* SET CHANNEL ATTRIBUTE TS3 */
abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts3 to e1_0/ts4/d */
- abis_nm_conn_terr_traf(&trx->ts[3], 0, 4, 3);
+ abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+4, 3);
/* SET CHANNEL ATTRIBUTE TS4 */
abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts4 to e1_0/ts5/a */
- abis_nm_conn_terr_traf(&trx->ts[4], 0, 5, 0);
+ abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+5, 0);
/* SET CHANNEL ATTRIBUTE TS5 */
abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts5 to e1_0/ts5/b */
- abis_nm_conn_terr_traf(&trx->ts[5], 0, 5, 1);
+ abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+5, 1);
/* SET CHANNEL ATTRIBUTE TS6 */
abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts6 to e1_0/ts5/c */
- abis_nm_conn_terr_traf(&trx->ts[6], 0, 5, 2);
+ abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+5, 2);
/* SET CHANNEL ATTRIBUTE TS7 */
abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
/* Connect traffic of bts0/trx0/ts7 to e1_0/ts5/d */
- abis_nm_conn_terr_traf(&trx->ts[7], 0, 5, 3);
+ abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+5, 3);
}
/* end DB transmission */
@@ -659,6 +677,8 @@
static int shutdown_om(struct gsm_bts *bts)
{
+ fprintf(stdout, "shutting down OML for BTS %u\n", bts->nr);
+
/* stop sending event reports */
abis_nm_event_reports(bts, 0);
@@ -890,10 +910,12 @@
{
int i;
- for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
- rsl_bcch_info(trx, bcch_infos[i].type,
- bcch_infos[i].data,
- bcch_infos[i].len);
+ if (trx == trx->bts->c0) {
+ for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
+ rsl_bcch_info(trx, bcch_infos[i].type,
+ bcch_infos[i].data,
+ bcch_infos[i].len);
+ }
}
rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
@@ -964,7 +986,7 @@
{
fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
"using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
- trx->nr, trx->bts->nr, MCC, MNC, BSIC, TSC);
+ trx->bts->nr, trx->nr, MCC, MNC, BSIC, TSC);
set_system_infos(trx);
}
@@ -1040,6 +1062,8 @@
static int bootstrap_network(void)
{
+ int rc;
+
switch(BTS_TYPE) {
case GSM_BTS_TYPE_NANOBTS_1800:
if (ARFCN < 512 || ARFCN > 885) {
@@ -1093,11 +1117,26 @@
trx1 = gsm_bts_trx_alloc(bts);
trx1->arfcn = ARFCN + 2;
}
-
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;
+ }
- gsmnet->num_bts = 1;
- return e1_config(bts, cardnr, release_l2);
+ 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;
@@ -1153,6 +1192,7 @@
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");
}
@@ -1182,10 +1222,11 @@
{"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:P1",
+ c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:S:B:P12",
long_options, &option_index);
if (c == -1)
break;
@@ -1262,6 +1303,9 @@
case '1':
bs11_has_trx1 = 1;
break;
+ case '2':
+ bs11_has_bts1 = 1;
+ break;
}
default:
/* ignore */
@@ -1275,9 +1319,11 @@
fprintf(stdout, "signal %u received\n", signal);
switch (signal) {
- case SIGHUP:
+ case SIGINT:
case SIGABRT:
shutdown_net(gsmnet);
+ sleep(3);
+ exit(0);
break;
case SIGUSR1:
talloc_report_full(tall_bsc_ctx, stderr);
@@ -1303,7 +1349,7 @@
if (rc < 0)
exit(1);
- signal(SIGHUP, &signal_handler);
+ signal(SIGINT, &signal_handler);
signal(SIGABRT, &signal_handler);
signal(SIGUSR1, &signal_handler);
diff --git a/openbsc/src/e1_config.c b/openbsc/src/e1_config.c
index addc9fe..8987803 100644
--- a/openbsc/src/e1_config.c
+++ b/openbsc/src/e1_config.c
@@ -25,18 +25,35 @@
struct e1inp_ts *sign_ts;
struct e1inp_sign_link *oml_link, *rsl_link;
struct gsm_bts_trx *trx = bts->c0;
+ int base_ts;
+
+ switch (bts->nr) {
+ case 0:
+ /* First BTS uses E1 TS 01,02,03,04,05 */
+ base_ts = HARDCODED_BTS0_TS - 1;
+ break;
+ case 1:
+ /* Second BTS uses E1 TS 06,07,08,09,10 */
+ base_ts = HARDCODED_BTS1_TS - 1;
+ break;
+ case 2:
+ /* Third BTS uses E1 TS 11,12,13,14,15 */
+ base_ts = HARDCODED_BTS2_TS - 1;
+ default:
+ return -EINVAL;
+ }
line = talloc_zero(tall_bsc_ctx, struct e1inp_line);
if (!line)
return -ENOMEM;
/* create E1 timeslots for signalling and TRAU frames */
- e1inp_ts_config(&line->ts[1-1], line, E1INP_TS_TYPE_SIGN);
- e1inp_ts_config(&line->ts[2-1], line, E1INP_TS_TYPE_TRAU);
- e1inp_ts_config(&line->ts[3-1], line, E1INP_TS_TYPE_TRAU);
+ e1inp_ts_config(&line->ts[base_ts+1-1], line, E1INP_TS_TYPE_SIGN);
+ e1inp_ts_config(&line->ts[base_ts+2-1], line, E1INP_TS_TYPE_TRAU);
+ e1inp_ts_config(&line->ts[base_ts+3-1], line, E1INP_TS_TYPE_TRAU);
/* create signalling links for TS1 */
- sign_ts = &line->ts[1-1];
+ sign_ts = &line->ts[base_ts+1-1];
oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML,
trx, TEI_OML, SAPI_OML);
rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
@@ -47,40 +64,40 @@
trx->rsl_link = rsl_link;
/* enable subchannel demuxer on TS2 */
- subch_demux_activate(&line->ts[2-1].trau.demux, 1);
- subch_demux_activate(&line->ts[2-1].trau.demux, 2);
- subch_demux_activate(&line->ts[2-1].trau.demux, 3);
+ subch_demux_activate(&line->ts[base_ts+2-1].trau.demux, 1);
+ subch_demux_activate(&line->ts[base_ts+2-1].trau.demux, 2);
+ subch_demux_activate(&line->ts[base_ts+2-1].trau.demux, 3);
/* enable subchannel demuxer on TS3 */
- subch_demux_activate(&line->ts[3-1].trau.demux, 0);
- subch_demux_activate(&line->ts[3-1].trau.demux, 1);
- subch_demux_activate(&line->ts[3-1].trau.demux, 2);
- subch_demux_activate(&line->ts[3-1].trau.demux, 3);
+ subch_demux_activate(&line->ts[base_ts+3-1].trau.demux, 0);
+ subch_demux_activate(&line->ts[base_ts+3-1].trau.demux, 1);
+ subch_demux_activate(&line->ts[base_ts+3-1].trau.demux, 2);
+ subch_demux_activate(&line->ts[base_ts+3-1].trau.demux, 3);
trx = gsm_bts_trx_num(bts, 1);
if (trx) {
/* create E1 timeslots for TRAU frames of TRX1 */
- e1inp_ts_config(&line->ts[4-1], line, E1INP_TS_TYPE_TRAU);
- e1inp_ts_config(&line->ts[5-1], line, E1INP_TS_TYPE_TRAU);
+ e1inp_ts_config(&line->ts[base_ts+4-1], line, E1INP_TS_TYPE_TRAU);
+ e1inp_ts_config(&line->ts[base_ts+5-1], line, E1INP_TS_TYPE_TRAU);
/* create RSL signalling link for TRX1 */
- sign_ts = &line->ts[1-1];
+ sign_ts = &line->ts[base_ts+1-1];
rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
trx, TEI_RSL+1, SAPI_RSL);
/* create back-links from trx */
trx->rsl_link = rsl_link;
/* enable subchannel demuxer on TS2 */
- subch_demux_activate(&line->ts[4-1].trau.demux, 0);
- subch_demux_activate(&line->ts[4-1].trau.demux, 1);
- subch_demux_activate(&line->ts[4-1].trau.demux, 2);
- subch_demux_activate(&line->ts[4-1].trau.demux, 3);
+ subch_demux_activate(&line->ts[base_ts+4-1].trau.demux, 0);
+ subch_demux_activate(&line->ts[base_ts+4-1].trau.demux, 1);
+ subch_demux_activate(&line->ts[base_ts+4-1].trau.demux, 2);
+ subch_demux_activate(&line->ts[base_ts+4-1].trau.demux, 3);
/* enable subchannel demuxer on TS3 */
- subch_demux_activate(&line->ts[5-1].trau.demux, 0);
- subch_demux_activate(&line->ts[5-1].trau.demux, 1);
- subch_demux_activate(&line->ts[5-1].trau.demux, 2);
- subch_demux_activate(&line->ts[5-1].trau.demux, 3);
+ subch_demux_activate(&line->ts[base_ts+5-1].trau.demux, 0);
+ subch_demux_activate(&line->ts[base_ts+5-1].trau.demux, 1);
+ subch_demux_activate(&line->ts[base_ts+5-1].trau.demux, 2);
+ subch_demux_activate(&line->ts[base_ts+5-1].trau.demux, 3);
}
return mi_setup(cardnr, line, release_l2);
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index c21c6b4..285b758 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -117,7 +117,7 @@
}
}
- llist_add(&trx->list, &bts->trx_list);
+ llist_add_tail(&trx->list, &bts->trx_list);
return trx;
}
@@ -147,7 +147,7 @@
}
bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4;
- llist_add(&bts->list, &net->bts_list);
+ llist_add_tail(&bts->list, &net->bts_list);
return bts;
}
@@ -270,15 +270,15 @@
{
switch (band) {
case GSM_BAND_400:
- return "GSM 400";
+ return "GSM400";
case GSM_BAND_850:
- return "GSM 850";
+ return "GSM850";
case GSM_BAND_900:
- return "GSM 900";
+ return "GSM900";
case GSM_BAND_1800:
- return "DCS 1800";
+ return "DCS1800";
case GSM_BAND_1900:
- return "PCS 1900";
+ return "PCS1900";
}
return "invalid";
}
diff --git a/openbsc/src/input/misdn.c b/openbsc/src/input/misdn.c
index a04c2ab..2ec74b8 100644
--- a/openbsc/src/input/misdn.c
+++ b/openbsc/src/input/misdn.c
@@ -477,14 +477,7 @@
int sk, ret, cnt;
struct mISDN_devinfo devinfo;
- /* register the driver with the core */
- /* FIXME: do this in the plugin initializer function */
- ret = e1inp_driver_register(&misdn_driver);
- if (ret)
- return ret;
-
/* create the actual line instance */
- /* FIXME: do this independent of driver registration */
e1h = talloc(tall_bsc_ctx, struct mi_e1_handle);
memset(e1h, 0, sizeof(*e1h));
@@ -531,14 +524,15 @@
return -EINVAL;
}
- if (devinfo.nrbchan != 30) {
- fprintf(stderr, "error: E1 card has no 30 B-channels\n");
- return -EINVAL;
- }
-
ret = mi_e1_setup(line, release_l2);
if (ret)
return ret;
return e1inp_line_register(line);
}
+
+static __attribute__((constructor)) void on_dso_load_sms(void)
+{
+ /* register the driver with the core */
+ e1inp_driver_register(&misdn_driver);
+}
diff --git a/openbsc/src/vty/command.c b/openbsc/src/vty/command.c
index e9b3652..44bdf26 100644
--- a/openbsc/src/vty/command.c
+++ b/openbsc/src/vty/command.c
@@ -34,6 +34,7 @@
#include <ctype.h>
#include <time.h>
#include <sys/time.h>
+#include <sys/stat.h>
//#include "memory.h"
//#include "log.h"
@@ -474,6 +475,7 @@
cmd->cmdsize = cmd_cmdsize(cmd->strvec);
}
+#ifdef VTY_CRYPT_PW
static unsigned char itoa64[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -499,6 +501,7 @@
return crypt(passwd, salt);
}
+#endif
/* This function write configuration of this host. */
static int config_write_host(struct vty *vty)
@@ -2216,7 +2219,6 @@
return (*matched_element->func) (matched_element, vty, argc, argv);
}
-#if 0
/* Configration make from file. */
int config_from_file(struct vty *vty, FILE * fp)
{
@@ -2248,7 +2250,6 @@
}
return CMD_SUCCESS;
}
-#endif
/* Configration from terminal */
DEFUN(config_terminal,
@@ -2445,7 +2446,6 @@
return CMD_SUCCESS;
}
-#if 0
/* Write current configuration into file. */
DEFUN(config_write_file,
config_write_file_cmd,
@@ -2549,7 +2549,7 @@
if (chmod(config_file, CONFIGFILE_MASK) != 0) {
vty_out(vty, "Can't chmod configuration file %s: %s (%d).%s",
- config_file, safe_strerror(errno), errno, VTY_NEWLINE);
+ config_file, strerror(errno), errno, VTY_NEWLINE);
return CMD_WARNING;
}
@@ -2640,7 +2640,6 @@
return CMD_SUCCESS;
}
-#endif
/* Hostname configuration */
DEFUN(config_hostname,
@@ -3329,13 +3328,11 @@
install_element(node, &config_help_cmd);
install_element(node, &config_list_cmd);
-#if 0
install_element(node, &config_write_terminal_cmd);
install_element(node, &config_write_file_cmd);
install_element(node, &config_write_memory_cmd);
install_element(node, &config_write_cmd);
install_element(node, &show_running_config_cmd);
-#endif
}
/* Initialize command interface. Install basic nodes and commands. */
@@ -3379,9 +3376,9 @@
install_default(ENABLE_NODE);
install_element(ENABLE_NODE, &config_disable_cmd);
install_element(ENABLE_NODE, &config_terminal_cmd);
- //install_element (ENABLE_NODE, ©_runningconfig_startupconfig_cmd);
+ install_element (ENABLE_NODE, ©_runningconfig_startupconfig_cmd);
}
- //install_element (ENABLE_NODE, &show_startup_config_cmd);
+ install_element (ENABLE_NODE, &show_startup_config_cmd);
install_element(ENABLE_NODE, &show_version_cmd);
if (terminal) {
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 11b2ff6..b480c3d 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -157,6 +157,56 @@
return CMD_SUCCESS;
}
+static void config_write_ts_single(struct vty *vty, struct gsm_bts_trx_ts *ts)
+{
+ vty_out(vty, "\t\tts %u%s", ts->nr, VTY_NEWLINE);
+ vty_out(vty, "\t\t\tphys_chan_config %s%s", gsm_pchan_name(ts->pchan),
+ VTY_NEWLINE);
+ vty_out(vty, "\t\t\te1_subslot %u %u %u%s", ts->e1_link.e1_nr,
+ ts->e1_link.e1_ts, ts->e1_link.e1_ts_ss, VTY_NEWLINE);
+}
+
+static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx)
+{
+ int i;
+
+ vty_out(vty, "\ttrx %u%s", trx->nr, VTY_NEWLINE);
+ vty_out(vty, "\t\tarfcn %u%s", trx->arfcn, VTY_NEWLINE);
+ vty_out(vty, "\t\tmax_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
+
+ for (i = 0; i < TRX_NR_TS; i++)
+ config_write_ts_single(vty, &trx->ts[i]);
+}
+
+static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
+{
+ struct gsm_bts_trx *trx;
+
+ vty_out(vty, "bts %u%s", bts->nr, VTY_NEWLINE);
+ vty_out(vty, "\ttype %s%s", btstype2str(bts->type), VTY_NEWLINE);
+ vty_out(vty, "\tband %s%s", gsm_band_name(bts->band), VTY_NEWLINE);
+ vty_out(vty, "\tlocation_area_code %u%s", bts->location_area_code,
+ VTY_NEWLINE);
+ vty_out(vty, "\ttraining_sequence_code %u%s", bts->tsc, VTY_NEWLINE);
+ vty_out(vty, "\tbase_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
+ vty_out(vty, "\tunit_id %u %u%s",
+ bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
+
+ llist_for_each_entry(trx, &bts->trx_list, list)
+ config_write_trx_single(vty, trx);
+}
+
+static int config_write_bts(struct vty *v)
+{
+ struct gsm_bts *bts;
+
+ llist_for_each_entry(bts, &gsmnet->bts_list, list)
+ config_write_bts_single(v, bts);
+
+ return CMD_SUCCESS;
+}
+
+
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",
@@ -224,6 +274,7 @@
return CMD_SUCCESS;
}
+
static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
{
struct in_addr ia;
@@ -942,7 +993,7 @@
install_element(VIEW_NODE, &show_subscr_cmd);
install_element(CONFIG_NODE, &cfg_bts_cmd);
- install_node(&bts_node, dummy_config_write);
+ install_node(&bts_node, config_write_bts);
install_default(BTS_NODE);
install_element(BTS_NODE, &cfg_bts_type_cmd);
install_element(BTS_NODE, &cfg_bts_band_cmd);