mgw: clean up codec negotiation (sdp)

The codec negotiation via SDP is currently in a neglected state. Also
osmo-mgw does some kind of codec decision wile the SDP is parsed, the
result is information for one codec, even when there are multiple codecs
negotiated. This is problematic because we loose all information about
alternate codecs while we parse. This should be untangled and the
information should be presevered. Also we are not really capable
picking a default. Wehen we do not supply any codec information (not
even LCO), then we should pick a sane default codec.

- separate the codec decision from the sdp parser and concentrate
  codec related code in a separate c file
- add support for multiple codecs in one SDP negotiation
- do not initalize "magic" codec defaults during conn allocation
- do not allow invalid payload types, especially not 255. When
  someone tries to select an invalid payload type, do not fail
  hard, just pick a sane default.
- handle the codec decision in protocol.c, pick a sane default
  codec when no (valid) codec has been negotiated (no LCO, no SDP)

Change-Id: If730d022ba6bdb217ad4e20b3fbbd1114dbb4b8f
Closes: OS#2658
Related: OS#3114
Related: OS#2728
diff --git a/include/osmocom/mgcp/Makefile.am b/include/osmocom/mgcp/Makefile.am
index 7e297e4..65ca670 100644
--- a/include/osmocom/mgcp/Makefile.am
+++ b/include/osmocom/mgcp/Makefile.am
@@ -5,5 +5,6 @@
 	mgcp_stat.h \
 	mgcp_endp.h \
 	mgcp_sdp.h \
+	mgcp_codec.h \
 	debug.h \
 	$(NULL)
diff --git a/include/osmocom/mgcp/mgcp_codec.h b/include/osmocom/mgcp/mgcp_codec.h
new file mode 100644
index 0000000..f8d5e70
--- /dev/null
+++ b/include/osmocom/mgcp/mgcp_codec.h
@@ -0,0 +1,6 @@
+#pragma once
+
+void mgcp_codec_summary(struct mgcp_conn_rtp *conn);
+void mgcp_codec_reset_all(struct mgcp_conn_rtp *conn);
+int mgcp_codec_add(struct mgcp_conn_rtp *conn, int payload_type, const char *audio_name);
+int mgcp_codec_decide(struct mgcp_conn_rtp *conn);
diff --git a/include/osmocom/mgcp/mgcp_common.h b/include/osmocom/mgcp/mgcp_common.h
index d23339f..eb6564f 100644
--- a/include/osmocom/mgcp/mgcp_common.h
+++ b/include/osmocom/mgcp/mgcp_common.h
@@ -82,4 +82,8 @@
 /* A prefix to denote the virtual trunk (RTP on both ends) */
 #define MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK "rtpbridge/"
 
+/* Maximal number of payload types / codecs that can be negotiated via SDP at
+ * at once. */
+#define MGCP_MAX_CODECS 10
+
 #endif
diff --git a/include/osmocom/mgcp/mgcp_internal.h b/include/osmocom/mgcp/mgcp_internal.h
index bff7da0..b564905 100644
--- a/include/osmocom/mgcp/mgcp_internal.h
+++ b/include/osmocom/mgcp/mgcp_internal.h
@@ -114,12 +114,19 @@
 	/* in network byte order */
 	int rtp_port, rtcp_port;
 
-	/* audio codec information */
-	struct mgcp_rtp_codec codec;
+	/* currently selected audio codec */
+	struct mgcp_rtp_codec *codec;
+
+	/* array with assigned audio codecs to choose from (SDP) */
+	struct mgcp_rtp_codec codecs[MGCP_MAX_CODECS];
+
+	/* number of assigned audio codecs (SDP) */
+	unsigned int codecs_assigned;
 
 	/* per endpoint data */
 	int  frames_per_packet;
 	uint32_t packet_duration_ms;
+	int maximum_packet_time; /* -1: not set */
 	char *fmtp_extra;
 	/* are we transmitting packets (1) or dropping (0) outbound packets */
 	int output_enabled;
diff --git a/include/osmocom/mgcp/mgcp_sdp.h b/include/osmocom/mgcp/mgcp_sdp.h
index 240f8cf..950092e 100644
--- a/include/osmocom/mgcp/mgcp_sdp.h
+++ b/include/osmocom/mgcp/mgcp_sdp.h
@@ -26,9 +26,6 @@
 			struct mgcp_conn_rtp *conn,
 			struct mgcp_parse_data *p);
 
-int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
-			int payload_type, const char *audio_name);
-
 int mgcp_write_response_sdp(const struct mgcp_endpoint *endp,
 			    const struct mgcp_conn_rtp *conn, struct msgb *sdp,
 			    const char *addr);