bsc_hack.c: Make adding of (nano)BTS to the network dynamic

Fix the FIXME and replace the hardcoded site_id's of the
nanoBTS with a command line option. You can use -i DEVICE_X
for every BTS you want to handle.
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index 688ee9f..58c209f 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -63,6 +63,15 @@
 static enum gsm_band BAND = GSM_BAND_900;
 static const char *database_name = "hlr.sqlite3";
 
+struct nano_bts_id {
+	struct llist_head entry;
+	int site_id;
+	int bts_id;
+};
+
+static LLIST_HEAD(nanobts_ids);
+
+
 /* The following definitions are for OM and NM packets that we cannot yet
  * generate by code but we just pass on */
 
@@ -963,8 +972,6 @@
 
 static int bootstrap_network(void)
 {
-	struct gsm_bts *bts;
-
 	switch(BTS_TYPE) {
 	case GSM_BTS_TYPE_NANOBTS_1800:
 		if (ARFCN < 512 || ARFCN > 885) {
@@ -993,9 +1000,6 @@
 	gsmnet->name_long = "OpenBSC";
 	gsmnet->name_short = "OpenBSC";
 
-	bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC);
-	bootstrap_bts(bts);
-
 	if (db_init(database_name)) {
 		printf("DB: Failed to init database. Please check the option settings.\n");
 		return -1;
@@ -1014,17 +1018,27 @@
 
 	/* E1 mISDN input setup */
 	if (BTS_TYPE == GSM_BTS_TYPE_BS11) {
+		struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC);
+		bootstrap_bts(bts);
+
 		gsmnet->num_bts = 1;
 		return e1_config(bts, cardnr, release_l2);
 	} else {
-		/* FIXME: do this dynamic */
-		bts->ip_access.site_id = 1801;
-		bts->ip_access.bts_id = 0;
+		struct nano_bts_id *bts_id;
+		struct gsm_bts *bts;
 
-		bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC);
-		bootstrap_bts(bts);
-		bts->ip_access.site_id = 1800;
-		bts->ip_access.bts_id = 0;
+		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, HARDCODED_TSC, HARDCODED_BSIC);
+			bootstrap_bts(bts);
+			bts->ip_access.site_id = bts_id->site_id;
+			bts->ip_access.bts_id = 0;
+		}
+
 		return ipaccess_setup(gsmnet);
 	}
 }
@@ -1061,6 +1075,7 @@
 	printf("  -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
 	printf("  -p --pcap file  The filename of the pcap file\n");
 	printf("  -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
+	printf("  -i --bts-id=NUMBER The known nanoBTS device numbers. Can be specified multiple times.\n");
 	printf("  -C --cardnr number  For bs11 select E1 card number other than 0\n");
 	printf("  -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
 	printf("  -h --help this text\n");
@@ -1087,10 +1102,11 @@
 			{"release-l2", 0, 0, 'R'},
 			{"timestamp", 0, 0, 'T'},
 			{"band", 0, 0, 'b'},
+			{"bts-id", 1, 0, 'i'},
 			{0, 0, 0, 0}
 		};
 
-		c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:",
+		c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:",
 				long_options, &option_index);
 		if (c == -1)
 			break;
@@ -1145,6 +1161,17 @@
 		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;
+		}
 		default:
 			/* ignore */
 			break;