Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/4905

to look at the new patch set (#2).

libosmo-mgcp: Connection Identifiers are allocated by MGW, not CA

The MGCP connection identifier is allocated by the MGW while processing
the CRCX, see RFC3435 2.1.3.2:. Including/Accepting a connection
identifier in CRCX is "forbidden" as per RFC3435 Section 3.2.2.

So the MGW side must *reject* a CRCX message with 'I' parameter, and
allocate a connection identifier which is subsequently returned in the
response.

Closes: OS#2648
Change-Id: Iab6a6038e7610c62f34e642cd49c93d11151252c
---
M configure.ac
M include/osmocom/mgcp/mgcp_conn.h
M src/libosmo-mgcp-client/mgcp_client.c
M src/libosmo-mgcp/Makefile.am
M src/libosmo-mgcp/mgcp_conn.c
M src/libosmo-mgcp/mgcp_protocol.c
M tests/mgcp/mgcp_test.c
M tests/mgcp/mgcp_test.ok
8 files changed, 953 insertions(+), 162 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/05/4905/2

diff --git a/configure.ac b/configure.ac
index f72b9e1..606f404 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,6 +40,7 @@
 
 
 PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.10.0)
+PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.10.0)
 PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.10.0)
 PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.1.0)
 
diff --git a/include/osmocom/mgcp/mgcp_conn.h b/include/osmocom/mgcp/mgcp_conn.h
index 982a311..e2a423f 100644
--- a/include/osmocom/mgcp/mgcp_conn.h
+++ b/include/osmocom/mgcp/mgcp_conn.h
@@ -28,8 +28,7 @@
 #include <inttypes.h>
 
 struct mgcp_conn *mgcp_conn_alloc(void *ctx, struct mgcp_endpoint *endp,
-                                 const char *id, enum mgcp_conn_type type,
-                                 char *name);
+                                 enum mgcp_conn_type type, char *name);
 struct mgcp_conn *mgcp_conn_get(struct mgcp_endpoint *endp, const char *id);
 struct mgcp_conn_rtp *mgcp_conn_get_rtp(struct mgcp_endpoint *endp,
                                        const char *id);
diff --git a/src/libosmo-mgcp-client/mgcp_client.c 
b/src/libosmo-mgcp-client/mgcp_client.c
index ad972de..3517842 100644
--- a/src/libosmo-mgcp-client/mgcp_client.c
+++ b/src/libosmo-mgcp-client/mgcp_client.c
@@ -258,6 +258,59 @@
        return 0;
 }
 
+/* Parse a line like "I: 0cedfd5a19542d197af9afe5231f1d61" */
+static int mgcp_parse_conn_id(struct mgcp_response *r, const char *line)
+{
+       if (strlen(line) < 4)
+               goto response_parse_failure;
+
+       if (memcmp("I: ", line, 3) != 0)
+               goto response_parse_failure;
+
+       strncpy(r->head.conn_id, line + 3, sizeof(r->head.conn_id));
+       r->head.conn_id[sizeof(r->head.conn_id) - 1] = '\0';
+       return 0;
+
+response_parse_failure:
+       LOGP(DLMGCP, LOGL_ERROR,
+            "Failed to parse MGCP response (connectionIdentifier)\n");
+       return -EINVAL;
+}
+
+/* Parse MGCP parameters of the response */
+static int parse_head_params(struct mgcp_response *r)
+{
+       char *line;
+       int rc = 0;
+       OSMO_ASSERT(r->body);
+       char *data = r->body;
+       char *data_end = strstr(r->body, "\n\n");
+
+       /* Protect SDP body, for_each_non_empty_line() will
+        * only parse until it hits \0 mark. */
+       if (data_end)
+               *data_end = '\0';
+
+       for_each_non_empty_line(line, data) {
+               switch (line[0]) {
+               case 'I':
+                       rc = mgcp_parse_conn_id(r, line);
+                       if (rc)
+                               goto exit;
+                       break;
+               default:
+                       /* skip unhandled parameters */
+                       break;
+               }
+       }
+exit:
+       /* Restore original state */
+       if (data_end)
+               *data_end = '\n';
+
+       return rc;
+}
+
 static struct mgcp_response_pending *mgcp_client_response_pending_get(
                                         struct mgcp_client *mgcp,
                                         struct mgcp_response *r)
@@ -288,7 +341,13 @@
 
        rc = mgcp_response_parse_head(&r, msg);
        if (rc) {
-               LOGP(DLMGCP, LOGL_ERROR, "Cannot parse MGCP response\n");
+               LOGP(DLMGCP, LOGL_ERROR, "Cannot parse MGCP response (head)\n");
+               return -1;
+       }
+
+       rc = parse_head_params(&r);
+       if (rc) {
+               LOGP(DLMGCP, LOGL_ERROR, "Cannot parse MGCP response (head 
parameters)\n");
                return -1;
        }
 
@@ -650,7 +709,6 @@
 
 #define MGCP_CRCX_MANDATORY (MGCP_MSG_PRESENCE_ENDPOINT | \
                             MGCP_MSG_PRESENCE_CALL_ID | \
-                            MGCP_MSG_PRESENCE_CONN_ID | \
                             MGCP_MSG_PRESENCE_CONN_MODE)
 #define MGCP_MDCX_MANDATORY (MGCP_MSG_PRESENCE_ENDPOINT | \
                             MGCP_MSG_PRESENCE_CONN_ID)
@@ -721,8 +779,7 @@
                rc += msgb_printf(msg, "I: %s\r\n", mgcp_msg->conn_id);
 
        /* Add local connection options */
-       if (mgcp_msg->presence & MGCP_MSG_PRESENCE_CONN_ID
-           && mgcp_msg->verb == MGCP_VERB_CRCX)
+       if (mgcp_msg->verb == MGCP_VERB_CRCX)
                rc += msgb_printf(msg, "L: p:20, a:AMR, nt:IN\r\n");
 
        /* Add mode */
diff --git a/src/libosmo-mgcp/Makefile.am b/src/libosmo-mgcp/Makefile.am
index fce0e1b..a785d62 100644
--- a/src/libosmo-mgcp/Makefile.am
+++ b/src/libosmo-mgcp/Makefile.am
@@ -7,6 +7,7 @@
 AM_CFLAGS = \
        -Wall \
        $(LIBOSMOCORE_CFLAGS) \
+       $(LIBOSMOGSM_CFLAGS) \
        $(LIBOSMOVTY_CFLAGS) \
        $(LIBOSMONETIF_CFLAGS) \
        $(COVERAGE_CFLAGS) \
@@ -14,6 +15,7 @@
 
 AM_LDFLAGS = \
        $(LIBOSMOCORE_LIBS) \
+       $(LIBOSMOGSM_LIBS) \
        $(LIBOSMOVTY_LIBS) \
        $(LIBOSMONETIF_LIBS) \
        $(COVERAGE_LDFLAGS) \
diff --git a/src/libosmo-mgcp/mgcp_conn.c b/src/libosmo-mgcp/mgcp_conn.c
index f77e7e8..f5d2668 100644
--- a/src/libosmo-mgcp/mgcp_conn.c
+++ b/src/libosmo-mgcp/mgcp_conn.c
@@ -25,6 +25,38 @@
 #include <osmocom/mgcp/mgcp_internal.h>
 #include <osmocom/mgcp/mgcp_common.h>
 #include <osmocom/mgcp/mgcp_ep.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <ctype.h>
+
+/* Allocate a new connection identifier. According to RFC3435, they must
+ * be unique only within the scope of the endpoint. */
+static int mgcp_alloc_id(struct mgcp_endpoint *endp, char *id)
+{
+       int i;
+       int k;
+       int rc;
+       uint8_t id_bin[16];
+       char *id_hex;
+
+       for (i = 0; i < 32; i++) {
+               rc = osmo_get_rand_id(id_bin, sizeof(id_bin));
+               if (rc < 0)
+                       return rc;
+
+               id_hex = osmo_hexdump_nospc(id_bin, sizeof(id_bin));
+               for (k = 0; k < strlen(id_hex); k++)
+                       id_hex[k] = toupper(id_hex[k]);
+
+               /* ensure that the generated conn_id is unuque
+                * for the current this endpoint */
+               if (!mgcp_conn_get_rtp(endp, id_hex)) {
+                       strncpy(id, id_hex, MGCP_CONN_ID_MAXLEN);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
 
 /* Reset codec state and free memory */
 static void mgcp_rtp_codec_reset(struct mgcp_rtp_codec *codec)
@@ -78,22 +110,17 @@
  *  \param[in] type connection type (e.g. MGCP_CONN_TYPE_RTP)
  *  \returns pointer to allocated connection, NULL on error */
 struct mgcp_conn *mgcp_conn_alloc(void *ctx, struct mgcp_endpoint *endp,
-                                 const char *id, enum mgcp_conn_type type,
-                                 char *name)
+                                 enum mgcp_conn_type type, char *name)
 {
        struct mgcp_conn *conn;
+       int rc;
+
        OSMO_ASSERT(endp);
-       OSMO_ASSERT(id);
-       OSMO_ASSERT(strlen(id) < MGCP_CONN_ID_MAXLEN);
        OSMO_ASSERT(endp->conns.next != NULL && endp->conns.prev != NULL);
        OSMO_ASSERT(strlen(name) < sizeof(conn->name));
 
        /* Do not allow more then two connections */
        if (llist_count(&endp->conns) >= endp->type->max_conns)
-               return NULL;
-
-       /* Prevent duplicate connection IDs */
-       if (mgcp_conn_get(endp, id))
                return NULL;
 
        /* Create new connection and add it to the list */
@@ -106,7 +133,11 @@
        conn->mode_orig = MGCP_CONN_NONE;
        conn->u.rtp.conn = conn;
        strcpy(conn->name, name);
-       strncpy(conn->id, id, sizeof(conn->id));
+       rc = mgcp_alloc_id(endp, conn->id);
+       if (rc < 0) {
+               talloc_free(conn);
+               return NULL;
+       }
 
        switch (type) {
        case MGCP_CONN_TYPE_RTP:
diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c
index a326f00..17c24b1 100644
--- a/src/libosmo-mgcp/mgcp_protocol.c
+++ b/src/libosmo-mgcp/mgcp_protocol.c
@@ -447,7 +447,7 @@
        char *line;
        int have_sdp = 0, osmux_cid = -1;
        struct mgcp_conn_rtp *conn = NULL;
-        const char *conn_id = NULL;
+       struct mgcp_conn *_conn = NULL;
        char conn_name[512];
 
        LOGP(DLMGCP, LOGL_NOTICE, "CRCX: creating new connection ...\n");
@@ -466,9 +466,6 @@
                        break;
                case 'C':
                        callid = (const char *)line + 3;
-                       break;
-               case 'I':
-                       conn_id = (const char *)line + 3;
                        break;
                case 'M':
                        mode = (const char *)line + 3;
@@ -506,13 +503,6 @@
        if (!mode) {
                LOGP(DLMGCP, LOGL_ERROR,
                     "CRCX: endpoint:%x insufficient parameters, missing 
mode\n",
-                    ENDPOINT_NUMBER(endp));
-               return create_err_response(endp, 400, "CRCX", p->trans);
-       }
-
-       if (!conn_id) {
-               LOGP(DLMGCP, LOGL_ERROR,
-                    "CRCX: endpoint:%x insufficient parameters, missing 
connection id\n",
                     ENDPOINT_NUMBER(endp));
                return create_err_response(endp, 400, "CRCX", p->trans);
        }
@@ -560,32 +550,17 @@
        set_local_cx_options(endp->tcfg->endpoints, &endp->local_options,
                             local_options);
 
-       /* Only accept another connection when the connection ID is different. 
*/
-       if (mgcp_conn_get_rtp(endp, conn_id)) {
-               LOGP(DLMGCP, LOGL_ERROR,
-                    "CRCX: endpoint:%x there is already a connection with id 
%u present!\n",
-                    conn_id, ENDPOINT_NUMBER(endp));
-               if (tcfg->force_realloc) {
-                       /* Ignore the existing connection by just freeing it */
-                       mgcp_conn_free(endp, conn_id);
-               } else {
-                       /* There is already a connection with that ID present,
-                        * leave everything as it is and return with an error. 
*/
-                       return create_err_response(endp, 400, "CRCX", p->trans);
-               }
-       }
-
-       snprintf(conn_name, sizeof(conn_name), "%s-%s", callid, conn_id);
-       mgcp_conn_alloc(NULL, endp, conn_id, MGCP_CONN_TYPE_RTP,
-                       conn_name);
-       conn = mgcp_conn_get_rtp(endp, conn_id);
-       if (!conn) {
+       snprintf(conn_name, sizeof(conn_name), "%s", callid);
+       _conn = mgcp_conn_alloc(NULL, endp, MGCP_CONN_TYPE_RTP, conn_name);
+       if (!_conn) {
                LOGP(DLMGCP, LOGL_ERROR,
                     "CRCX: endpoint:%x unable to allocate RTP connection\n",
                     ENDPOINT_NUMBER(endp));
                goto error2;
 
        }
+       conn = mgcp_conn_get_rtp(endp, _conn->id);
+       OSMO_ASSERT(conn);
 
        if (mgcp_parse_conn_mode(mode, endp, conn->conn) != 0) {
                error_code = 517;
diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c
index e11ee48..db119fe 100644
--- a/tests/mgcp/mgcp_test.c
+++ b/tests/mgcp/mgcp_test.c
@@ -82,27 +82,27 @@
 
 #define MDCX3 \
        "MDCX 18983215 1@mgw MGCP 1.0\r\n" \
-       "I: 1\n"
+       "I: %s\n"
 
 #define MDCX3_RET \
        "200 18983215 OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
-       "m=audio 16002 RTP/AVP 128\r\n" \
-       "a=rtpmap:128 GSM-EFR/8000\r\n" \
+       "m=audio 16002 RTP/AVP 97\r\n" \
+       "a=rtpmap:97 GSM-EFR/8000\r\n" \
        "a=ptime:40\r\n"
 
 #define MDCX3A_RET \
        "200 18983215 OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
@@ -112,15 +112,15 @@
 
 #define MDCX3_FMTP_RET \
        "200 18983215 OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
-       "m=audio 16006 RTP/AVP 128\r\n" \
-       "a=rtpmap:128 GSM-EFR/8000\r\n" \
+       "m=audio 16006 RTP/AVP 97\r\n" \
+       "a=rtpmap:97 GSM-EFR/8000\r\n" \
        "a=fmtp:126 0/1/2\r\n" \
        "a=ptime:40\r\n"
 
@@ -128,11 +128,11 @@
        "MDCX 18983216 1@mgw MGCP 1.0\r\n" \
        "M: sendrecv\r" \
        "C: 2\r\n" \
-       "I: 1\r\n" \
+       "I: %s\r\n" \
        "L: p:20, a:AMR, nt:IN\r\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
        "m=audio 4441 RTP/AVP 99\r\n" \
@@ -141,10 +141,10 @@
 
 #define MDCX4_RET(Ident) \
        "200 " Ident " OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
@@ -154,10 +154,10 @@
 
 #define MDCX4_RO_RET(Ident) \
        "200 " Ident " OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
@@ -169,11 +169,11 @@
        "MDCX 18983217 1@mgw MGCP 1.0\r\n" \
        "M: sendrecv\r" \
        "C: 2\r\n" \
-       "I: 1\r\n" \
+       "I: %s\r\n" \
        "L: p:20-40, a:AMR, nt:IN\r\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
        "m=audio 4441 RTP/AVP 99\r\n" \
@@ -184,11 +184,11 @@
        "MDCX 18983218 1@mgw MGCP 1.0\r\n" \
        "M: sendrecv\r" \
        "C: 2\r\n" \
-       "I: 1\r\n" \
+       "I: %s\r\n" \
        "L: p:20-20, a:AMR, nt:IN\r\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
        "m=audio 4441 RTP/AVP 99\r\n" \
@@ -199,11 +199,11 @@
        "MDCX 18983219 1@mgw MGCP 1.0\r\n" \
        "M: sendrecv\r" \
        "C: 2\r\n" \
-       "I: 1\r\n" \
+       "I: %s\r\n" \
        "L: a:AMR, nt:IN\r\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
        "m=audio 4441 RTP/AVP 99\r\n" \
@@ -214,11 +214,11 @@
        "MDCX 18983220 1@mgw MGCP 1.0\r\n" \
        "M: sendonly\r" \
        "C: 2\r\n" \
-       "I: 1\r\n" \
+       "I: %s\r\n" \
        "L: p:20, a:AMR, nt:IN\r\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
        "m=audio 4441 RTP/AVP 99\r\n" \
@@ -229,7 +229,7 @@
        "MDCX 18983221 1@mgw MGCP 1.0\r\n" \
        "M: recvonly\r" \
        "C: 2\r\n" \
-       "I: 1\r\n" \
+       "I: %s\r\n" \
        "L: p:20, a:AMR, nt:IN\r\n"
 
 #define SHORT2 "CRCX 1"
@@ -242,7 +242,6 @@
        "CRCX 2 1@mgw MGCP 1.0\r\n" \
        "M: recvonly\r\n" \
        "C: 2\r\n" \
-       "I: 1\r\n" \
        "L: p:20\r\n" \
        "\r\n" \
        "v=0\r\n" \
@@ -253,10 +252,10 @@
 
 #define CRCX_RET \
        "200 2 OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
@@ -266,10 +265,10 @@
 
 #define CRCX_RET_NO_RTPMAP \
        "200 2 OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
@@ -278,10 +277,10 @@
 
 #define CRCX_FMTP_RET \
        "200 2 OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
@@ -294,7 +293,6 @@
        "CRCX 2 1@mgw MGCP 1.0\r" \
        "M: recvonly\r" \
        "C: 2\r\n" \
-       "I: 1\n" \
        "\n" \
        "v=0\r" \
        "c=IN IP4 123.12.12.123\r" \
@@ -303,10 +301,10 @@
 
 #define CRCX_ZYN_RET \
        "200 2 OK\r\n" \
-       "I: 1\n" \
+       "I: %s\n" \
        "\n" \
        "v=0\r\n" \
-       "o=- 1 23 IN IP4 0.0.0.0\r\n" \
+       "o=- %s 23 IN IP4 0.0.0.0\r\n" \
        "s=-\r\n" \
        "c=IN IP4 0.0.0.0\r\n" \
        "t=0 0\r\n" \
@@ -316,7 +314,7 @@
 
 #define DLCX \
        "DLCX 7 1@mgw MGCP 1.0\r\n" \
-       "I: 1\r\n" \
+       "I: %s\r\n" \
        "C: 2\r\n"
 
 #define DLCX_RET \
@@ -343,7 +341,6 @@
 
 #define CRCX_MULT_1 \
        "CRCX 2 1@mgw MGCP 1.0\r\n" \
-       "I: 4711\r\n" \
        "M: recvonly\r\n" \
        "C: 2\r\n" \
        "X\r\n" \
@@ -358,7 +355,6 @@
 
 #define CRCX_MULT_2 \
        "CRCX 2 2@mgw MGCP 1.0\r\n" \
-       "I: 90210\r\n" \
        "M: recvonly\r\n" \
        "C: 2\r\n" \
        "X\r\n" \
@@ -374,7 +370,6 @@
 
 #define CRCX_MULT_3 \
        "CRCX 2 3@mgw MGCP 1.0\r\n" \
-       "I: 0815\r\n" \
        "M: recvonly\r\n" \
        "C: 2\r\n" \
        "X\r\n" \
@@ -390,7 +385,6 @@
 
 #define CRCX_MULT_4 \
        "CRCX 2 4@mgw MGCP 1.0\r\n" \
-       "I: 32168\r\n" \
        "M: recvonly\r\n" \
        "C: 2\r\n" \
        "X\r\n" \
@@ -407,7 +401,6 @@
 #define CRCX_MULT_GSM_EXACT \
        "CRCX 259260421 5@mgw MGCP 1.0\r\n" \
        "C: 1355c6041e\r\n" \
-       "I: 3\r\n" \
        "L: p:20, a:GSM, nt:IN\r\n" \
        "M: recvonly\r\n" \
        "\r\n" \
@@ -432,7 +425,7 @@
 #define MDCX_NAT_DUMMY \
        "MDCX 23 5@mgw MGCP 1.0\r\n" \
        "C: 1355c6041e\r\n" \
-       "I: 3\r\n" \
+       "I: %s\r\n" \
        "\r\n" \
        "c=IN IP4 8.8.8.8\r\n" \
        "m=audio 16434 RTP/AVP 255\r\n"
@@ -482,12 +475,20 @@
        {"DLCX", DLCX, DLCX_RET},
 };
 
-static struct msgb *create_msg(const char *str)
+static struct msgb *create_msg(const char *str, const char *conn_id)
 {
        struct msgb *msg;
+       int len;
+
+       printf("creating message from statically defined input:\n");
+       printf("---------8<---------\n%s\n---------8<---------\n", str);
 
        msg = msgb_alloc_headroom(4096, 128, "MGCP msg");
-       int len = sprintf((char *)msg->data, "%s", str);
+       if (conn_id)
+               len = sprintf((char *)msg->data, str, conn_id, conn_id);
+       else
+               len = sprintf((char *)msg->data, "%s", str);
+
        msg->l2h = msgb_put(msg, len);
        return msg;
 }
@@ -554,12 +555,84 @@
                    MGCP_CONN_RECV_SEND);
 }
 
+/* Extract a connection ID from a response (CRCX) */
+static int get_conn_id_from_response(uint8_t *resp, char *conn_id,
+                                    unsigned int conn_id_len)
+{
+       char *conn_id_ptr;
+       int i;
+
+       memset(conn_id, 0, conn_id_len);
+
+       conn_id_ptr = strstr((char *)resp, "I: ");
+       if (!conn_id_ptr)
+               return -EINVAL;
+
+       memcpy(conn_id, conn_id_ptr + 3, 32);
+
+       for (i = 0; i < conn_id_len; i++) {
+               if (conn_id[i] == '\n' || conn_id[i] == '\n')
+                       conn_id[i] = '\0';
+       }
+
+       return 0;
+}
+
+/* Check response, automatically patch connection ID if needed */
+static int check_response(uint8_t *resp, const char *exp_resp)
+{
+       char exp_resp_patched[4096];
+       const char *exp_resp_ptr;
+       char conn_id[256];
+
+       printf("checking response:\n");
+
+       /* If the expected response is intened to be patched
+        * (%s placeholder inside) we will patch it with the
+        * connection identifier we just received from the
+        * real response. This is necessary because the CI
+        * is generated by the mgcp code on CRCX and we can
+        * not know it in advance */
+       if (strstr(exp_resp, "%s")) {
+               if (get_conn_id_from_response(resp, conn_id, sizeof(conn_id)) ==
+                   0) {
+                       sprintf(exp_resp_patched, exp_resp, conn_id, conn_id);
+                       exp_resp_ptr = exp_resp_patched;
+                       printf
+                           ("using message with patched conn_id for 
comparison\n");
+               } else {
+                       printf
+                           ("patching conn_id failed, using message as 
statically defined for comparison\n");
+                       exp_resp_ptr = exp_resp;
+               }
+       } else {
+               printf("using message as statically defined for comparison\n");
+               exp_resp_ptr = exp_resp;
+       }
+
+       if (strcmp((char *)resp, exp_resp_ptr) != 0) {
+               printf("Unexpected response, please check!\n");
+               printf
+                   ("Got:\n---------8<---------\n%s\n---------8<---------\n\n",
+                    resp);
+               printf
+                   
("Expected:\n---------8<---------\n%s\n---------8<---------\n",
+                    exp_resp_ptr);
+               return -EINVAL;
+       }
+
+       printf("Response matches our expectations.\n");
+       return 0;
+}
+
 static void test_messages(void)
 {
        struct mgcp_config *cfg;
        struct mgcp_endpoint *endp;
        int i;
        struct mgcp_conn_rtp *conn = NULL;
+       char conn_id[256];
+       char last_conn_id[256];
 
        cfg = mgcp_config_alloc();
 
@@ -568,6 +641,8 @@
 
        cfg->policy_cb = mgcp_test_policy_cb;
 
+       memset(last_conn_id, 0, sizeof(last_conn_id));
+
        mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
 
        for (i = 0; i < ARRAY_SIZE(tests); i++) {
@@ -575,6 +650,7 @@
                struct msgb *inp;
                struct msgb *msg;
 
+               printf("\n================================================\n");
                printf("Testing %s\n", t->name);
 
                last_endpoint = -1;
@@ -583,7 +659,7 @@
                osmo_talloc_replace_string(cfg, &cfg->trunk.audio_fmtp_extra,
                                           t->extra_fmtp);
 
-               inp = create_msg(t->req);
+               inp = create_msg(t->req, last_conn_id);
                msg = mgcp_handle_message(cfg, inp);
                msgb_free(inp);
                if (!t->exp_resp) {
@@ -592,11 +668,16 @@
                                       (char *)msg->data);
                                OSMO_ASSERT(false);
                        }
-               } else if (strcmp((char *)msg->data, t->exp_resp) != 0) {
-                       printf("%s failed.\nExpected:\n%s\nGot:\n%s\n",
-                              t->name, t->exp_resp, (char *) msg->data);
+               } else if (check_response(msg->data, t->exp_resp) != 0) {
+                       printf("%s failed.\n", t->name);
                        OSMO_ASSERT(false);
                }
+
+               if (msg
+                   && get_conn_id_from_response(msg->data, conn_id,
+                                                sizeof(conn_id)) == 0)
+                       memcpy(last_conn_id, conn_id, sizeof(conn_id));
+
                msgb_free(msg);
 
                if (dummy_packets)
@@ -657,7 +738,7 @@
                }
 
                /* Check detected payload type */
-               if (t->ptype != PTYPE_IGNORE) {
+               if (conn && t->ptype != PTYPE_IGNORE) {
                        OSMO_ASSERT(last_endpoint != -1);
                        endp = &cfg->trunk.endpoints[last_endpoint];
 
@@ -682,6 +763,8 @@
 {
        struct mgcp_config *cfg;
        int i;
+       char conn_id[256];
+       char last_conn_id[256];
 
        cfg = mgcp_config_alloc();
 
@@ -695,24 +778,31 @@
                struct msgb *inp;
                struct msgb *msg;
 
+               printf("\n================================================\n");
                printf("Testing %s\n", t->name);
 
-               inp = create_msg(t->req);
+               inp = create_msg(t->req, last_conn_id);
                msg = mgcp_handle_message(cfg, inp);
 
                msgb_free(inp);
-               if (strcmp((char *)msg->data, t->exp_resp) != 0) {
+               if (check_response(msg->data, t->exp_resp) != 0) {
                        printf("%s failed '%s'\n", t->name, (char *)msg->data);
                        OSMO_ASSERT(false);
                }
+
+               if (msg
+                   && get_conn_id_from_response(msg->data, conn_id,
+                                                sizeof(conn_id)) == 0)
+                       memcpy(last_conn_id, conn_id, sizeof(conn_id));
+
                msgb_free(msg);
 
                /* Retransmit... */
                printf("Re-transmitting %s\n", t->name);
-               inp = create_msg(t->req);
+               inp = create_msg(t->req, last_conn_id);
                msg = mgcp_handle_message(cfg, inp);
                msgb_free(inp);
-               if (strcmp((char *)msg->data, t->exp_resp) != 0) {
+               if (check_response(msg->data, t->exp_resp) != 0) {
                        printf("%s failed '%s'\n", t->name, (char *)msg->data);
                        OSMO_ASSERT(false);
                }
@@ -733,6 +823,7 @@
 {
        struct mgcp_config *cfg;
        struct msgb *inp, *msg;
+       char conn_id[256];
 
        cfg = mgcp_config_alloc();
        cfg->rqnt_cb = rqnt_cb;
@@ -742,12 +833,16 @@
 
        mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
 
-       inp = create_msg(CRCX);
-       msgb_free(mgcp_handle_message(cfg, inp));
+       inp = create_msg(CRCX, NULL);
+       msg = mgcp_handle_message(cfg, inp);
+       OSMO_ASSERT(msg);
+       OSMO_ASSERT(get_conn_id_from_response(msg->data, conn_id,
+                                             sizeof(conn_id)) == 0);
+       msgb_free(msg);
        msgb_free(inp);
 
        /* send the RQNT and check for the CB */
-       inp = create_msg(RQNT);
+       inp = create_msg(RQNT, conn_id);
        msg = mgcp_handle_message(cfg, inp);
        if (strncmp((const char *)msg->l2h, "200", 3) != 0) {
                printf("FAILED: message is not 200. '%s'\n", msg->l2h);
@@ -762,7 +857,7 @@
        msgb_free(msg);
        msgb_free(inp);
 
-       inp = create_msg(DLCX);
+       inp = create_msg(DLCX, conn_id);
        msgb_free(mgcp_handle_message(cfg, inp));
        msgb_free(inp);
        talloc_free(cfg);
@@ -865,7 +960,7 @@
        int loss;
        int rc;
 
-       msg = create_msg(DLCX_RET);
+       msg = create_msg(DLCX_RET, NULL);
        rc = mgcp_parse_stats(msg, &bps, &bos, &pr, &_or, &loss, &jitter);
        printf("Parsing result: %d\n", rc);
        if (bps != 0 || bos != 0 || pr != 0 || _or != 0 || loss != 0
@@ -875,7 +970,7 @@
 
        msg =
            create_msg
-           ("250 7 OK\r\nP: PS=10, OS=20, PR=30, OR=40, PL=-3, JI=40\r\n");
+               ("250 7 OK\r\nP: PS=10, OS=20, PR=30, OR=40, PL=-3, JI=40\r\n", 
NULL);
        rc = mgcp_parse_stats(msg, &bps, &bos, &pr, &_or, &loss, &jitter);
        printf("Parsing result: %d\n", rc);
        if (bps != 10 || bos != 20 || pr != 30 || _or != 40 || loss != -3
@@ -1014,6 +1109,7 @@
        int last_in_ts_err_cnt = 0;
        int last_out_ts_err_cnt = 0;
        struct mgcp_conn_rtp *conn = NULL;
+       struct mgcp_conn *_conn = NULL;
 
        printf("Testing packet error detection%s%s.\n",
               patch_ssrc ? ", patch SSRC" : "",
@@ -1033,9 +1129,10 @@
        endp.tcfg = &trunk;
 
        INIT_LLIST_HEAD(&endp.conns);
-       mgcp_conn_alloc(NULL, &endp, "4711", MGCP_CONN_TYPE_RTP,
-                       "test-connection");
-       conn = mgcp_conn_get_rtp(&endp, "4711");
+       _conn = mgcp_conn_alloc(NULL, &endp, MGCP_CONN_TYPE_RTP,
+                               "test-connection");
+       OSMO_ASSERT(_conn);
+       conn = mgcp_conn_get_rtp(&endp, _conn->id);
        OSMO_ASSERT(conn);
 
        rtp = &conn->end;
@@ -1093,6 +1190,7 @@
        struct msgb *inp, *resp;
        struct in_addr addr;
        struct mgcp_conn_rtp *conn = NULL;
+       char conn_id[256];
 
        printf("Testing multiple payload types\n");
 
@@ -1104,85 +1202,95 @@
 
        /* Allocate endpoint 1@mgw with two codecs */
        last_endpoint = -1;
-       inp = create_msg(CRCX_MULT_1);
+       inp = create_msg(CRCX_MULT_1, NULL);
        resp = mgcp_handle_message(cfg, inp);
+       OSMO_ASSERT(get_conn_id_from_response(resp->data, conn_id,
+                                             sizeof(conn_id)) == 0);
        msgb_free(inp);
        msgb_free(resp);
 
        OSMO_ASSERT(last_endpoint == 1);
        endp = &cfg->trunk.endpoints[last_endpoint];
-       conn = mgcp_conn_get_rtp(endp, "4711");
+       conn = mgcp_conn_get_rtp(endp, conn_id);
        OSMO_ASSERT(conn);
        OSMO_ASSERT(conn->end.codec.payload_type == 18);
        OSMO_ASSERT(conn->end.alt_codec.payload_type == 97);
 
        /* Allocate 2@mgw with three codecs, last one ignored */
        last_endpoint = -1;
-       inp = create_msg(CRCX_MULT_2);
+       inp = create_msg(CRCX_MULT_2, NULL);
        resp = mgcp_handle_message(cfg, inp);
+       OSMO_ASSERT(get_conn_id_from_response(resp->data, conn_id,
+                                             sizeof(conn_id)) == 0);
        msgb_free(inp);
        msgb_free(resp);
 
        OSMO_ASSERT(last_endpoint == 2);
        endp = &cfg->trunk.endpoints[last_endpoint];
-       conn = mgcp_conn_get_rtp(endp, "90210");
+       conn = mgcp_conn_get_rtp(endp, conn_id);
        OSMO_ASSERT(conn);
        OSMO_ASSERT(conn->end.codec.payload_type == 18);
        OSMO_ASSERT(conn->end.alt_codec.payload_type == 97);
 
        /* Allocate 3@mgw with no codecs, check for PT == -1 */
        last_endpoint = -1;
-       inp = create_msg(CRCX_MULT_3);
+       inp = create_msg(CRCX_MULT_3, NULL);
        resp = mgcp_handle_message(cfg, inp);
+       OSMO_ASSERT(get_conn_id_from_response(resp->data, conn_id,
+                                             sizeof(conn_id)) == 0);
        msgb_free(inp);
        msgb_free(resp);
 
        OSMO_ASSERT(last_endpoint == 3);
        endp = &cfg->trunk.endpoints[last_endpoint];
-       conn = mgcp_conn_get_rtp(endp, "0815");
+       conn = mgcp_conn_get_rtp(endp, conn_id);
        OSMO_ASSERT(conn);
        OSMO_ASSERT(conn->end.codec.payload_type == -1);
        OSMO_ASSERT(conn->end.alt_codec.payload_type == -1);
 
        /* Allocate 4@mgw with a single codec */
        last_endpoint = -1;
-       inp = create_msg(CRCX_MULT_4);
+       inp = create_msg(CRCX_MULT_4, NULL);
        resp = mgcp_handle_message(cfg, inp);
+       OSMO_ASSERT(get_conn_id_from_response(resp->data, conn_id,
+                                             sizeof(conn_id)) == 0);
        msgb_free(inp);
        msgb_free(resp);
 
        OSMO_ASSERT(last_endpoint == 4);
        endp = &cfg->trunk.endpoints[last_endpoint];
-       conn = mgcp_conn_get_rtp(endp, "32168");
+       conn = mgcp_conn_get_rtp(endp, conn_id);
        OSMO_ASSERT(conn);
        OSMO_ASSERT(conn->end.codec.payload_type == 18);
        OSMO_ASSERT(conn->end.alt_codec.payload_type == -1);
 
        /* Allocate 5@mgw at select GSM.. */
        last_endpoint = -1;
-       inp = create_msg(CRCX_MULT_GSM_EXACT);
+       inp = create_msg(CRCX_MULT_GSM_EXACT, NULL);
        talloc_free(cfg->trunk.audio_name);
        cfg->trunk.audio_name = "GSM/8000";
        cfg->trunk.no_audio_transcoding = 1;
        resp = mgcp_handle_message(cfg, inp);
+       OSMO_ASSERT(get_conn_id_from_response(resp->data, conn_id,
+                                             sizeof(conn_id)) == 0);
        msgb_free(inp);
        msgb_free(resp);
 
        OSMO_ASSERT(last_endpoint == 5);
        endp = &cfg->trunk.endpoints[last_endpoint];
-       conn = mgcp_conn_get_rtp(endp, "3");
+       conn = mgcp_conn_get_rtp(endp, conn_id);
        OSMO_ASSERT(conn);
        OSMO_ASSERT(conn->end.codec.payload_type == 3);
        OSMO_ASSERT(conn->end.alt_codec.payload_type == -1);
 
-       inp = create_msg(MDCX_NAT_DUMMY);
+       inp = create_msg(MDCX_NAT_DUMMY, conn_id);
        last_endpoint = -1;
        resp = mgcp_handle_message(cfg, inp);
        msgb_free(inp);
        msgb_free(resp);
        OSMO_ASSERT(last_endpoint == 5);
        endp = &cfg->trunk.endpoints[last_endpoint];
-       conn = mgcp_conn_get_rtp(endp, "3");
+       conn = mgcp_conn_get_rtp(endp, conn_id);
        OSMO_ASSERT(conn);
        OSMO_ASSERT(conn->end.codec.payload_type == 3);
        OSMO_ASSERT(conn->end.alt_codec.payload_type == -1);
@@ -1199,19 +1307,21 @@
        talloc_free(endp->last_response);
        talloc_free(endp->last_trans);
        endp->last_response = endp->last_trans = NULL;
-       conn = mgcp_conn_get_rtp(endp, "3");
+       conn = mgcp_conn_get_rtp(endp, conn_id);
        OSMO_ASSERT(!conn);
 
        last_endpoint = -1;
-       inp = create_msg(CRCX_MULT_GSM_EXACT);
+       inp = create_msg(CRCX_MULT_GSM_EXACT, NULL);
        cfg->trunk.no_audio_transcoding = 0;
        resp = mgcp_handle_message(cfg, inp);
+       OSMO_ASSERT(get_conn_id_from_response(resp->data, conn_id,
+                                             sizeof(conn_id)) == 0);
        msgb_free(inp);
        msgb_free(resp);
 
        OSMO_ASSERT(last_endpoint == 5);
        endp = &cfg->trunk.endpoints[last_endpoint];
-       conn = mgcp_conn_get_rtp(endp, "3");
+       conn = mgcp_conn_get_rtp(endp, conn_id);
        OSMO_ASSERT(conn);
        OSMO_ASSERT(conn->end.codec.payload_type == 255);
        OSMO_ASSERT(conn->end.alt_codec.payload_type == 0);
@@ -1224,6 +1334,7 @@
        struct mgcp_config *cfg;
        struct mgcp_endpoint *endp;
        struct mgcp_conn_rtp *conn = NULL;
+       struct mgcp_conn *_conn = NULL;
 
        printf("Testing no sequence flow on initial packet\n");
 
@@ -1233,9 +1344,10 @@
 
        endp = &cfg->trunk.endpoints[1];
 
-       mgcp_conn_alloc(NULL, endp, "4711", MGCP_CONN_TYPE_RTP,
-                       "test-connection");
-       conn = mgcp_conn_get_rtp(endp, "4711");
+       _conn = mgcp_conn_alloc(NULL, endp, MGCP_CONN_TYPE_RTP,
+                               "test-connection");
+       OSMO_ASSERT(_conn);
+       conn = mgcp_conn_get_rtp(endp, _conn->id);
        OSMO_ASSERT(conn);
 
        OSMO_ASSERT(conn->state.stats_initialized == 0);
@@ -1281,9 +1393,10 @@
 
        mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
 
-       inp = create_msg(CRCX);
+       inp = create_msg(CRCX, NULL);
        msg = mgcp_handle_message(cfg, inp);
-       if (strcmp((char *)msg->data, CRCX_RET_NO_RTPMAP) != 0) {
+
+       if (check_response(msg->data, CRCX_RET_NO_RTPMAP) != 0) {
                printf("FAILED: there should not be a RTPMAP: %s\n",
                       (char *)msg->data);
                OSMO_ASSERT(false);
diff --git a/tests/mgcp/mgcp_test.ok b/tests/mgcp/mgcp_test.ok
index 7376930..c764531 100644
--- a/tests/mgcp/mgcp_test.ok
+++ b/tests/mgcp/mgcp_test.ok
@@ -11,87 +11,550 @@
 line: ''
 line: ''
 line: ''
+
+================================================
 Testing AUEP1
+creating message from statically defined input:
+---------8<---------
+AUEP 158663169 ds/e1-1/[email protected] MGCP 1.0
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing AUEP2
+creating message from statically defined input:
+---------8<---------
+AUEP 18983213 ds/e1-2/[email protected] MGCP 1.0
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing MDCX1
+creating message from statically defined input:
+---------8<---------
+MDCX 18983213 ds/e1-3/[email protected] MGCP 1.0
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing MDCX2
+creating message from statically defined input:
+---------8<---------
+MDCX 18983214 ds/e1-1/[email protected] MGCP 1.0
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing CRCX
+creating message from statically defined input:
+---------8<---------
+CRCX 2 1@mgw MGCP 1.0
+M: recvonly
+C: 2
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 97
+a=rtpmap:97 GSM-EFR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 1: RECV
+
+================================================
 Testing MDCX3
+creating message from statically defined input:
+---------8<---------
+MDCX 18983215 1@mgw MGCP 1.0
+I: %s
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetization period not set
-Connection mode: 1: RECV
+
+================================================
 Testing MDCX4
+creating message from statically defined input:
+---------8<---------
+MDCX 18983216 1@mgw MGCP 1.0
+M: sendrecv
C: 2
+I: %s
+L: p:20, a:AMR, nt:IN
+
+v=0
+o=- %s 23 IN IP4 0.0.0.0
+c=IN IP4 0.0.0.0
+t=0 0
+m=audio 4441 RTP/AVP 99
+a=rtpmap:99 AMR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 3: SEND RECV
+
+================================================
 Testing MDCX4_PT1
+creating message from statically defined input:
+---------8<---------
+MDCX 18983217 1@mgw MGCP 1.0
+M: sendrecv
C: 2
+I: %s
+L: p:20-40, a:AMR, nt:IN
+
+v=0
+o=- %s 23 IN IP4 0.0.0.0
+c=IN IP4 0.0.0.0
+t=0 0
+m=audio 4441 RTP/AVP 99
+a=rtpmap:99 AMR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetetization period: 20-40
-Connection mode: 3: SEND RECV
+
+================================================
 Testing MDCX4_PT2
+creating message from statically defined input:
+---------8<---------
+MDCX 18983218 1@mgw MGCP 1.0
+M: sendrecv
C: 2
+I: %s
+L: p:20-20, a:AMR, nt:IN
+
+v=0
+o=- %s 23 IN IP4 0.0.0.0
+c=IN IP4 0.0.0.0
+t=0 0
+m=audio 4441 RTP/AVP 99
+a=rtpmap:99 AMR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 3: SEND RECV
+
+================================================
 Testing MDCX4_PT3
+creating message from statically defined input:
+---------8<---------
+MDCX 18983219 1@mgw MGCP 1.0
+M: sendrecv
C: 2
+I: %s
+L: a:AMR, nt:IN
+
+v=0
+o=- %s 23 IN IP4 0.0.0.0
+c=IN IP4 0.0.0.0
+t=0 0
+m=audio 4441 RTP/AVP 99
+a=rtpmap:99 AMR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetization period not set
-Connection mode: 3: SEND RECV
+
+================================================
 Testing MDCX4_SO
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 2: SEND
+creating message from statically defined input:
+---------8<---------
+MDCX 18983220 1@mgw MGCP 1.0
+M: sendonly
C: 2
+I: %s
+L: p:20, a:AMR, nt:IN
+
+v=0
+o=- %s 23 IN IP4 0.0.0.0
+c=IN IP4 0.0.0.0
+t=0 0
+m=audio 4441 RTP/AVP 99
+a=rtpmap:99 AMR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
+
+================================================
 Testing MDCX4_RO
+creating message from statically defined input:
+---------8<---------
+MDCX 18983221 1@mgw MGCP 1.0
+M: recvonly
C: 2
+I: %s
+L: p:20, a:AMR, nt:IN
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 1: RECV
+
+================================================
 Testing DLCX
+creating message from statically defined input:
+---------8<---------
+DLCX 7 1@mgw MGCP 1.0
+I: %s
+C: 2
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing CRCX_ZYN
+creating message from statically defined input:
+---------8<---------
+CRCX 2 1@mgw MGCP 1.0
M: recvonly
C: 2
+
+v=0
c=IN IP4 123.12.12.123
m=audio 5904 RTP/AVP 97
a=rtpmap:97 GSM-EFR/8000
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 20
-Requested packetization period not set
-Connection mode: 1: RECV
+
+================================================
 Testing EMPTY
+creating message from statically defined input:
+---------8<---------
+
+
+---------8<---------
+
+================================================
 Testing SHORT1
+creating message from statically defined input:
+---------8<---------
+CRCX 
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing SHORT2
+creating message from statically defined input:
+---------8<---------
+CRCX 1
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing SHORT3
+creating message from statically defined input:
+---------8<---------
+CRCX 1 1@mgw
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing SHORT4
+creating message from statically defined input:
+---------8<---------
+CRCX 1 1@mgw MGCP
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing RQNT1
+creating message from statically defined input:
+---------8<---------
+RQNT 186908780 1@mgw MGCP 1.0
+X: B244F267488
+S: D/9
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing RQNT2
+creating message from statically defined input:
+---------8<---------
+RQNT 186908781 1@mgw MGCP 1.0
+X: ADD4F26746F
+R: D/[0-9#*](N), G/ft, fxr/t38
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing DLCX
+creating message from statically defined input:
+---------8<---------
+DLCX 7 1@mgw MGCP 1.0
+I: %s
+C: 2
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing CRCX
+creating message from statically defined input:
+---------8<---------
+CRCX 2 1@mgw MGCP 1.0
+M: recvonly
+C: 2
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 97
+a=rtpmap:97 GSM-EFR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetetization period: 20-20
-Connection mode: 1: RECV
+
+================================================
 Testing MDCX3
+creating message from statically defined input:
+---------8<---------
+MDCX 18983215 1@mgw MGCP 1.0
+I: %s
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Dummy packets: 2
-Detected packet duration: 40
-Requested packetization period not set
-Connection mode: 1: RECV
+
+================================================
 Testing DLCX
+creating message from statically defined input:
+---------8<---------
+DLCX 7 1@mgw MGCP 1.0
+I: %s
+C: 2
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing CRCX
+creating message from statically defined input:
+---------8<---------
+CRCX 2 1@mgw MGCP 1.0
+M: recvonly
+C: 2
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 97
+a=rtpmap:97 GSM-EFR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Re-transmitting CRCX
+creating message from statically defined input:
+---------8<---------
+CRCX 2 1@mgw MGCP 1.0
+M: recvonly
+C: 2
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 97
+a=rtpmap:97 GSM-EFR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
+
+================================================
 Testing RQNT1
+creating message from statically defined input:
+---------8<---------
+RQNT 186908780 1@mgw MGCP 1.0
+X: B244F267488
+S: D/9
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
 Re-transmitting RQNT1
+creating message from statically defined input:
+---------8<---------
+RQNT 186908780 1@mgw MGCP 1.0
+X: B244F267488
+S: D/9
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing RQNT2
+creating message from statically defined input:
+---------8<---------
+RQNT 186908781 1@mgw MGCP 1.0
+X: ADD4F26746F
+R: D/[0-9#*](N), G/ft, fxr/t38
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
 Re-transmitting RQNT2
+creating message from statically defined input:
+---------8<---------
+RQNT 186908781 1@mgw MGCP 1.0
+X: ADD4F26746F
+R: D/[0-9#*](N), G/ft, fxr/t38
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
+
+================================================
 Testing MDCX3
+creating message from statically defined input:
+---------8<---------
+MDCX 18983215 1@mgw MGCP 1.0
+I: %s
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Re-transmitting MDCX3
+creating message from statically defined input:
+---------8<---------
+MDCX 18983215 1@mgw MGCP 1.0
+I: %s
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
+
+================================================
 Testing DLCX
+creating message from statically defined input:
+---------8<---------
+DLCX 7 1@mgw MGCP 1.0
+I: %s
+C: 2
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
 Re-transmitting DLCX
+creating message from statically defined input:
+---------8<---------
+DLCX 7 1@mgw MGCP 1.0
+I: %s
+C: 2
+
+---------8<---------
+checking response:
+using message as statically defined for comparison
+Response matches our expectations.
 Testing packet loss calculation.
+creating message from statically defined input:
+---------8<---------
+CRCX 2 1@mgw MGCP 1.0
+M: recvonly
+C: 2
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 97
+a=rtpmap:97 GSM-EFR/8000
+a=ptime:40
+
+---------8<---------
+creating message from statically defined input:
+---------8<---------
+RQNT 186908780 1@mgw MGCP 1.0
+X: B244F267488
+S: D/9
+
+---------8<---------
+creating message from statically defined input:
+---------8<---------
+DLCX 7 1@mgw MGCP 1.0
+I: %s
+C: 2
+
+---------8<---------
 Testing stat parsing
+creating message from statically defined input:
+---------8<---------
+250 7 OK
+P: PS=0, OS=0, PR=0, OR=0, PL=0, JI=0
+X-Osmo-CP: EC TI=0, TO=0
+
+---------8<---------
 Parsing result: 0
+creating message from statically defined input:
+---------8<---------
+250 7 OK
+P: PS=10, OS=20, PR=30, OR=40, PL=-3, JI=40
+
+---------8<---------
 Parsing result: 0
 Testing packet error detection, patch SSRC.
 Output SSRC changed to 11223344
@@ -466,6 +929,156 @@
 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
 Stats: Jitter = 0, Transit = -144000
 Testing multiple payload types
+creating message from statically defined input:
+---------8<---------
+CRCX 2 1@mgw MGCP 1.0
+M: recvonly
+C: 2
+X
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 18 97
+a=rtpmap:18 G729/8000
+a=rtpmap:97 GSM-EFR/8000
+a=ptime:40
+
+---------8<---------
+creating message from statically defined input:
+---------8<---------
+CRCX 2 2@mgw MGCP 1.0
+M: recvonly
+C: 2
+X
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 18 97 101
+a=rtpmap:18 G729/8000
+a=rtpmap:97 GSM-EFR/8000
+a=rtpmap:101 FOO/8000
+a=ptime:40
+
+---------8<---------
+creating message from statically defined input:
+---------8<---------
+CRCX 2 3@mgw MGCP 1.0
+M: recvonly
+C: 2
+X
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP
+a=rtpmap:18 G729/8000
+a=rtpmap:97 GSM-EFR/8000
+a=rtpmap:101 FOO/8000
+a=ptime:40
+
+---------8<---------
+creating message from statically defined input:
+---------8<---------
+CRCX 2 4@mgw MGCP 1.0
+M: recvonly
+C: 2
+X
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 18
+a=rtpmap:18 G729/8000
+a=rtpmap:97 GSM-EFR/8000
+a=rtpmap:101 FOO/8000
+a=ptime:40
+
+---------8<---------
+creating message from statically defined input:
+---------8<---------
+CRCX 259260421 5@mgw MGCP 1.0
+C: 1355c6041e
+L: p:20, a:GSM, nt:IN
+M: recvonly
+
+v=0
+o=- 1439038275 1439038275 IN IP4 192.168.181.247
+s=-
+c=IN IP4 192.168.181.247
+t=0 0
+m=audio 29084 RTP/AVP 255 0 8 3 18 4 96 97 101
+a=rtpmap:0 PCMU/8000
+a=rtpmap:8 PCMA/8000
+a=rtpmap:3 gsm/8000
+a=rtpmap:18 G729/8000
+a=fmtp:18 annexb=no
+a=rtpmap:4 G723/8000
+a=rtpmap:96 iLBC/8000
+a=fmtp:96 mode=20
+a=rtpmap:97 iLBC/8000
+a=fmtp:97 mode=30
+a=rtpmap:101 telephone-event/8000
+a=fmtp:101 0-15
+a=recvonly
+
+---------8<---------
+creating message from statically defined input:
+---------8<---------
+MDCX 23 5@mgw MGCP 1.0
+C: 1355c6041e
+I: %s
+
+c=IN IP4 8.8.8.8
+m=audio 16434 RTP/AVP 255
+
+---------8<---------
+creating message from statically defined input:
+---------8<---------
+CRCX 259260421 5@mgw MGCP 1.0
+C: 1355c6041e
+L: p:20, a:GSM, nt:IN
+M: recvonly
+
+v=0
+o=- 1439038275 1439038275 IN IP4 192.168.181.247
+s=-
+c=IN IP4 192.168.181.247
+t=0 0
+m=audio 29084 RTP/AVP 255 0 8 3 18 4 96 97 101
+a=rtpmap:0 PCMU/8000
+a=rtpmap:8 PCMA/8000
+a=rtpmap:3 gsm/8000
+a=rtpmap:18 G729/8000
+a=fmtp:18 annexb=no
+a=rtpmap:4 G723/8000
+a=rtpmap:96 iLBC/8000
+a=fmtp:96 mode=20
+a=rtpmap:97 iLBC/8000
+a=fmtp:97 mode=30
+a=rtpmap:101 telephone-event/8000
+a=fmtp:101 0-15
+a=recvonly
+
+---------8<---------
 Testing no sequence flow on initial packet
 Testing no rtpmap name
+creating message from statically defined input:
+---------8<---------
+CRCX 2 1@mgw MGCP 1.0
+M: recvonly
+C: 2
+L: p:20
+
+v=0
+c=IN IP4 123.12.12.123
+m=audio 5904 RTP/AVP 97
+a=rtpmap:97 GSM-EFR/8000
+a=ptime:40
+
+---------8<---------
+checking response:
+using message with patched conn_id for comparison
+Response matches our expectations.
 Done

-- 
To view, visit https://gerrit.osmocom.org/4905
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Iab6a6038e7610c62f34e642cd49c93d11151252c
Gerrit-PatchSet: 2
Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <[email protected]>

Reply via email to