introduce and implement silent_call_reroute() and silent_call_rx()

Thise two functions are interfacing with the 04.08 layer 3 to
determine if a particular message should be handled inside
the OpenBSC layer 3, or if it should be handled in the silent call
handler.
diff --git a/openbsc/src/silent_call.c b/openbsc/src/silent_call.c
index 500d187..2679db7 100644
--- a/openbsc/src/silent_call.c
+++ b/openbsc/src/silent_call.c
@@ -34,6 +34,7 @@
 #include <openbsc/abis_rsl.h>
 #include <openbsc/chan_alloc.h>
 
+/* paging of the requested subscriber has completed */
 static int paging_cb_silent(unsigned int hooknum, unsigned int event,
 			    struct msgb *msg, void *_lchan, void *_data)
 {
@@ -70,6 +71,48 @@
 	return rc;
 }
 
+/* receive a layer 3 message from a silent call */
+int silent_call_rx(struct msgb *msg)
+{
+	/* FIXME: do something like sending it through a UDP port */
+	return 0;
+}
+
+struct msg_match {
+	u_int8_t pdisc;
+	u_int8_t msg_type;
+};
+
+/* list of messages that are handled inside OpenBSC, even in a silent call */
+static const struct msg_match silent_call_accept[] = {
+	{ GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST },
+	{ GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_REQ },
+};
+
+/* decide if we need to reroute a message as part of a silent call */
+int silent_call_reroute(struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	u_int8_t pdisc = gh->proto_discr & 0x0f;
+	int i;
+
+	/* if we're not part of a silent call, never reroute */
+	if (!msg->lchan->silent_call)
+		return 0;
+
+	/* check if we are a special message that is handled in openbsc */
+	for (i = 0; i < ARRAY_SIZE(silent_call_accept); i++) {
+		if (silent_call_accept[i].pdisc == pdisc &&
+		    silent_call_accept[i].msg_type == gh->msg_type)
+			return 0;
+	}
+
+	/* otherwise, reroute */
+	return 1;
+}
+
+
+/* initiate a silent call with a given subscriber */
 int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data)
 {
 	int rc;
@@ -79,6 +122,7 @@
 	return rc;
 }
 
+/* end a silent call with a given subscriber */
 int gsm_silent_call_stop(struct gsm_subscriber *subscr)
 {
 	struct gsm_lchan *lchan;