Merge branch 'master' into sms
diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h
index c065f90..b41182d 100644
--- a/openbsc/include/openbsc/signal.h
+++ b/openbsc/include/openbsc/signal.h
@@ -55,6 +55,7 @@
 	S_NM_SW_ACTIV_REP,	/* GSM 12.21 software activated report */
 	S_NM_FAIL_REP,		/* GSM 12.21 failure event report */
 	S_NM_NACK,		/* GSM 12.21 various NM_MT_*_NACK happened */
+	S_NM_IPACC_NACK,	/* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_NACK happened */
 };
 
 /* SS_LCHAN signals */
diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c
index 0ec0640..7e016db 100644
--- a/openbsc/src/abis_nm.c
+++ b/openbsc/src/abis_nm.c
@@ -2309,6 +2309,18 @@
 		DEBUGPC(DNM, "unknown\n");
 		break;
 	}
+
+	/* signal handling */
+	switch  (foh->msg_type) {
+	case NM_MT_IPACC_RSL_CONNECT_NACK:
+	case NM_MT_IPACC_SET_NVATTR_NACK:
+	case NM_MT_IPACC_GET_NVATTR_NACK:
+		dispatch_signal(SS_NM, S_NM_IPACC_NACK, (void*) ((long)foh->msg_type));
+		break;
+	default:
+		break;
+	}
+
 	return 0;
 }
 
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index 3495e6c..a5b9a90 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -1352,7 +1352,7 @@
 }
 
 
-/* Section 3.3.2.3 . I think this looks like a table */
+/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
 int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
 {
 	switch (ccch_conf) {
@@ -1371,6 +1371,7 @@
 	}
 }
 
+/* Section 3.3.2.3 TS 05.02 */
 int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
 {
 	switch (ccch_conf) {
diff --git a/openbsc/src/ipaccess-config.c b/openbsc/src/ipaccess-config.c
index 8c52093..52e9cc9 100644
--- a/openbsc/src/ipaccess-config.c
+++ b/openbsc/src/ipaccess-config.c
@@ -37,6 +37,7 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/e1_input.h>
 #include <openbsc/abis_nm.h>
+#include <openbsc/signal.h>
 
 static struct gsm_network *gsmnet;
 
@@ -51,6 +52,33 @@
 static u_int8_t unit_id_attr[] = { 0x91, 0x00, 9, '2', '3', '4', '2', '/' , '0', '/', '0', 0x00 };
 */
 
+/*
+ * Callback function for NACK on the OML NM
+ *
+ * Currently we send the config requests but don't check the
+ * result. The nanoBTS will send us a NACK when we did something the
+ * BTS didn't like.
+ */
+static int ipacc_msg_nack(int mt)
+{
+	fprintf(stderr, "Failure to set attribute. This seems fatal\n");
+	exit(-1);
+	return 0;
+}
+
+static int nm_sig_cb(unsigned int subsys, unsigned int signal,
+		     void *handler_data, void *signal_data)
+{
+	switch (signal) {
+	case S_NM_IPACC_NACK:
+		return ipacc_msg_nack((int)signal_data);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static void bootstrap_om(struct gsm_bts *bts)
 {
 	int len;
@@ -145,6 +173,20 @@
 	return 0;
 }
 
+static void print_usage(void)
+{
+	printf("Usage: ipaccess-config\n");
+}
+
+static void print_help(void)
+{
+	printf("  -u --unit-id UNIT_ID\n");
+	printf("  -o --oml-ip ip\n");
+	printf("  -r --restart\n");
+	printf("  -n flags/mask Set NVRAM attributes.\n");
+	printf("  -h --help this text\n");
+}
+
 int main(int argc, char **argv)
 {
 	struct gsm_bts *bts;
@@ -162,9 +204,10 @@
 			{ "unit-id", 1, 0, 'u' },
 			{ "oml-ip", 1, 0, 'o' },
 			{ "restart", 0, 0, 'r' },
+			{ "help", 0, 0, 'h' },
 		};
 
-		c = getopt_long(argc, argv, "u:o:rn:", long_options,
+		c = getopt_long(argc, argv, "u:o:rn:h", long_options,
 				&option_index);
 
 		if (c == -1)
@@ -189,11 +232,15 @@
 			ul = strtoul(slash+1, NULL, 16);
 			nv_mask = ul & 0xffff;
 			break;
+		case 'h':
+			print_usage();
+			print_help();
+			exit(0);
 		}
 	};
 
 	if (optind >= argc) {
-		fprintf(stderr, "you have to specify the IP address of the BTS\n");
+		fprintf(stderr, "you have to specify the IP address of the BTS. Use --help for more information\n");
 		exit(2);
 	}
 
@@ -204,6 +251,7 @@
 	bts = gsm_bts_alloc(gsmnet, GSM_BTS_TYPE_NANOBTS_900, HARDCODED_TSC,
 				HARDCODED_BSIC);
 	
+	register_signal_handler(SS_NM, nm_sig_cb, NULL);
 	printf("Trying to connect to ip.access BTS ...\n");
 
 	memset(&sin, 0, sizeof(sin));