This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
dexter gerrit-no-reply at lists.osmocom.orgHello Neels Hofmeyr, Harald Welte, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/4905 to look at the new patch set (#7). 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 TODO-RELEASE 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 9 files changed, 970 insertions(+), 162 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/05/4905/7 diff --git a/TODO-RELEASE b/TODO-RELEASE index 917c995..9d0e0dc 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -23,5 +23,7 @@ # If any interfaces have been added since the last public release, a++; # If any interfaces have been removed or changed since the last public release, a=0. # -#library what description / commit summary line -libosmo-mgcp API/ABI change parse and represent connection identifiers as hex strings \ No newline at end of file +#library what description / commit summary line +libosmo-mgcp API/ABI change parse and represent connection identifiers as hex strings +libosmo-mgcp API/ABI change connection identifiers are assigned by the server, not CA +libosmo-mgcp-client API/ABI change parse and store connection identifier in response \ No newline at end of file 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..ac86f52 100644 --- a/src/libosmo-mgcp-client/mgcp_client.c +++ b/src/libosmo-mgcp-client/mgcp_client.c @@ -258,6 +258,58 @@ 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; + + osmo_strlcpy(r->head.conn_id, line + 3, sizeof(r->head.conn_id)); + 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 +340,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 +708,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 +778,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 a89d60c..e33596d 100644 --- a/src/libosmo-mgcp/mgcp_conn.c +++ b/src/libosmo-mgcp/mgcp_conn.c @@ -25,6 +25,46 @@ #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; + + /* Generate a connection id that is unique for the current endpoint. + * Technically a counter would be sufficient, but in order to + * be able to find a specific connection in large logfiles and to + * prevent unintentional connections we assign the connection + * identifiers randomly from a reasonable large number space */ + 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 unique + * for this endpoint */ + if (!mgcp_conn_get_rtp(endp, id_hex)) { + osmo_strlcpy(id, id_hex, MGCP_CONN_ID_LENGTH); + return 0; + } + } + + LOGP(DLMGCP, LOGL_ERROR, "endpoint:%x, unable to generate a unique connectionIdentifier\n", + ENDPOINT_NUMBER(endp)); + + return -1; +} /* Reset codec state and free memory */ static void mgcp_rtp_codec_reset(struct mgcp_rtp_codec *codec) @@ -78,22 +118,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_LENGTH); 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 +141,11 @@ conn->mode_orig = MGCP_CONN_NONE; conn->u.rtp.conn = conn; strcpy(conn->name, name); - osmo_strlcpy(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 672a8d4..feca8da 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"); @@ -468,7 +468,10 @@ callid = (const char *)line + 3; break; case 'I': - conn_id = (const char *)line + 3; + /* It is illegal to send a connection identifier + * together with a CRCX, the MGW will assign the + * connection identifier by itself on CRCX */ + return create_err_response(NULL, 523, "CRCX", p->trans); break; case 'M': mode = (const char *)line + 3; @@ -506,13 +509,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 +556,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 7d976da..fb99911 100644 --- a/tests/mgcp/mgcp_test.c +++ b/tests/mgcp/mgcp_test.c @@ -82,27 +82,27 @@ #define MDCX3 \ "MDCX 18983215 1 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 && strlen(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,18 +555,95 @@ 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; + + conn_id_ptr = strstr((char *)resp, "I: "); + if (!conn_id_ptr) + return -EINVAL; + + memset(conn_id, 0, conn_id_len); + memcpy(conn_id, conn_id_ptr + 3, 32); + + for (i = 0; i < conn_id_len; i++) { + if (conn_id[i] == '\n' || conn_id[i] == '\r') + conn_id[i] = '\0'; + } + + /* A valid conn_id must at least contain one digit, and must + * not exceed a length of 32 digits */ + OSMO_ASSERT(strlen(conn_id) <= 32); + OSMO_ASSERT(strlen(conn_id) > 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 last_conn_id[256]; cfg = mgcp_config_alloc(); cfg->trunk.vty_number_endpoints = 64; mgcp_endpoints_allocate(&cfg->trunk); cfg->policy_cb = mgcp_test_policy_cb; + + memset(last_conn_id, 0, sizeof(last_conn_id)); mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1)); @@ -574,6 +652,7 @@ struct msgb *inp; struct msgb *msg; + printf("\n================================================\n"); printf("Testing %s\n", t->name); last_endpoint = -1; @@ -582,7 +661,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) { @@ -591,11 +670,15 @@ (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, last_conn_id, + sizeof(last_conn_id)); + msgb_free(msg); if (dummy_packets) @@ -656,7 +739,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]; @@ -681,11 +764,14 @@ { struct mgcp_config *cfg; int i; + char last_conn_id[256]; cfg = mgcp_config_alloc(); cfg->trunk.vty_number_endpoints = 64; mgcp_endpoints_allocate(&cfg->trunk); + + memset(last_conn_id, 0, sizeof(last_conn_id)); mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1)); @@ -694,24 +780,30 @@ 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 && strcmp(t->name, CRCX)) + get_conn_id_from_response(msg->data, last_conn_id, + sizeof(last_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); } @@ -732,6 +824,7 @@ { struct mgcp_config *cfg; struct msgb *inp, *msg; + char conn_id[256]; cfg = mgcp_config_alloc(); cfg->rqnt_cb = rqnt_cb; @@ -741,12 +834,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); @@ -761,7 +858,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); @@ -864,7 +961,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 @@ -874,7 +971,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 @@ -1013,6 +1110,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" : "", @@ -1032,9 +1130,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; @@ -1092,6 +1191,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"); @@ -1103,85 +1203,95 @@ /* Allocate endpoint 1 at 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 at 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 at 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 at 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 at 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); @@ -1198,19 +1308,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); @@ -1223,6 +1335,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"); @@ -1232,9 +1345,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 +1395,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/2 at 172.16.6.66 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/1 at 172.16.6.66 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/1 at 172.16.6.66 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/2 at 172.16.6.66 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at mgw MGCP 1.0 +X: B244F267488 +S: D/9 + +---------8<--------- +creating message from statically defined input: +---------8<--------- +DLCX 7 1 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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: 7 Gerrit-Project: osmo-mgw Gerrit-Branch: master Gerrit-Owner: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de> Gerrit-Reviewer: dexter <pmaier at sysmocom.de>