[mgcp] Introduce a policy CB for the MGCP protocol

The are three policies. Accept, Reject and Defer. This will
allow to handle network connections and such from the policy
callback instead of directly acting on it.
diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h
index fcc4d76..004ae78 100644
--- a/openbsc/include/openbsc/mgcp.h
+++ b/openbsc/include/openbsc/mgcp.h
@@ -65,7 +65,18 @@
 #define MGCP_ENDP_DLCX 2
 #define MGCP_ENDP_MDCX 3
 
+/*
+ * what to do with the msg?
+ *	- continue as usual?
+ *	- reject and send a failure code?
+ *	- defer? do not send anything
+ */
+#define MGCP_POLICY_CONT	4
+#define MGCP_POLICY_REJECT	5
+#define MGCP_POLICY_DEFER	6
+
 typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp);
+typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id);
 
 struct mgcp_config {
 	int source_port;
@@ -85,6 +96,8 @@
 	int forward_port;
 
 	mgcp_change change_cb;
+	mgcp_policy policy_cb;
+	void *data;
 
 	struct mgcp_endpoint *endpoints;
 	unsigned int last_call_id;
diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c
index 0fe33dd..bd47f8c 100644
--- a/openbsc/src/mgcp/mgcp_protocol.c
+++ b/openbsc/src/mgcp/mgcp_protocol.c
@@ -455,6 +455,25 @@
 	if (endp->ci == CI_UNUSED)
 		goto error2;
 
+	/* policy CB */
+	if (cfg->policy_cb) {
+		switch (cfg->policy_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX, trans_id)) {
+		case MGCP_POLICY_REJECT:
+			LOGP(DMGCP, LOGL_NOTICE, "CRCX rejected by policy on 0x%x\n",
+			     ENDPOINT_NUMBER(endp));
+			mgcp_free_endp(endp);
+			return create_response(500, "CRCX", trans_id);
+			break;
+		case MGCP_POLICY_DEFER:
+			/* stop processing */
+			return NULL;
+			break;
+		case MGCP_POLICY_CONT:
+			/* just continue */
+			break;
+		}
+	}
+
 	LOGP(DMGCP, LOGL_NOTICE, "Creating endpoint on: 0x%x CI: %u port: %u\n",
 		ENDPOINT_NUMBER(endp), endp->ci, endp->rtp_port);
 	if (cfg->change_cb)
@@ -548,6 +567,24 @@
 	}
 	MSG_TOKENIZE_END
 
+	/* policy CB */
+	if (cfg->policy_cb) {
+		switch (cfg->policy_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX, trans_id)) {
+		case MGCP_POLICY_REJECT:
+			LOGP(DMGCP, LOGL_NOTICE, "MDCX rejected by policy on 0x%x\n",
+			     ENDPOINT_NUMBER(endp));
+			return create_response(500, "MDCX", trans_id);
+			break;
+		case MGCP_POLICY_DEFER:
+			/* stop processing */
+			return NULL;
+			break;
+		case MGCP_POLICY_CONT:
+			/* just continue */
+			break;
+		}
+	}
+
 	/* modify */
 	LOGP(DMGCP, LOGL_NOTICE, "Modified endpoint on: 0x%x Server: %s:%u\n",
 		ENDPOINT_NUMBER(endp), inet_ntoa(endp->remote), ntohs(endp->net_rtp));
@@ -602,6 +639,24 @@
 	}
 	MSG_TOKENIZE_END
 
+	/* policy CB */
+	if (cfg->policy_cb) {
+		switch (cfg->policy_cb(cfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_DLCX, trans_id)) {
+		case MGCP_POLICY_REJECT:
+			LOGP(DMGCP, LOGL_NOTICE, "DLCX rejected by policy on 0x%x\n",
+			     ENDPOINT_NUMBER(endp));
+			return create_response(500, "DLCX", trans_id);
+			break;
+		case MGCP_POLICY_DEFER:
+			/* stop processing */
+			return NULL;
+			break;
+		case MGCP_POLICY_CONT:
+			/* just continue */
+			break;
+		}
+	}
+
 	/* free the connection */
 	mgcp_free_endp(endp);
 	if (cfg->change_cb)