Gracefully reject non-speech calls

As we currently really only deal with voice/speech calls and don't
support FAX and DATA (CSD) calls, we now gracefully reject them.
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index a1fa546..e1374c9 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -439,18 +439,29 @@
 	bcap->coding = (lv[1] & 0x10) >> 4;
 	bcap->radio = (lv[1] & 0x60) >> 5;
 
-	i = 1;
-	s = 0;
-	while(!(lv[i] & 0x80)) {
-		i++; /* octet 3a etc */
-		if (in_len < i)
-			return 0;
-		bcap->speech_ver[s++] = lv[i] & 0x0f;
-		bcap->speech_ver[s] = -1; /* end of list */
-		if (i == 2) /* octet 3a */
-			bcap->speech_ctm = (lv[i] & 0x20) >> 5;
-		if (s == 7) /* maximum speech versions + end of list */
-			return 0;
+	if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) {
+		i = 1;
+		s = 0;
+		while(!(lv[i] & 0x80)) {
+			i++; /* octet 3a etc */
+			if (in_len < i)
+				return 0;
+			bcap->speech_ver[s++] = lv[i] & 0x0f;
+			bcap->speech_ver[s] = -1; /* end of list */
+			if (i == 2) /* octet 3a */
+				bcap->speech_ctm = (lv[i] & 0x20) >> 5;
+			if (s == 7) /* maximum speech versions + end of list */
+				return 0;
+		}
+	} else {
+		i = 1;
+		while (!(lv[i] & 0x80)) {
+			i++; /* octet 3a etc */
+			if (in_len < i)
+				return 0;
+			/* ignore them */
+		}
+		/* FIXME: implement OCTET 4+ parsing */
 	}
 
 	return 0;
@@ -461,21 +472,24 @@
 			     const struct gsm_mncc_bearer_cap *bcap)
 {
 	u_int8_t lv[32 + 1];
-	int i, s;
+	int i = 1, s;
 
 	lv[1] = bcap->transfer;
 	lv[1] |= bcap->mode << 3;
 	lv[1] |= bcap->coding << 4;
 	lv[1] |= bcap->radio << 5;
 
-	i = 1;
-	for (s = 0; bcap->speech_ver[s] >= 0; s++) {
-		i++; /* octet 3a etc */
-		lv[i] = bcap->speech_ver[s];
-		if (i == 2) /* octet 3a */
-			lv[i] |= bcap->speech_ctm << 5;
+	if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) {
+		for (s = 0; bcap->speech_ver[s] >= 0; s++) {
+			i++; /* octet 3a etc */
+			lv[i] = bcap->speech_ver[s];
+			if (i == 2) /* octet 3a */
+				lv[i] |= bcap->speech_ctm << 5;
+		}
+		lv[i] |= 0x80; /* last IE of octet 3 etc */
+	} else {
+		/* FIXME: implement OCTET 4+ encoding */
 	}
-	lv[i] |= 0x80; /* last IE of octet 3 etc */
 
 	lv[0] = i;
 	if (lv_only)
diff --git a/openbsc/src/mncc.c b/openbsc/src/mncc.c
index f62541c..de17657 100644
--- a/openbsc/src/mncc.c
+++ b/openbsc/src/mncc.c
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #include <sys/types.h>
 
 #include <openbsc/gsm_04_08.h>
@@ -136,19 +137,36 @@
 	struct gsm_mncc mncc;
 	struct gsm_call *remote;
 
+	memset(&mncc, 0, sizeof(struct gsm_mncc));
+	mncc.callref = call->callref;
+
 	/* already have remote call */
 	if (call->remote_ref)
 		return 0;
 	
+	/* transfer mode 1 would be packet mode, which was never specified */
+	if (setup->bearer_cap.mode != 0) {
+		DEBUGP(DMNCC, "(call %x) We don't support packet mode\n",
+			call->callref);
+		mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
+		goto out_reject;
+	}
+
+	/* we currently only do speech */
+	if (setup->bearer_cap.transfer != GSM_MNCC_BCAP_SPEECH) {
+		DEBUGP(DMNCC, "(call %x) We only support voice calls\n",
+			call->callref);
+		mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
+		goto out_reject;
+	}
+
 	/* create remote call */
 	if (!(remote = talloc(tall_call_ctx, struct gsm_call))) {
-		memset(&mncc, 0, sizeof(struct gsm_mncc));
-		mncc.callref = call->callref;
 		mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
 				GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
-		mncc_send(call->net, MNCC_REJ_REQ, &mncc);
-		free_call(call);
-		return 0;
+		goto out_reject;
 	}
 	llist_add_tail(&remote->entry, &call_list);
 	remote->net = call->net;
@@ -179,6 +197,11 @@
 	setup->callref = remote->callref;
 	DEBUGP(DMNCC, "(call %x) Forwarding SETUP to remote.\n", call->callref);
 	return mncc_send(remote->net, MNCC_SETUP_REQ, setup);
+
+out_reject:
+	mncc_send(call->net, MNCC_REJ_REQ, &mncc);
+	free_call(call);
+	return 0;
 }
 
 static int mncc_alert_ind(struct gsm_call *call, int msg_type,