[si] Make it possible to set the NECI value...

Allow to configure the NECI value... and change code
that is relying on the NECI value.
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index 186a53f..4a3bdc1 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -724,8 +724,8 @@
 int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
 void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, 
 		u_int16_t mnc, u_int16_t lac);
-enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra);
-enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra);
+enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
+enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
 
 int gsm48_tx_mm_info(struct gsm_lchan *lchan);
 int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 3040525..c1b7b05 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -410,6 +410,7 @@
 	char *name_short;
 	enum gsm_auth_policy auth_policy;
 	int a5_encryption;
+	int neci;
 
 	/* layer 4 */
 	int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg);
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index de0f484..2d00603 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -1133,8 +1133,8 @@
 
 	/* determine channel type (SDCCH/TCH_F/TCH_H) based on
 	 * request reference RA */
-	lctype = get_ctype_by_chreq(bts, rqd_ref->ra);
-	chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra);
+	lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci);
+	chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci);
 
 	/* check availability / allocate channel */
 	lchan = lchan_alloc(bts, lctype);
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index bb1e382..d11cde5 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -956,6 +956,10 @@
 	type_4->cell_sel_par.ms_txpwr_max_ccch =
 			ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
 
+	/* Set NECI to influence channel request */
+	type_3->cell_sel_par.neci = bts->network->neci;
+	type_4->cell_sel_par.neci = bts->network->neci;
+
 	if (bts->cell_barred) {
 		type_1->rach_control.cell_bar = 1;
 		type_2->rach_control.cell_bar = 1;
diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c
index 2545f33..0e242b7 100644
--- a/openbsc/src/gsm_04_08_utils.c
+++ b/openbsc/src/gsm_04_08_utils.c
@@ -302,13 +302,13 @@
 	[CHREQ_T_PAG_R_TCH_FH]		= GSM_CHREQ_REASON_PAG,
 };
 
-enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra)
+enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci)
 {
 	int i;
 	/* FIXME: determine if we set NECI = 0 in the BTS SI4 */
 
 	for (i = 0; i < ARRAY_SIZE(chreq_type_neci0); i++) {
-		const struct chreq *chr = &chreq_type_neci0[i];
+		const struct chreq *chr = neci ? &chreq_type_neci1[i] : &chreq_type_neci0[i];
 		if ((ra & chr->mask) == chr->val)
 			return ctype_by_chreq[chr->type];
 	}
@@ -316,13 +316,13 @@
 	return GSM_LCHAN_SDCCH;
 }
 
-enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra)
+enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci)
 {
 	int i;
 	/* FIXME: determine if we set NECI = 0 in the BTS SI4 */
 
 	for (i = 0; i < ARRAY_SIZE(chreq_type_neci0); i++) {
-		const struct chreq *chr = &chreq_type_neci0[i];
+		const struct chreq *chr = neci ? &chreq_type_neci1[i] : &chreq_type_neci0[i];
 		if ((ra & chr->mask) == chr->val)
 			return reason_by_chreq[chr->type];
 	}
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 894146b..54c9d5c 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -87,6 +87,8 @@
 		gsm_auth_policy_name(net->auth_policy), VTY_NEWLINE);
 	vty_out(vty, "  Encryption: A5/%u%s", net->a5_encryption,
 		VTY_NEWLINE);
+	vty_out(vty, "  NECI (TCH/H): %u%s", net->neci,
+		VTY_NEWLINE);
 }
 
 DEFUN(show_net, show_net_cmd, "show network",
@@ -789,6 +791,15 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_net_neci,
+      cfg_net_neci_cmd,
+      "neci (0|1)",
+      "Set if NECI of cell selection is to be set")
+{
+	gsmnet->neci = atoi(argv[0]);
+	return CMD_SUCCESS;
+}
+
 /* per-BTS configuration */
 DEFUN(cfg_bts,
       cfg_bts_cmd,
@@ -1228,6 +1239,7 @@
 	install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
 	install_element(GSMNET_NODE, &cfg_net_auth_policy_cmd);
 	install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
+	install_element(GSMNET_NODE, &cfg_net_neci_cmd);
 
 	install_element(GSMNET_NODE, &cfg_bts_cmd);
 	install_node(&bts_node, config_write_bts);