aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-02-15 03:38:12 +0000
committerHarald Welte <laforge@gnumonks.org>2009-02-15 03:38:12 +0000
commit8c1d0e41a7ca457854855f5aae4c929cd8396d88 (patch)
treeeb1ddd0338f1f5683dfd44fc34f24d79de1b2da5
parente0590df5242af3178dbf75d527536634be0b890b (diff)
* add bsc_hack commandline argument to select BTS type
* add event-based OML bring-up for nanoBTS
-rw-r--r--include/openbsc/gsm_data.h16
-rw-r--r--src/bsc_hack.c211
-rw-r--r--src/gsm_data.c6
3 files changed, 215 insertions, 18 deletions
diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h
index 9f3952118..801284eba 100644
--- a/include/openbsc/gsm_data.h
+++ b/include/openbsc/gsm_data.h
@@ -98,8 +98,12 @@ enum gsm_chreq_reason_t {
struct gsm_nm_state {
u_int8_t operational;
u_int8_t administrative;
+ u_int8_t availability;
+};
+struct gsm_attr {
+ u_int8_t len;
+ u_int8_t data[0];
};
-
/*
* LOCATION UPDATING REQUEST state
@@ -162,6 +166,7 @@ struct gsm_bts_trx_ts {
unsigned int flags;
struct gsm_nm_state nm_state;
+ struct gsm_attr *nm_attr;
/* To which E1 subslot are we connected */
struct gsm_e1_subslot e1_link;
@@ -177,6 +182,10 @@ struct gsm_bts_trx {
/* how do we talk RSL with this TRX? */
struct e1inp_sign_link *rsl_link;
struct gsm_nm_state nm_state;
+ struct gsm_attr *nm_attr;
+ struct {
+ struct gsm_nm_state nm_state;
+ } bb_transc;
u_int16_t arfcn;
struct gsm_bts_trx_ts ts[TRX_NR_TS];
@@ -236,6 +245,7 @@ struct gsm_bts {
/* Abis network management O&M handle */
struct abis_nm_h *nmh;
struct gsm_nm_state nm_state;
+ struct gsm_attr *nm_attr;
/* number of this BTS on given E1 link */
u_int8_t bts_nr;
@@ -269,8 +279,8 @@ struct gsm_network {
struct gsm_bts bts[GSM_MAX_BTS+1];
};
-struct gsm_network *gsm_network_init(unsigned int num_bts, u_int16_t country_code,
- u_int16_t network_code);
+struct gsm_network *gsm_network_init(unsigned int num_bts, enum gsm_bts_type bts_type,
+ u_int16_t country_code, u_int16_t network_code);
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
const char *gsm_lchan_name(enum gsm_chan_t c);
diff --git a/src/bsc_hack.c b/src/bsc_hack.c
index cb7e16496..f3be6c26b 100644
--- a/src/bsc_hack.c
+++ b/src/bsc_hack.c
@@ -54,6 +54,7 @@ static struct gsm_network *gsmnet;
static int MCC = 1;
static int MNC = 1;
static int ARFCN = HARDCODED_ARFCN;
+static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
static const char *database_name = "hlr.sqlite3";
/* The following definitions are for OM and NM packets that we cannot yet
@@ -140,13 +141,32 @@ SET BTS ATTRIBUTES
unsigned char msg_2[] =
{
- 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x09, 0x3F, 0x0A, 0x04, 0x61, 0x00, 0x0B,
- 0x01, 0x0C, 0x00, 0x62, 0x00, 0x66, 0x00, 0x6E, 0x06, 0x18, 0x1F, 0x19,
- 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B, 0x0B, 0x23, 0x14, 0x28, 0x00, 0x04,
- 0x03, 0x2A, 0x7F, 0x2B, 0x00, 0xFA, 0x8F, 0x7D, 0x33, 0x2C, 0x1F, 0x29,
- 0x5A, 0x5A, 0x5A, 0x87, 0x94, 0x23, 0x28, 0x95, 0x23, 0x28, 0x35, 0x01,
- 0x00, 0x46, 0x01, 0x00, 0x58, 0x01, 0x40, 0xC5, 0x01, 0x00, 0xF2, 0x01,
- 0x00, 0x08, 0x00, HARDCODED_ARFCN/*0x01*/,
+ 0x41, 0x01, 0x00, 0xFF, 0xFF,
+ NM_ATT_BSIC, 0x3F,
+ NM_ATT_BTS_AIR_TIMER, 0x04,
+ 0x61, 0x00,
+ NM_ATT_CCCH_L_I_P, 0x01,
+ NM_ATT_CCCH_L_T, 0x00,
+ 0x62, 0x00,
+ 0x66, 0x00,
+ 0x6E, 0x06,
+ NM_ATT_INTAVE_PARAM, 0x1F,
+ NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
+ NM_ATT_CCCH_L_T, 0x23,
+ NM_ATT_GSM_TIME, 0x28, 0x00,
+ NM_ATT_ADM_STATE, 0x03,
+ NM_ATT_RACH_B_THRESH, 0x7F,
+ NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
+ 0x8F, 0x7D,
+ NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
+ 0x94, 0x23, 0x28,
+ 0x95, 0x23, 0x28,
+ 0x35, 0x01, 0x00,
+ 0x46, 0x01, 0x00,
+ 0x58, 0x01, 0x40,
+ 0xC5, 0x01, 0x00,
+ 0xF2, 0x01, 0x00,
+ NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
};
// Handover Recognition, SET ATTRIBUTES
@@ -260,12 +280,138 @@ unsigned char msg_6[] =
0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
};
+static unsigned char nanobts_attr_bts[] = {
+ NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
+ NM_ATT_INTAVE_PARAM, 0x06,
+ NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
+ NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
+ NM_ATT_MAX_TA, 0x3f,
+ NM_ATT_OVERL_PERIOD, 0x00, 0x01, 0x0a,
+ NM_ATT_CCCH_L_T, 0x1e,
+ NM_ATT_CCCH_L_I_P, 0x64,
+ NM_ATT_RACH_B_THRESH, 0x0a,
+ NM_ATT_LDAVG_SLOTS, 0x03, 0xe8,
+ NM_ATT_BTS_AIR_TIMER, 0x80,
+ NM_ATT_NY1, 0x0a,
+ NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
+ NM_ATT_BSIC, 0x20,
+};
-static void bootstrap_om(struct gsm_bts *bts)
+static unsigned char nanobts_attr_radio[] = {
+ NM_ATT_RF_MAXPOWR_R, 0x0c,
+ NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
+};
+
+int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
+ struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
+{
+ struct gsm_bts *bts;
+ struct gsm_bts_trx *trx;
+ struct gsm_bts_trx_ts *ts;
+
+ /* This is currently only required on nanoBTS */
+
+ switch (evt) {
+ case EVT_STATECHG_OPER:
+ switch (obj_class) {
+ case NM_OC_SITE_MANAGER:
+ bts = container_of(obj, struct gsm_bts, site_mgr);
+ if (old_state->operational != 2 && new_state->operational == 2) {
+ abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
+ }
+ break;
+ case NM_OC_BTS:
+ bts = obj;
+ if (new_state->availability == 5) {
+ abis_nm_set_bts_attr(bts, nanobts_attr_bts,
+ sizeof(nanobts_attr_bts));
+ abis_nm_opstart(bts, NM_OC_BTS,
+ bts->nr, 0xff, 0xff);
+ abis_nm_chg_adm_state(bts, NM_OC_BTS,
+ bts->nr, 0xff, 0xff,
+ NM_STATE_UNLOCKED);
+ }
+ break;
+ case NM_OC_RADIO_CARRIER:
+ trx = obj;
+ if (new_state->availability == 3) {
+ abis_nm_set_radio_attr(trx, nanobts_attr_radio,
+ sizeof(nanobts_attr_radio));
+ abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
+ trx->bts->nr, trx->nr, 0xff);
+ abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
+ trx->bts->nr, trx->nr, 0xff,
+ NM_STATE_UNLOCKED);
+ }
+ break;
+ case NM_OC_CHANNEL:
+ ts = obj;
+ trx = ts->trx;
+ if (new_state->availability == 5) {
+ if (ts->nr == 0 && trx == trx->bts->c0)
+ abis_nm_set_channel_attr(ts, NM_CHANC_SDCCH_CBCH);
+ else
+ abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
+ abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
+ trx->bts->nr, trx->nr, ts->nr);
+ abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
+ trx->bts->nr, trx->nr, ts->nr,
+ NM_STATE_UNLOCKED);
+ }
+ break;
+ case NM_OC_BASEB_TRANSC:
+ trx = container_of(obj, struct gsm_bts_trx, bb_transc);
+ if (new_state->availability == 5) {
+ abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
+ trx->bts->nr, trx->nr, 0xff);
+ abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
+ trx->bts->nr, trx->nr, 0xff,
+ NM_STATE_UNLOCKED);
+ }
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+static void bootstrap_om_nanobts(struct gsm_bts *bts)
{
+#if 0
struct gsm_bts_trx *trx = &bts->trx[0];
+ int i;
- fprintf(stdout, "bootstrapping OML\n");
+ abis_nm_set_bts_attr(bts, nanobts_attr_bts, sizeof(nanobts_attr_bts));
+ abis_nm_opstart(bts, NM_OC_BTS, 0x00, 0xff, 0xff);
+ abis_nm_set_radio_attr(bts->c0, nanobts_attr_radio, sizeof(nanobts_attr_radio));
+
+ abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
+ for (i = 1; i < TRX_NR_TS; i++)
+ abis_nm_set_channel_attr(&trx->ts[i], NM_CHANC_TCHFull);
+
+ abis_nm_opstart(bts, NM_OC_BASEB_TRANSC, 0x00, 0x00, 0xff);
+ abis_nm_opstart(bts, NM_OC_RADIO_CARRIER, 0x00, 0x00, 0xff);
+
+
+ for (i = 0; i < TRX_NR_TS; i++)
+ abis_nm_opstart(bts, NM_OC_CHANNEL, 0x00, 0x00, i);
+
+ abis_nm_chg_adm_state(bts, NM_OC_BASEB_TRANSC, 0x00, 0x00, 0xff,
+ NM_STATE_UNLOCKED);
+
+ abis_nm_chg_adm_state(bts, NM_OC_RADIO_CARRIER, 0x00, 0x00, 0xff,
+ NM_STATE_UNLOCKED);
+
+ for (i = 0; i < TRX_NR_TS; i++)
+ abis_nm_chg_adm_state(bts, NM_OC_CHANNEL, 0x00, 0x00, i,
+ NM_STATE_UNLOCKED);
+
+#endif
+}
+
+static void bootstrap_om_bs11(struct gsm_bts *bts)
+{
+ struct gsm_bts_trx *trx = &bts->trx[0];
/* stop sending event reports */
abis_nm_event_reports(bts, 0);
@@ -355,6 +501,23 @@ static void bootstrap_om(struct gsm_bts *bts)
abis_nm_event_reports(bts, 1);
}
+static void bootstrap_om(struct gsm_bts *bts)
+{
+ fprintf(stdout, "bootstrapping OML\n");
+
+ switch (bts->type) {
+ case GSM_BTS_TYPE_BS11:
+ bootstrap_om_bs11(bts);
+ break;
+ case GSM_BTS_TYPE_NANOBTS_900:
+ case GSM_BTS_TYPE_NANOBTS_1800:
+ bootstrap_om_nanobts(bts);
+ break;
+ default:
+ fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
+ }
+}
+
static int shutdown_om(struct gsm_bts *bts)
{
/* stop sending event reports */
@@ -693,7 +856,7 @@ static int bootstrap_network(void)
struct gsm_bts *bts;
/* initialize our data structures */
- gsmnet = gsm_network_init(1, MCC, MNC);
+ gsmnet = gsm_network_init(1, BTS_TYPE, MCC, MNC);
if (!gsmnet)
return -ENOMEM;
@@ -718,7 +881,10 @@ static int bootstrap_network(void)
telnet_init(gsmnet, 4242);
/* E1 mISDN input setup */
- return e1_config(bts);
+ if (BTS_TYPE == GSM_BTS_TYPE_BS11)
+ return e1_config(bts);
+ else
+ return ia_config(bts);
}
static void create_pcap_file(char *file)
@@ -758,6 +924,23 @@ static void print_help()
printf(" -h --help this text\n");
}
+static const char *bts_types[] = {
+ [GSM_BTS_TYPE_UNKNOWN] = "unknown",
+ [GSM_BTS_TYPE_BS11] = "bs11",
+ [GSM_BTS_TYPE_NANOBTS_900] = "nanobts900",
+ [GSM_BTS_TYPE_NANOBTS_1800] = "nanobts1800",
+};
+
+enum gsm_bts_type parse_btstype(char *arg)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(bts_types); i++) {
+ if (!strcmp(arg, bts_types[i]))
+ return i;
+ }
+ return 0; /* Default: BS11 */
+}
+
static void handle_options(int argc, char** argv)
{
while (1) {
@@ -773,10 +956,11 @@ static void handle_options(int argc, char** argv)
{"reject-cause", 1, 0, 'r'},
{"pcap", 1, 0, 'p'},
{"arfcn", 1, 0, 'f'},
+ {"bts-type", 1, 0, 't'},
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, "hc:n:d:sar:p:f:",
+ c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:",
long_options, &option_index);
if (c == -1)
break;
@@ -813,6 +997,9 @@ static void handle_options(int argc, char** argv)
case 'p':
create_pcap_file(optarg);
break;
+ case 't':
+ BTS_TYPE = parse_btstype(optarg);
+ break;
default:
/* ignore */
break;
diff --git a/src/gsm_data.c b/src/gsm_data.c
index 6763fc506..0593f6fbd 100644
--- a/src/gsm_data.c
+++ b/src/gsm_data.c
@@ -82,8 +82,8 @@ const char *gsm_chreq_name(enum gsm_chreq_reason_t c)
return chreq_names[c];
}
-struct gsm_network *gsm_network_init(unsigned int num_bts, u_int16_t country_code,
- u_int16_t network_code)
+struct gsm_network *gsm_network_init(unsigned int num_bts, enum gsm_bts_type bts_type,
+ u_int16_t country_code, u_int16_t network_code)
{
int i;
struct gsm_network *net;
@@ -106,7 +106,7 @@ struct gsm_network *gsm_network_init(unsigned int num_bts, u_int16_t country_cod
bts->network = net;
bts->nr = i;
- bts->type = GSM_BTS_TYPE_BS11;
+ bts->type = bts_type;
for (j = 0; j < BTS_MAX_TRX; j++) {
struct gsm_bts_trx *trx = &bts->trx[j];