mgcp: Merge OpenBSC MGCP code and update the structure to match it

* Upstream has a separation of BTS and NET side for RTP ports and
  can allocate them dynamically.
* Upstream has gained the concept of trunks. We will now have various
  trunks to connect audio things.

* We will now be able to utilize multiple trunks and have the endpoints
  used properly.
diff --git a/include/mgcp/mgcp.h b/include/mgcp/mgcp.h
index 71e45f3..675db0c 100644
--- a/include/mgcp/mgcp.h
+++ b/include/mgcp/mgcp.h
@@ -1,13 +1,13 @@
 /* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
 
 /*
- * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2010 by On-Waves
+ * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2011 by On-Waves
  * All Rights Reserved
  *
- * This program is free software: you can redistribute it and/or modify
+ * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -23,11 +23,15 @@
 #ifndef OPENBSC_MGCP_H
 #define OPENBSC_MGCP_H
 
+#include "cellmgr_debug.h"
+
 #include <osmocore/msgb.h>
+#include <osmocore/write_queue.h>
 
 #include <arpa/inet.h>
 
 #define RTP_PORT_DEFAULT 4000
+#define RTP_PORT_NET_DEFAULT 16000
 
 /**
  * Calculate the RTP audio port for the given multiplex
@@ -59,6 +63,7 @@
  */
 struct mgcp_endpoint;
 struct mgcp_config;
+struct mgcp_trunk_config;
 
 #define MGCP_ENDP_CRCX 1
 #define MGCP_ENDP_DLCX 2
@@ -74,51 +79,113 @@
 #define MGCP_POLICY_REJECT	5
 #define MGCP_POLICY_DEFER	6
 
-typedef int (*mgcp_realloc)(struct mgcp_config *cfg, int endpoint);
-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);
+typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint);
+typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state);
+typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id);
 typedef int (*mgcp_reset)(struct mgcp_config *cfg);
 
+#define PORT_ALLOC_STATIC	0
+#define PORT_ALLOC_DYNAMIC	1
+
+/**
+ * This holds information on how to allocate ports
+ */
+struct mgcp_port_range {
+	int mode;
+
+	/* pre-allocated from a base? */
+	int base_port;
+
+	/* dynamically allocated */
+	int range_start;
+	int range_end;
+	int last_port;
+};
+
+struct mgcp_trunk_config {
+	struct llist_head entry;
+
+	struct mgcp_config *cfg;
+
+	int trunk_nr;
+	int trunk_type;
+
+	char *audio_name;
+	int audio_payload;
+	int audio_loop;
+
+	/* spec handling */
+	int force_realloc;
+
+	unsigned int number_endpoints;
+	struct mgcp_endpoint *endpoints;
+
+	/* Special MGW handling */
+	int target_trunk_start;
+	int trunk_base;
+	int endp_offset;
+	int vad_enabled;
+
+	int digital_inp_gain;
+	int digital_out_gain;
+	int upstr_agc_enbl;
+	int upstr_adp_rate;
+	int upstr_max_gain;
+	int upstr_target_lvl;
+	int dwnstr_agc_enbl;
+	int dwnstr_adp_rate;
+	int dwnstr_max_gain;
+	int dwnstr_target_lvl;
+};
+
 struct mgcp_config {
 	int source_port;
 	char *local_ip;
 	char *source_addr;
-	unsigned int number_endpoints;
 	char *bts_ip;
 	char *call_agent_addr;
 
 	struct in_addr bts_in;
-	char *audio_name;
-	int audio_payload;
-	int audio_loop;
-	int early_bind;
-	int rtp_base_port;
+
+	/* transcoder handling */
+	char *transcoder_ip;
+	struct in_addr transcoder_in;
+	int transcoder_remote_base;
+
+	struct write_queue gw_fd;
+
+	struct mgcp_port_range bts_ports;
+	struct mgcp_port_range net_ports;
+	struct mgcp_port_range transcoder_ports;
 	int endp_dscp;
 
-	char *forward_ip;
-	int forward_port;
-
-	/* spec handling */
-	int force_realloc;
-
 	mgcp_change change_cb;
 	mgcp_policy policy_cb;
 	mgcp_reset reset_cb;
 	mgcp_realloc realloc_cb;
 	void *data;
 
-	struct mgcp_endpoint *endpoints;
 	uint32_t last_call_id;
+
+	/* trunk handling */
+	struct mgcp_trunk_config trunk;
+	struct llist_head trunks;
+
+	/* only used for start with a static configuration */
+	int last_net_port;
+	int last_bts_port;
+
+	/* MGW handling */
+	int configure_trunks;
 };
 
 /* config management */
 struct mgcp_config *mgcp_config_alloc(void);
 int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg);
 int mgcp_vty_init(void);
-void mgcp_vty_set_config(struct mgcp_config *cfg);
-int mgcp_endpoints_allocate(struct mgcp_config *cfg);
-int mgcp_bind_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
+int mgcp_endpoints_allocate(struct mgcp_trunk_config *cfg);
 void mgcp_free_endp(struct mgcp_endpoint *endp);
+int mgcp_reset_transcoder(struct mgcp_config *cfg);
 
 /*
  * format helper functions
@@ -129,9 +196,18 @@
 /* adc helper */
 static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
 {
-	if (timeslot == 0)
-		timeslot = 1;
-	return timeslot + (31 * multiplex);
+	if (timeslot == 0) {
+		LOGP(DMGCP, LOGL_ERROR, "Timeslot should not be 0\n");
+		timeslot = 255;
+	}
+
+	return timeslot + (32 * multiplex);
+}
+
+static inline void mgcp_endpoint_to_timeslot(int endpoint, int *multiplex, int *timeslot)
+{
+	*multiplex = endpoint / 32;
+	*timeslot = endpoint % 32;
 }