bsc_api: Move gsm48_rcvmsg into the BSC API and dispatch.

The next step in the way to the BSC API. We have a clear a
new connection was opened signal now... and the MSC could
use it...
diff --git a/openbsc/include/openbsc/bsc_api.h b/openbsc/include/openbsc/bsc_api.h
index 7747ada..e92da21 100644
--- a/openbsc/include/openbsc/bsc_api.h
+++ b/openbsc/include/openbsc/bsc_api.h
@@ -5,12 +5,16 @@
 
 #include "gsm_data.h"
 
+#define BSC_API_CONN_POL_ACCEPT	0
+#define BSC_API_CONN_POL_REJECT	1
+
 struct bsc_api {
 	void (*sapi_n_reject)(struct gsm_subscriber_connection *conn, int dlci);
 	void (*cipher_mode_compl)(struct gsm_subscriber_connection *conn,
 				  struct msgb *msg, uint16_t ind);
-	void (*compl_l3)(struct gsm_subscriber_connection *conn,
-			 struct msgb *msg, uint16_t chosen_channel); 
+	int (*compl_l3)(struct gsm_subscriber_connection *conn,
+			struct msgb *msg, uint16_t chosen_channel); 
+	void (*dtap)(struct gsm_subscriber_connection *conn, struct msgb *msg);
 	void (*ass_compl)(struct gsm_subscriber_connection *conn,
 			  uint16_t rr_cause);
 	void (*ass_fail)(struct gsm_subscriber_connection *conn,
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index 11bca54..3fbc35f 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -25,6 +25,7 @@
 /* config options controlling the behaviour of the lower leves */
 void gsm0408_allow_everyone(int allow);
 void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
+int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
 
 int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
 enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
diff --git a/openbsc/include/openbsc/gsm_04_11.h b/openbsc/include/openbsc/gsm_04_11.h
index 61eaffd..d62a392 100644
--- a/openbsc/include/openbsc/gsm_04_11.h
+++ b/openbsc/include/openbsc/gsm_04_11.h
@@ -25,7 +25,7 @@
 
 struct msgb;
 
-int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, struct msgb *msg, u_int8_t link_id);
+int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, struct msgb *msg);
 
 struct gsm_sms *sms_alloc(void);
 void sms_free(struct gsm_sms *sms);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index f3f4ed3..bb790bc 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -254,6 +254,7 @@
 	int silent_call;
 
 	/* back pointers */
+	int allocated;
 	struct gsm_lchan *lchan;
 	struct gsm_bts *bts;
 };
diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c
index 28fc324..02fc473 100644
--- a/openbsc/src/bsc_api.c
+++ b/openbsc/src/bsc_api.c
@@ -27,6 +27,7 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/signal.h>
 #include <openbsc/abis_rsl.h>
+#include <openbsc/chan_alloc.h>
 
 #include <osmocore/talloc.h>
 
@@ -84,6 +85,27 @@
 	return work;
 }
 
+int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
+{
+	int rc;
+	struct gsm_subscriber_connection *conn;
+	struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
+
+	conn = &msg->lchan->conn;
+	if (conn->allocated) {
+		api->dtap(conn, msg);
+	} else {
+		/* accept the connection or close the lchan */
+		rc = api->compl_l3(conn, msg, 0);
+		if (rc == BSC_API_CONN_POL_ACCEPT)
+			conn->allocated = 1;
+		else
+			lchan_auto_release(msg->lchan);
+	}
+
+	return 0;
+}
+
 static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id)
 {
 	struct bsc_api *api;
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 9ec2bf9..d9d2f7f 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -3096,8 +3096,8 @@
 	return rc;
 }
 
-/* here we pass in a msgb from the RSL->RLL.  We expect the l3 pointer to be set */
-int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
+/* here we get data from the BSC level... */
+int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
 	u_int8_t pdisc = gh->proto_discr & 0x0f;
@@ -3117,7 +3117,7 @@
 		rc = gsm0408_rcv_rr(msg);
 		break;
 	case GSM48_PDISC_SMS:
-		rc = gsm0411_rcv_sms(&msg->lchan->conn, msg, link_id);
+		rc = gsm0411_rcv_sms(conn, msg);
 		break;
 	case GSM48_PDISC_MM_GPRS:
 	case GSM48_PDISC_SM_GPRS:
diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c
index a9eee83..cb7cf85 100644
--- a/openbsc/src/gsm_04_11.c
+++ b/openbsc/src/gsm_04_11.c
@@ -913,7 +913,7 @@
 
 /* Entry point for incoming GSM48_PDISC_SMS from abis_rsl.c */
 int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn,
-		    struct msgb *msg, u_int8_t link_id)
+		    struct msgb *msg)
 {
 	struct gsm48_hdr *gh = msgb_l3(msg);
 	u_int8_t msg_type = gh->msg_type;
@@ -940,7 +940,7 @@
 		trans->sms.cp_state = GSM411_CPS_IDLE;
 		trans->sms.rp_state = GSM411_RPS_IDLE;
 		trans->sms.is_mt = 0;
-		trans->sms.link_id = link_id;
+		trans->sms.link_id = UM_SAPI_SMS;
 
 		trans->conn = conn;
 		use_subscr_con(trans->conn);
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index 2e8a00d..431e640 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -99,11 +99,6 @@
 void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
 {}
 
-int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
-{
-	return -1;
-}
-
 static void queue_for_msc(struct bsc_msc_connection *con, struct msgb *msg)
 {
 	if (write_queue_enqueue(&nat->msc_con->write_queue, msg) != 0) {
diff --git a/openbsc/src/osmo_msc.c b/openbsc/src/osmo_msc.c
index b647a81..569634d 100644
--- a/openbsc/src/osmo_msc.c
+++ b/openbsc/src/osmo_msc.c
@@ -40,9 +40,25 @@
 	gsm0408_clear_request(conn, cause);
 }
 
+static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
+			uint16_t chosen_channel)
+{
+	gsm0408_dispatch(conn, msg);
+
+	/* TODO: do better */
+	return BSC_API_CONN_POL_ACCEPT;
+}
+
+static void msc_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	gsm0408_dispatch(conn, msg);
+}
+
 static struct bsc_api msc_handler = {
 	.sapi_n_reject = msc_sapi_n_reject,
 	.clear_request = msc_clear_request,
+	.compl_l3 = msc_compl_l3,
+	.dtap  = msc_dtap,
 };
 
 struct bsc_api *msc_bsc_api() {
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index d1db2e4..ecd25c0 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -721,7 +721,3 @@
 	return -1;
 }
 
-int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
-{
-	return -1;
-}