aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2023-04-26 15:45:17 +0200
committerPhilipp Maier <pmaier@sysmocom.de>2023-05-22 11:18:45 +0200
commit4c4d227624077e049953e344b228c3951fb125df (patch)
treef267e1ec27254f6fabc99821fdc29d0c4a6c72ad
parent0e8310fa6cb1f599aae515c7f67c833abd87111d (diff)
mgcp_codec: fix codec decision
Unfortunately OsmoMGW was never really tested with multiple different codecs on either side of the connection. While OsmoMSC and OsmoBSC only assign exactly one codec on each side this has never been a problem, however it might become a problem when a call agent assigns multiple codecs on one side. This has been observed in a setup where OsmoMGW had one leg towards an external call agent. Also due to recent upgrades to the TTCN3 tests we are now able to simulate different codecs on both sides to pinpoint issues. Testing has shown that OsmoMGW has difficulties with multiple codecs. The reason for this is that the function that makes the codec decision was not fully finished. So let's finish the codec decision function and let's also use that decision when patching the payload type of outgoing RTP packets. Related: OS#5461 Change-Id: I6c3291f825488e5d8ce136aeb18450156794aeb5
-rw-r--r--include/osmocom/mgcp/mgcp_codec.h3
-rw-r--r--include/osmocom/mgcp/mgcp_trunk.h2
-rw-r--r--src/libosmo-mgcp/mgcp_codec.c136
-rw-r--r--src/libosmo-mgcp/mgcp_network.c24
-rw-r--r--src/libosmo-mgcp/mgcp_protocol.c12
-rw-r--r--src/libosmo-mgcp/mgcp_vty.c46
-rw-r--r--tests/mgcp/mgcp_test.c228
-rw-r--r--tests/mgcp/mgcp_test.ok268
8 files changed, 376 insertions, 343 deletions
diff --git a/include/osmocom/mgcp/mgcp_codec.h b/include/osmocom/mgcp/mgcp_codec.h
index 1f29b0888..cfc8ecf06 100644
--- a/include/osmocom/mgcp/mgcp_codec.h
+++ b/include/osmocom/mgcp/mgcp_codec.h
@@ -13,8 +13,7 @@ struct mgcp_conn_rtp;
void mgcp_codec_summary(struct mgcp_conn_rtp *conn);
void mgcp_codec_reset_all(struct mgcp_conn_rtp *conn);
int mgcp_codec_add(struct mgcp_conn_rtp *conn, int payload_type, const char *audio_name, const struct mgcp_codec_param *param);
-int mgcp_codec_decide(struct mgcp_conn_rtp *conn);
-struct mgcp_rtp_codec *mgcp_codec_find_convertible(struct mgcp_conn_rtp *conn, struct mgcp_rtp_codec *codec);
+int mgcp_codec_decide(struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst);
const struct mgcp_rtp_codec *mgcp_codec_pt_find_by_subtype_name(struct mgcp_conn_rtp *conn,
const char *subtype_name, unsigned int match_nr);
bool mgcp_codec_amr_align_mode_is_indicated(const struct mgcp_rtp_codec *codec);
diff --git a/include/osmocom/mgcp/mgcp_trunk.h b/include/osmocom/mgcp/mgcp_trunk.h
index 33c3d5b03..e608161ed 100644
--- a/include/osmocom/mgcp/mgcp_trunk.h
+++ b/include/osmocom/mgcp/mgcp_trunk.h
@@ -31,8 +31,6 @@ struct mgcp_trunk {
int audio_send_ptime;
int audio_send_name;
- int no_audio_transcoding;
-
int omit_rtcp;
int keepalive_interval;
diff --git a/src/libosmo-mgcp/mgcp_codec.c b/src/libosmo-mgcp/mgcp_codec.c
index 7fada78ee..905795c71 100644
--- a/src/libosmo-mgcp/mgcp_codec.c
+++ b/src/libosmo-mgcp/mgcp_codec.c
@@ -344,16 +344,11 @@ static bool codecs_convertible(struct mgcp_rtp_codec *codec_a, struct mgcp_rtp_c
return true;
}
-/*! For a given codec, find a convertible codec in the given connection.
- * \param[in] conn connection to search for a convertible codec
- * \param[in] codec for which a convertible codec shall be found.
- * \returns codec on success, -NULL on failure. */
-struct mgcp_rtp_codec *mgcp_codec_find_convertible(struct mgcp_conn_rtp *conn, struct mgcp_rtp_codec *codec)
+struct mgcp_rtp_codec *mgcp_codec_find_same(struct mgcp_conn_rtp *conn, struct mgcp_rtp_codec *codec)
{
struct mgcp_rtp_end *rtp_end;
unsigned int i;
unsigned int codecs_assigned;
- struct mgcp_rtp_codec *codec_convertible = NULL;
rtp_end = &conn->end;
@@ -363,89 +358,92 @@ struct mgcp_rtp_codec *mgcp_codec_find_convertible(struct mgcp_conn_rtp *conn, s
OSMO_ASSERT(codecs_assigned <= MGCP_MAX_CODECS);
for (i = 0; i < codecs_assigned; i++) {
if (codecs_same(codec, &rtp_end->codecs[i])) {
- codec_convertible = &rtp_end->codecs[i];
+ return &rtp_end->codecs[i];
break;
}
}
+ return NULL;
+}
+
+/* For a given codec, find a convertible codec in the given connection. */
+static struct mgcp_rtp_codec *codec_find_convertible(struct mgcp_conn_rtp *conn, struct mgcp_rtp_codec *codec)
+{
+ struct mgcp_rtp_end *rtp_end;
+ unsigned int i;
+ unsigned int codecs_assigned;
+ struct mgcp_rtp_codec *codec_convertible = NULL;
+
+ rtp_end = &conn->end;
+
+ /* Use the codec information from the source and try to find the equivalent of it on the destination side. In
+ * the first run we will look for an exact match. */
+ codec_convertible = mgcp_codec_find_same(conn, codec);
+ if (codec_convertible)
+ return codec_convertible;
+
/* In case we weren't able to find an exact match, we will try to find a match that is the same codec, but the
* payload format may be different. This alternative will require a frame format conversion (i.e. AMR bwe->oe) */
- if (!codec_convertible) {
- for (i = 0; i < codecs_assigned; i++) {
- if (codecs_convertible(codec, &rtp_end->codecs[i])) {
- codec_convertible = &rtp_end->codecs[i];
- break;
- }
+ codecs_assigned = rtp_end->codecs_assigned;
+ OSMO_ASSERT(codecs_assigned <= MGCP_MAX_CODECS);
+ for (i = 0; i < codecs_assigned; i++) {
+ if (codecs_convertible(codec, &rtp_end->codecs[i])) {
+ codec_convertible = &rtp_end->codecs[i];
+ break;
}
}
return codec_convertible;
}
-/* Check if the given codec is applicable on the specified endpoint
- * Helper function for mgcp_codec_decide() */
-static bool is_codec_compatible(const struct mgcp_endpoint *endp, const struct mgcp_rtp_codec *codec)
-{
- /* A codec name must be set, if not, this might mean that the codec
- * (payload type) that was assigned is unknown to us so we must stop
- * here. */
- if (!strlen(codec->subtype_name))
- return false;
-
- /* FIXME: implement meaningful checks to make sure that the given codec
- * is compatible with the given endpoint */
-
- return true;
-}
-
-/*! Decide for one suitable codec
- * \param[in] conn related rtp-connection.
+/*! Decide for one suitable codec on both of the given connections. In case a destination connection is not available,
+ * a tentative decision is made.
+ * \param[inout] conn_src related rtp-connection.
+ * \param[inout] conn_dst related destination rtp-connection (NULL if not present).
* \returns 0 on success, -EINVAL on failure. */
-int mgcp_codec_decide(struct mgcp_conn_rtp *conn)
+int mgcp_codec_decide(struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst)
{
- struct mgcp_rtp_end *rtp;
unsigned int i;
- struct mgcp_endpoint *endp;
- bool codec_assigned = false;
- endp = conn->conn->endp;
- rtp = &conn->end;
+ /* In case no destination connection is available (yet), or in case the destination connection exists but has
+ * no codecs assigned, we are forced to make a simple tentative decision:
+ * We just use the first codec of the source connection (conn_src) */
+ OSMO_ASSERT(conn_src->end.codecs_assigned <= MGCP_MAX_CODECS);
+ if (!conn_dst || conn_dst->end.codecs_assigned == 0) {
+ if (conn_src->end.codecs_assigned >= 1) {
+ conn_src->end.codec = &conn_src->end.codecs[0];
+ return 0;
+ } else
+ return -EINVAL;
+ }
- /* This function works on the results the SDP/LCO parser has extracted
- * from the MGCP message. The goal is to select a suitable codec for
- * the given connection. When transcoding is available, the first codec
- * from the codec list is taken without further checking. When
- * transcoding is not available, then the choice must be made more
- * carefully. Each codec in the list is checked until one is found that
- * is rated compatible. The rating is done by the helper function
- * is_codec_compatible(), which does the actual checking. */
- for (i = 0; i < rtp->codecs_assigned; i++) {
- /* When no transcoding is available, avoid codecs that would
- * require transcoding. */
- if (endp->trunk->no_audio_transcoding && !is_codec_compatible(endp, &rtp->codecs[i])) {
- LOGP(DLMGCP, LOGL_NOTICE, "transcoding not available, skipping codec: %d/%s\n",
- rtp->codecs[i].payload_type, rtp->codecs[i].subtype_name);
- continue;
+ /* Compare all codecs of the source connection (conn_src) to the codecs of the destination connection (conn_dst). In case
+ * of a match set this codec on both connections. This would be an ideal selection since no codec conversion would be
+ * required. */
+ for (i = 0; i < conn_src->end.codecs_assigned; i++) {
+ struct mgcp_rtp_codec *codec_conn_dst = mgcp_codec_find_same(conn_dst, &conn_src->end.codecs[i]);
+ if (codec_conn_dst) {
+ /* We found the a codec that is exactly the same (same codec, same payload format etc.) on both
+ * sides. We now set this codec on both connections. */
+ conn_dst->end.codec = codec_conn_dst;
+ conn_src->end.codec = mgcp_codec_find_same(conn_src, codec_conn_dst);
+ OSMO_ASSERT(conn_src->end.codec);
+ return 0;
}
-
- rtp->codec = &rtp->codecs[i];
- codec_assigned = true;
- break;
}
- /* FIXME: To the reviewes: This is problematic. I do not get why we
- * need to reset the packet_duration_ms depending on the codec
- * selection. I thought it were all 20ms? Is this to address some
- * cornercase. (This piece of code was in the code path before,
- * together with the note: "TODO/XXX: Store this per codec and derive
- * it on use" */
- if (codec_assigned) {
- if (rtp->maximum_packet_time >= 0
- && rtp->maximum_packet_time * rtp->codec->frame_duration_den >
- rtp->codec->frame_duration_num * 1500)
- rtp->packet_duration_ms = 0;
-
- return 0;
+ /* In case we could not find a codec that is exactly the same, let's at least try to find a codec that we are able
+ * to convert. */
+ for (i = 0; i < conn_src->end.codecs_assigned; i++) {
+ struct mgcp_rtp_codec *codec_conn_dst = codec_find_convertible(conn_dst, &conn_src->end.codecs[i]);
+ if (codec_conn_dst) {
+ /* We found the a codec that we are able to convert on both sides. We now set this codec on both
+ * connections. */
+ conn_dst->end.codec = codec_conn_dst;
+ conn_src->end.codec = codec_find_convertible(conn_src, codec_conn_dst);
+ OSMO_ASSERT(conn_src->end.codec);
+ return 0;
+ }
}
return -EINVAL;
diff --git a/src/libosmo-mgcp/mgcp_network.c b/src/libosmo-mgcp/mgcp_network.c
index ea1a699d8..6b1690717 100644
--- a/src/libosmo-mgcp/mgcp_network.c
+++ b/src/libosmo-mgcp/mgcp_network.c
@@ -492,32 +492,24 @@ void mgcp_rtp_annex_count(const struct mgcp_endpoint *endp,
/* There may be different payload type numbers negotiated for two connections.
* Patch the payload type of an RTP packet so that it uses the payload type
- * that is valid for the destination connection (conn_dst) */
-static int mgcp_patch_pt(struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst, struct msgb *msg)
+ * of the codec that is set for the destination connection (conn_dst) */
+static int mgcp_patch_pt(struct mgcp_conn_rtp *conn_dst, struct msgb *msg)
{
struct rtp_hdr *rtp_hdr;
- struct mgcp_rtp_codec *codec_src;
- struct mgcp_rtp_codec *codec_dst;
if (msgb_length(msg) < sizeof(struct rtp_hdr)) {
- LOG_CONN_RTP(conn_src, LOGL_ERROR, "RTP packet too short (%u < %zu)\n",
+ LOG_CONN_RTP(conn_dst, LOGL_NOTICE, "RTP packet too short (%u < %zu)\n",
msgb_length(msg), sizeof(struct rtp_hdr));
return -EINVAL;
}
rtp_hdr = (struct rtp_hdr *)msgb_data(msg);
- /* Find the codec information that is used on the source side */
- codec_src = mgcp_codec_from_pt(conn_src, rtp_hdr->payload_type);
- if (!codec_src)
- return -EINVAL;
-
- /* Lookup a suitable codec in the destination connection. (The codec must be of the same type or at least
- * convertible) */
- codec_dst = mgcp_codec_find_convertible(conn_dst, codec_src);
- if (!codec_dst)
+ if (!conn_dst->end.codec) {
+ LOG_CONN_RTP(conn_dst, LOGL_NOTICE, "no codec set on destination connection!\n");
return -EINVAL;
+ }
+ rtp_hdr->payload_type = (uint8_t) conn_dst->end.codec->payload_type;
- rtp_hdr->payload_type = (uint8_t) codec_dst->payload_type;
return 0;
}
@@ -1172,7 +1164,7 @@ int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr
* IuUP -> AMR: calls this function, skip patching if conn_src is IuUP.
* {AMR or IuUP} -> IuUP: calls mgcp_udp_send() directly, skipping this function: No need to examine dst. */
if (is_rtp && !mgcp_conn_rtp_is_iuup(conn_src)) {
- rc = mgcp_patch_pt(conn_src, conn_dst, msg);
+ rc = mgcp_patch_pt(conn_dst, msg);
if (rc < 0) {
/* FIXME: It is legal that the payload type on the egress connection is
* different from the payload type that has been negotiated on the
diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c
index b697a9430..1fa345b86 100644
--- a/src/libosmo-mgcp/mgcp_protocol.c
+++ b/src/libosmo-mgcp/mgcp_protocol.c
@@ -761,6 +761,9 @@ static int handle_codec_info(struct mgcp_conn_rtp *conn,
struct mgcp_request_data *rq, int have_sdp, bool crcx)
{
struct mgcp_endpoint *endp = rq->endp;
+ struct mgcp_conn *conn_dst;
+ struct mgcp_conn_rtp *conn_dst_rtp;
+
int rc;
char *cmd;
@@ -802,8 +805,15 @@ static int handle_codec_info(struct mgcp_conn_rtp *conn,
goto error;
}
+ /* Try to find an destination RTP connection that we can include in the codec decision. */
+ conn_dst = mgcp_find_dst_conn(conn->conn);
+ if (conn_dst && conn_dst->type == MGCP_CONN_TYPE_RTP)
+ conn_dst_rtp = &conn_dst->u.rtp;
+ else
+ conn_dst_rtp = NULL;
+
/* Make codec decision */
- if (mgcp_codec_decide(conn) != 0)
+ if (mgcp_codec_decide(conn, conn_dst_rtp) != 0)
goto error;
return 0;
diff --git a/src/libosmo-mgcp/mgcp_vty.c b/src/libosmo-mgcp/mgcp_vty.c
index 5c19c14ee..784894c18 100644
--- a/src/libosmo-mgcp/mgcp_vty.c
+++ b/src/libosmo-mgcp/mgcp_vty.c
@@ -120,8 +120,6 @@ static int config_write_mgcp(struct vty *vty)
trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " number endpoints %u%s",
trunk->v.vty_number_endpoints, VTY_NEWLINE);
- vty_out(vty, " %sallow-transcoding%s",
- trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
if (strlen(g_cfg->call_agent_addr))
vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
VTY_NEWLINE);
@@ -701,25 +699,19 @@ DEFUN_USRATTR(cfg_mgcp_sdp_fmtp_extra,
return CMD_SUCCESS;
}
-DEFUN_USRATTR(cfg_mgcp_allow_transcoding,
- cfg_mgcp_allow_transcoding_cmd,
- X(MGW_CMD_ATTR_NEWCONN),
- "allow-transcoding", "Allow transcoding\n")
+DEFUN_DEPRECATED(cfg_mgcp_allow_transcoding,
+ cfg_mgcp_allow_transcoding_cmd,
+ "allow-transcoding", "Allow transcoding\n")
{
- struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
- OSMO_ASSERT(trunk);
- trunk->no_audio_transcoding = 0;
+ vty_out(vty, "%% Deprecated 'allow-transcoding' config no longer has any effect%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
-DEFUN_USRATTR(cfg_mgcp_no_allow_transcoding,
- cfg_mgcp_no_allow_transcoding_cmd,
- X(MGW_CMD_ATTR_NEWCONN),
- "no allow-transcoding", NO_STR "Allow transcoding\n")
+DEFUN_DEPRECATED(cfg_mgcp_no_allow_transcoding,
+ cfg_mgcp_no_allow_transcoding_cmd,
+ "no allow-transcoding", NO_STR "Allow transcoding\n")
{
- struct mgcp_trunk *trunk = mgcp_trunk_by_num(g_cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID);
- OSMO_ASSERT(trunk);
- trunk->no_audio_transcoding = 1;
+ vty_out(vty, "%% Deprecated 'no allow-transcoding' config no longer has any effect%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1073,8 +1065,6 @@ static int config_write_trunk(struct vty *vty)
if (trunk->audio_fmtp_extra)
vty_out(vty, " sdp audio fmtp-extra %s%s",
trunk->audio_fmtp_extra, VTY_NEWLINE);
- vty_out(vty, " %sallow-transcoding%s",
- trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
}
return CMD_SUCCESS;
@@ -1326,23 +1316,19 @@ DEFUN_ATTR(cfg_trunk_no_rtp_keepalive,
return CMD_SUCCESS;
}
-DEFUN_USRATTR(cfg_trunk_allow_transcoding,
- cfg_trunk_allow_transcoding_cmd,
- X(MGW_CMD_ATTR_NEWCONN),
- "allow-transcoding", "Allow transcoding\n")
+DEFUN_DEPRECATED(cfg_trunk_allow_transcoding,
+ cfg_trunk_allow_transcoding_cmd,
+ "allow-transcoding", "Allow transcoding\n")
{
- struct mgcp_trunk *trunk = vty->index;
- trunk->no_audio_transcoding = 0;
+ vty_out(vty, "%% Deprecated 'allow-transcoding' config no longer has any effect%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
-DEFUN_USRATTR(cfg_trunk_no_allow_transcoding,
- cfg_trunk_no_allow_transcoding_cmd,
- X(MGW_CMD_ATTR_NEWCONN),
- "no allow-transcoding", NO_STR "Allow transcoding\n")
+DEFUN_DEPRECATED(cfg_trunk_no_allow_transcoding,
+ cfg_trunk_no_allow_transcoding_cmd,
+ "no allow-transcoding", NO_STR "Allow transcoding\n")
{
- struct mgcp_trunk *trunk = vty->index;
- trunk->no_audio_transcoding = 1;
+ vty_out(vty, "%% Deprecated 'no allow-transcoding' config no longer has any effect%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c
index bc2dae0e5..2374e9195 100644
--- a/tests/mgcp/mgcp_test.c
+++ b/tests/mgcp/mgcp_test.c
@@ -1467,7 +1467,6 @@ static void test_multilple_codec(void)
/* Allocate 5@mgw and let osmo-mgw pick a codec from the list */
last_endpoint[0] = '\0';
inp = create_msg(CRCX_MULT_GSM_EXACT, NULL);
- 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);
@@ -1511,7 +1510,6 @@ static void test_multilple_codec(void)
last_endpoint[0] = '\0';
inp = create_msg(CRCX_MULT_GSM_EXACT, NULL);
- 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);
@@ -1769,26 +1767,25 @@ static const struct mgcp_codec_param amr_param_octet_aligned_unset = {
.amr_octet_aligned_present = false,
};
-struct testcase_mgcp_codec_find_convertible_codec {
+struct testcase_mgcp_codec_decide_codec {
int payload_type;
const char *audio_name;
const struct mgcp_codec_param *param;
int expect_rc;
};
-struct testcase_mgcp_codec_find_convertible_expect {
- bool end;
+struct testcase_mgcp_codec_decide_expect {
int payload_type_map[2];
};
-struct testcase_mgcp_codec_find_convertible {
+struct testcase_mgcp_codec_decide {
const char *descr;
/* two conns on an endpoint, each with N configured codecs */
- struct testcase_mgcp_codec_find_convertible_codec codecs[2][10];
- struct testcase_mgcp_codec_find_convertible_expect expect[32];
+ struct testcase_mgcp_codec_decide_codec codecs[2][10];
+ struct testcase_mgcp_codec_decide_expect expect[2];
};
-static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_convertible_cases[] = {
+static const struct testcase_mgcp_codec_decide test_mgcp_codec_find_convertible_cases[] = {
{
.descr = "same order, but differing payload type numbers",
.codecs = {
@@ -1805,10 +1802,7 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
.expect = {
{ .payload_type_map = {112, 96}, },
- { .payload_type_map = {0, 0}, },
- { .payload_type_map = {111, 97} },
- { .payload_type_map = {123, -EINVAL} },
- { .end = true },
+ { .payload_type_map = {112, 96}, },
},
},
{
@@ -1826,11 +1820,8 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
},
.expect = {
- { .payload_type_map = {112, 96}, },
{ .payload_type_map = {0, 0}, },
- { .payload_type_map = {111, 97} },
- { .payload_type_map = {123, -EINVAL} },
- { .end = true },
+ { .payload_type_map = {111, 97}, },
},
},
{
@@ -1848,11 +1839,8 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
},
.expect = {
- { .payload_type_map = {96, 97}, },
- { .payload_type_map = {97, 96}, },
{ .payload_type_map = {0, 0}, },
- { .payload_type_map = {123, -EINVAL} },
- { .end = true },
+ { .payload_type_map = {96, 97}, },
},
},
{
@@ -1868,10 +1856,8 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
},
.expect = {
- { .payload_type_map = {112, -EINVAL}, },
- { .payload_type_map = {0, -EINVAL}, },
- { .payload_type_map = {111, -EINVAL} },
- { .end = true },
+ { .payload_type_map = {-EINVAL, -EINVAL}, },
+ { .payload_type_map = {-EINVAL, 96}, },
},
},
{
@@ -1888,13 +1874,11 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
.expect = {
{ .payload_type_map = {112, -EINVAL}, },
- { .payload_type_map = {0, -EINVAL}, },
- { .payload_type_map = {111, -EINVAL} },
- { .end = true },
+ { .payload_type_map = {-EINVAL, -EINVAL}, },
},
},
{
- .descr = "test AMR with differing octet-aligned settings",
+ .descr = "test AMR with differing octet-aligned settings (both <-> both)",
.codecs = {
{
{ 111, "AMR/8000", &amr_param_octet_aligned_true, },
@@ -1908,8 +1892,38 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
.expect = {
{ .payload_type_map = {111, 121}, },
{ .payload_type_map = {112, 122} },
- { .payload_type_map = {123, -EINVAL} },
- { .end = true },
+ },
+ },
+ {
+ .descr = "test AMR with differing octet-aligned settings (oa <-> both)",
+ .codecs = {
+ {
+ { 111, "AMR/8000", &amr_param_octet_aligned_true, },
+ },
+ {
+ { 122, "AMR/8000", &amr_param_octet_aligned_false, },
+ { 121, "AMR/8000", &amr_param_octet_aligned_true, },
+ },
+ },
+ .expect = {
+ { .payload_type_map = {111, 121}, },
+ { .payload_type_map = {111, 121}, },
+ },
+ },
+ {
+ .descr = "test AMR with differing octet-aligned settings (bwe <-> both)",
+ .codecs = {
+ {
+ { 112, "AMR/8000", &amr_param_octet_aligned_false, },
+ },
+ {
+ { 122, "AMR/8000", &amr_param_octet_aligned_false, },
+ { 121, "AMR/8000", &amr_param_octet_aligned_true, },
+ },
+ },
+ .expect = {
+ { .payload_type_map = {112, 122}, },
+ { .payload_type_map = {112, 122}, },
},
},
{
@@ -1924,8 +1938,7 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
.expect = {
{ .payload_type_map = {111, 122}, },
- { .payload_type_map = {55, -EINVAL}, },
- { .end = true },
+ { .payload_type_map = {111, 122}, },
},
},
{
@@ -1940,8 +1953,7 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
.expect = {
{ .payload_type_map = {111, 122}, },
- { .payload_type_map = {55, -EINVAL}, },
- { .end = true },
+ { .payload_type_map = {111, 122}, },
},
},
{
@@ -1957,8 +1969,7 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
.expect = {
/* Note: Both 111, anbd 112 will translate to 122. The translation from 112 */
{ .payload_type_map = {112, 122} },
- { .payload_type_map = {55, -EINVAL}, },
- { .end = true },
+ { .payload_type_map = {112, 122}, },
},
},
{
@@ -1974,8 +1985,7 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
.expect = {
/* Note: Both 111, anbd 112 will translate to 122. The translation from 112 */
{ .payload_type_map = {112, 122} },
- { .payload_type_map = {55, -EINVAL}, },
- { .end = true },
+ { .payload_type_map = {112, 122}, },
},
},
{
@@ -1993,11 +2003,8 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
},
.expect = {
- { .payload_type_map = {112, 96}, },
{ .payload_type_map = {0, 0}, },
- { .payload_type_map = {111, 97} },
- { .payload_type_map = {123, -EINVAL} },
- { .end = true },
+ { .payload_type_map = {111, 97}, },
},
},
{
@@ -2015,11 +2022,8 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
},
.expect = {
- { .payload_type_map = {112, 96}, },
{ .payload_type_map = {0, 0}, },
- { .payload_type_map = {111, 97} },
- { .payload_type_map = {123, -EINVAL} },
- { .end = true },
+ { .payload_type_map = {111, 97}, },
},
},
{
@@ -2037,70 +2041,97 @@ static const struct testcase_mgcp_codec_find_convertible test_mgcp_codec_find_co
},
.expect = {
{ .payload_type_map = {111, 121}, },
- { .payload_type_map = {112, -EINVAL} },
- { .payload_type_map = {113, -EINVAL} },
- { .end = true },
+ { .payload_type_map = {111, 121} },
},
},
};
-static int pt_translate(struct mgcp_conn_rtp *conn, unsigned int index_src, unsigned int index_dst, int payload_type)
+static bool codec_decision(struct mgcp_conn_rtp *conn, unsigned int index_conn_src, unsigned int index_conn_dst,
+ const struct testcase_mgcp_codec_decide_expect *expect)
{
- struct mgcp_rtp_codec *codec_src = NULL;
- struct mgcp_rtp_codec *codec_dst = NULL;
- struct mgcp_conn_rtp *conn_src = &conn[index_src];
- struct mgcp_conn_rtp *conn_dst = &conn[index_dst];
-
- /* Find the codec information that is used on the source side */
- codec_src = mgcp_codec_from_pt(conn_src, payload_type);
- if (!codec_src) {
- printf(" - mgcp_codec_from_pt(conn%u, %d) -> NO RESULT\n", index_src, payload_type);
- return -EINVAL;
- }
- printf(" - mgcp_codec_from_pt(conn%u, %d) -> %s\n", index_src, payload_type, codec_src->subtype_name);
+ bool ok = true;
+ int payload_type_conn_src;
+ int payload_type_conn_dst;
+
+ printf(" - mgcp_codec_decide(&conn[%u], &conn[%u]):\n", index_conn_src, index_conn_dst);
+ if (mgcp_codec_decide(&conn[index_conn_src], &conn[index_conn_dst]) != 0) {
+ if (expect->payload_type_map[index_conn_src] == -EINVAL
+ && expect->payload_type_map[index_conn_dst] == -EINVAL)
+ printf(" codec decision failed (expected)!\n");
+ else {
+ printf(" ERROR: codec decision failed!\n");
+ ok = false;
+ }
+ } else {
+ printf(" Codec decision result:\n");
+ if (conn[index_conn_src].end.codec) {
+ payload_type_conn_src = conn[index_conn_src].end.codec->payload_type;
+ printf(" conn[%u]: codec:%s, pt:%d\n",
+ index_conn_src, conn[index_conn_src].end.codec->subtype_name, payload_type_conn_src);
+ } else {
+ payload_type_conn_src = -EINVAL;
+ printf(" conn[%u]: codec:none, pt:none\n", index_conn_src);
+ }
- codec_dst = mgcp_codec_find_convertible(conn_dst, codec_src);
- if (!codec_dst) {
- printf(" - mgcp_codec_find_convertible(conn%u, %s) -> NO RESULT\n", index_dst, codec_src->subtype_name);
- return -EINVAL;
+ if (conn[index_conn_dst].end.codec) {
+ payload_type_conn_dst = conn[index_conn_dst].end.codec->payload_type;
+ printf(" conn[%u]: codec:%s, pt:%d\n",
+ index_conn_dst, conn[index_conn_dst].end.codec->subtype_name,
+ payload_type_conn_dst);
+ } else {
+ payload_type_conn_dst = -EINVAL;
+ printf(" conn[%u]: codec:none, pt:none\n", index_conn_dst);
+ }
+
+ if (payload_type_conn_src != expect->payload_type_map[index_conn_src]) {
+ printf(" ERROR: conn[%u] unexpected codec decision, expected pt=%d, got pt=%d\n",
+ index_conn_src, expect->payload_type_map[index_conn_src], payload_type_conn_src);
+ ok = false;
+ }
+
+ if (payload_type_conn_dst != expect->payload_type_map[index_conn_dst]) {
+ printf(" ERROR: conn[%u] unexpected codec decision, expected pt=%d, got pt=%d\n",
+ index_conn_dst, expect->payload_type_map[index_conn_dst],
+ payload_type_conn_dst);
+ ok = false;
+ }
}
- printf(" - mgcp_codec_find_convertible(conn%u, %s) -> %s -> %u\n",
- index_dst, codec_src->subtype_name, codec_dst->subtype_name, codec_dst->payload_type);
- return codec_dst->payload_type;
+
+ return ok;
}
-static void test_mgcp_codec_find_convertible(void)
+static void test_mgcp_codec_decide(void)
{
int i;
bool ok = true;
printf("\nTesting mgcp_codec_find_convertible()\n");
for (i = 0; i < ARRAY_SIZE(test_mgcp_codec_find_convertible_cases); i++) {
- const struct testcase_mgcp_codec_find_convertible *t = &test_mgcp_codec_find_convertible_cases[i];
- struct mgcp_conn_rtp conn[2] = {};
+ const struct testcase_mgcp_codec_decide *t = &test_mgcp_codec_find_convertible_cases[i];
+ struct mgcp_conn_rtp conn[2] = { };
int rc;
int conn_i;
int c;
printf("#%d: %s\n", i, t->descr);
+ /* Build testvector (add codecs to conn, set properties etc... */
for (conn_i = 0; conn_i < 2; conn_i++) {
printf(" - add codecs on conn%d:\n", conn_i);
for (c = 0; c < ARRAY_SIZE(t->codecs[conn_i]); c++) {
- const struct testcase_mgcp_codec_find_convertible_codec *codec = &t->codecs[conn_i][c];
+ const struct testcase_mgcp_codec_decide_codec *codec = &t->codecs[conn_i][c];
if (!codec->audio_name)
break;
- rc = mgcp_codec_add(&conn[conn_i], codec->payload_type, codec->audio_name, codec->param);
+ rc = mgcp_codec_add(&conn[conn_i], codec->payload_type, codec->audio_name,
+ codec->param);
printf(" %2d: %3d %s%s -> rc=%d\n", c, codec->payload_type, codec->audio_name,
codec->param ?
- (codec->param->amr_octet_aligned_present?
- (codec->param->amr_octet_aligned ?
- " octet-aligned=1" : " octet-aligned=0")
- : " octet-aligned=unset")
- : "",
- rc);
+ (codec->param->amr_octet_aligned_present ?
+ (codec->param->amr_octet_aligned ? " octet-aligned=1" : " octet-aligned=0")
+ : " octet-aligned=unset")
+ : "", rc);
if (rc != codec->expect_rc) {
printf(" ERROR: expected rc=%d\n", codec->expect_rc);
ok = false;
@@ -2110,32 +2141,17 @@ static void test_mgcp_codec_find_convertible(void)
printf(" (none)\n");
}
- for (c = 0; c < ARRAY_SIZE(t->expect); c++) {
- const struct testcase_mgcp_codec_find_convertible_expect *expect = &t->expect[c];
- int result;
-
- if (expect->end)
- break;
-
- result = pt_translate(conn, 0, 1, expect->payload_type_map[0]);
- if (result != expect->payload_type_map[1]) {
- printf(" ERROR: expected -> %d\n", expect->payload_type_map[1]);
- ok = false;
- }
+ /* Run codec decision and check expectation */
+ if (!codec_decision(conn, 0, 1, &t->expect[0]))
+ ok = false;
- /* If the expected result is an error, don't do reverse map test */
- if (expect->payload_type_map[1] < 0)
- continue;
-
- result = pt_translate(conn, 1, 0, expect->payload_type_map[1]);
- if (result != expect->payload_type_map[0]) {
- printf(" ERROR: expected -> %d\n", expect->payload_type_map[0]);
- ok = false;
- }
- }
+ if (!codec_decision(conn, 1, 0, &t->expect[1]))
+ ok = false;
- for (conn_i = 0; conn_i < 2; conn_i++)
- mgcp_codec_reset_all(&conn[conn_i]);
+ if (ok)
+ printf(" ===> SUCCESS: codec decision as expected!\n");
+ else
+ printf(" ===> FAIL: unexpected codec decision!\n");
}
OSMO_ASSERT(ok);
@@ -2295,7 +2311,7 @@ int main(int argc, char **argv)
test_osmux_cid();
test_get_lco_identifier();
test_check_local_cx_options(ctx);
- test_mgcp_codec_find_convertible();
+ test_mgcp_codec_decide();
test_conn_id_matching();
test_e1_trunk_nr_from_epname();
test_mgcp_is_rtp_dummy_payload();
diff --git a/tests/mgcp/mgcp_test.ok b/tests/mgcp/mgcp_test.ok
index 4ea9a34ef..08df5d499 100644
--- a/tests/mgcp/mgcp_test.ok
+++ b/tests/mgcp/mgcp_test.ok
@@ -1286,19 +1286,15 @@ Testing mgcp_codec_find_convertible()
0: 96 AMR/8000/1 octet-aligned=1 -> rc=0
1: 0 PCMU/8000/1 -> rc=0
2: 97 GSM-HR-08/8000/1 -> rc=0
- - mgcp_codec_from_pt(conn0, 112) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 96
- - mgcp_codec_from_pt(conn1, 96) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 112
- - mgcp_codec_from_pt(conn0, 0) -> PCMU
- - mgcp_codec_find_convertible(conn1, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn1, 0) -> PCMU
- - mgcp_codec_find_convertible(conn0, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn0, 111) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
- - mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
- - mgcp_codec_from_pt(conn0, 123) -> NO RESULT
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:112
+ conn[1]: codec:AMR, pt:96
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:96
+ conn[0]: codec:AMR, pt:112
+ ===> SUCCESS: codec decision as expected!
#1: different order and different payload type numbers
- add codecs on conn0:
0: 0 PCMU/8000/1 -> rc=0
@@ -1308,19 +1304,15 @@ Testing mgcp_codec_find_convertible()
0: 97 GSM-HR-08/8000/1 -> rc=0
1: 0 PCMU/8000/1 -> rc=0
2: 96 AMR/8000/1 octet-aligned=1 -> rc=0
- - mgcp_codec_from_pt(conn0, 112) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 96
- - mgcp_codec_from_pt(conn1, 96) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 112
- - mgcp_codec_from_pt(conn0, 0) -> PCMU
- - mgcp_codec_find_convertible(conn1, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn1, 0) -> PCMU
- - mgcp_codec_find_convertible(conn0, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn0, 111) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
- - mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
- - mgcp_codec_from_pt(conn0, 123) -> NO RESULT
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:PCMU, pt:0
+ conn[1]: codec:PCMU, pt:0
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:GSM-HR-08, pt:97
+ conn[0]: codec:GSM-HR-08, pt:111
+ ===> SUCCESS: codec decision as expected!
#2: both sides have the same payload_type numbers assigned to differing codecs
- add codecs on conn0:
0: 0 PCMU/8000/1 -> rc=0
@@ -1330,19 +1322,15 @@ Testing mgcp_codec_find_convertible()
0: 97 GSM-HR-08/8000/1 -> rc=0
1: 0 PCMU/8000/1 -> rc=0
2: 96 AMR/8000/1 octet-aligned=1 -> rc=0
- - mgcp_codec_from_pt(conn0, 96) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
- - mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 96
- - mgcp_codec_from_pt(conn0, 97) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 96
- - mgcp_codec_from_pt(conn1, 96) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 97
- - mgcp_codec_from_pt(conn0, 0) -> PCMU
- - mgcp_codec_find_convertible(conn1, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn1, 0) -> PCMU
- - mgcp_codec_find_convertible(conn0, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn0, 123) -> NO RESULT
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:PCMU, pt:0
+ conn[1]: codec:PCMU, pt:0
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:GSM-HR-08, pt:97
+ conn[0]: codec:GSM-HR-08, pt:96
+ ===> SUCCESS: codec decision as expected!
#3: conn0 has no codecs
- add codecs on conn0:
(none)
@@ -1350,9 +1338,13 @@ Testing mgcp_codec_find_convertible()
0: 96 AMR/8000/1 octet-aligned=1 -> rc=0
1: 0 PCMU/8000/1 -> rc=0
2: 97 GSM-HR-08/8000/1 -> rc=0
- - mgcp_codec_from_pt(conn0, 112) -> NO RESULT
- - mgcp_codec_from_pt(conn0, 0) -> NO RESULT
- - mgcp_codec_from_pt(conn0, 111) -> NO RESULT
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ codec decision failed (expected)!
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:96
+ conn[0]: codec:none, pt:none
+ ===> SUCCESS: codec decision as expected!
#4: conn1 has no codecs
- add codecs on conn0:
0: 112 AMR/8000/1 octet-aligned=1 -> rc=0
@@ -1360,69 +1352,116 @@ Testing mgcp_codec_find_convertible()
2: 111 GSM-HR-08/8000/1 -> rc=0
- add codecs on conn1:
(none)
- - mgcp_codec_from_pt(conn0, 112) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> NO RESULT
- - mgcp_codec_from_pt(conn0, 0) -> PCMU
- - mgcp_codec_find_convertible(conn1, PCMU) -> NO RESULT
- - mgcp_codec_from_pt(conn0, 111) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn1, GSM-HR-08) -> NO RESULT
-#5: test AMR with differing octet-aligned settings
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:112
+ conn[1]: codec:none, pt:none
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ codec decision failed (expected)!
+ ===> SUCCESS: codec decision as expected!
+#5: test AMR with differing octet-aligned settings (both <-> both)
- add codecs on conn0:
0: 111 AMR/8000 octet-aligned=1 -> rc=0
1: 112 AMR/8000 octet-aligned=0 -> rc=0
- add codecs on conn1:
0: 122 AMR/8000 octet-aligned=0 -> rc=0
1: 121 AMR/8000 octet-aligned=1 -> rc=0
- - mgcp_codec_from_pt(conn0, 111) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 121
- - mgcp_codec_from_pt(conn1, 121) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 111
- - mgcp_codec_from_pt(conn0, 112) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
- - mgcp_codec_from_pt(conn1, 122) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 112
- - mgcp_codec_from_pt(conn0, 123) -> NO RESULT
-#6: test AMR with missing octet-aligned settings (oa <-> unset)
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:111
+ conn[1]: codec:AMR, pt:121
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:122
+ conn[0]: codec:AMR, pt:112
+ ===> SUCCESS: codec decision as expected!
+#6: test AMR with differing octet-aligned settings (oa <-> both)
+ - add codecs on conn0:
+ 0: 111 AMR/8000 octet-aligned=1 -> rc=0
+ - add codecs on conn1:
+ 0: 122 AMR/8000 octet-aligned=0 -> rc=0
+ 1: 121 AMR/8000 octet-aligned=1 -> rc=0
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:111
+ conn[1]: codec:AMR, pt:121
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:121
+ conn[0]: codec:AMR, pt:111
+ ===> SUCCESS: codec decision as expected!
+#7: test AMR with differing octet-aligned settings (bwe <-> both)
+ - add codecs on conn0:
+ 0: 112 AMR/8000 octet-aligned=0 -> rc=0
+ - add codecs on conn1:
+ 0: 122 AMR/8000 octet-aligned=0 -> rc=0
+ 1: 121 AMR/8000 octet-aligned=1 -> rc=0
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:112
+ conn[1]: codec:AMR, pt:122
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:122
+ conn[0]: codec:AMR, pt:112
+ ===> SUCCESS: codec decision as expected!
+#8: test AMR with missing octet-aligned settings (oa <-> unset)
- add codecs on conn0:
0: 111 AMR/8000 octet-aligned=1 -> rc=0
- add codecs on conn1:
0: 122 AMR/8000 octet-aligned=unset -> rc=0
- - mgcp_codec_from_pt(conn0, 111) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
- - mgcp_codec_from_pt(conn1, 122) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 111
- - mgcp_codec_from_pt(conn0, 55) -> NO RESULT
-#7: test AMR with missing octet-aligned settings (bwe <-> unset)
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:111
+ conn[1]: codec:AMR, pt:122
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:122
+ conn[0]: codec:AMR, pt:111
+ ===> SUCCESS: codec decision as expected!
+#9: test AMR with missing octet-aligned settings (bwe <-> unset)
- add codecs on conn0:
0: 111 AMR/8000 octet-aligned=0 -> rc=0
- add codecs on conn1:
0: 122 AMR/8000 octet-aligned=unset -> rc=0
- - mgcp_codec_from_pt(conn0, 111) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
- - mgcp_codec_from_pt(conn1, 122) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 111
- - mgcp_codec_from_pt(conn0, 55) -> NO RESULT
-#8: test AMR with NULL param (oa <-> null)
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:111
+ conn[1]: codec:AMR, pt:122
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:122
+ conn[0]: codec:AMR, pt:111
+ ===> SUCCESS: codec decision as expected!
+#10: test AMR with NULL param (oa <-> null)
- add codecs on conn0:
0: 112 AMR/8000 octet-aligned=1 -> rc=0
- add codecs on conn1:
0: 122 AMR/8000 -> rc=0
- - mgcp_codec_from_pt(conn0, 112) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
- - mgcp_codec_from_pt(conn1, 122) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 112
- - mgcp_codec_from_pt(conn0, 55) -> NO RESULT
-#9: test AMR with NULL param (bwe <-> null)
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:112
+ conn[1]: codec:AMR, pt:122
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:122
+ conn[0]: codec:AMR, pt:112
+ ===> SUCCESS: codec decision as expected!
+#11: test AMR with NULL param (bwe <-> null)
- add codecs on conn0:
0: 112 AMR/8000 octet-aligned=0 -> rc=0
- add codecs on conn1:
0: 122 AMR/8000 -> rc=0
- - mgcp_codec_from_pt(conn0, 112) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 122
- - mgcp_codec_from_pt(conn1, 122) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 112
- - mgcp_codec_from_pt(conn0, 55) -> NO RESULT
-#10: match FOO/8000/1 and FOO/8000 as identical, single channel is implicit
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:AMR, pt:112
+ conn[1]: codec:AMR, pt:122
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:AMR, pt:122
+ conn[0]: codec:AMR, pt:112
+ ===> SUCCESS: codec decision as expected!
+#12: match FOO/8000/1 and FOO/8000 as identical, single channel is implicit
- add codecs on conn0:
0: 0 PCMU/8000/1 -> rc=0
1: 111 GSM-HR-08/8000/1 -> rc=0
@@ -1431,20 +1470,16 @@ Testing mgcp_codec_find_convertible()
0: 97 GSM-HR-08/8000 -> rc=0
1: 0 PCMU/8000 -> rc=0
2: 96 AMR/8000 octet-aligned=1 -> rc=0
- - mgcp_codec_from_pt(conn0, 112) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 96
- - mgcp_codec_from_pt(conn1, 96) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 112
- - mgcp_codec_from_pt(conn0, 0) -> PCMU
- - mgcp_codec_find_convertible(conn1, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn1, 0) -> PCMU
- - mgcp_codec_find_convertible(conn0, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn0, 111) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
- - mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
- - mgcp_codec_from_pt(conn0, 123) -> NO RESULT
-#11: match FOO/8000/1 and FOO as identical, 8k and single channel are implicit
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:PCMU, pt:0
+ conn[1]: codec:PCMU, pt:0
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:GSM-HR-08, pt:97
+ conn[0]: codec:GSM-HR-08, pt:111
+ ===> SUCCESS: codec decision as expected!
+#13: match FOO/8000/1 and FOO as identical, 8k and single channel are implicit
- add codecs on conn0:
0: 0 PCMU/8000/1 -> rc=0
1: 111 GSM-HR-08/8000/1 -> rc=0
@@ -1453,20 +1488,16 @@ Testing mgcp_codec_find_convertible()
0: 97 GSM-HR-08 -> rc=0
1: 0 PCMU -> rc=0
2: 96 AMR octet-aligned=1 -> rc=0
- - mgcp_codec_from_pt(conn0, 112) -> AMR
- - mgcp_codec_find_convertible(conn1, AMR) -> AMR -> 96
- - mgcp_codec_from_pt(conn1, 96) -> AMR
- - mgcp_codec_find_convertible(conn0, AMR) -> AMR -> 112
- - mgcp_codec_from_pt(conn0, 0) -> PCMU
- - mgcp_codec_find_convertible(conn1, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn1, 0) -> PCMU
- - mgcp_codec_find_convertible(conn0, PCMU) -> PCMU -> 0
- - mgcp_codec_from_pt(conn0, 111) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 97
- - mgcp_codec_from_pt(conn1, 97) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
- - mgcp_codec_from_pt(conn0, 123) -> NO RESULT
-#12: test whether channel number matching is waterproof
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:PCMU, pt:0
+ conn[1]: codec:PCMU, pt:0
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:GSM-HR-08, pt:97
+ conn[0]: codec:GSM-HR-08, pt:111
+ ===> SUCCESS: codec decision as expected!
+#14: test whether channel number matching is waterproof
- add codecs on conn0:
0: 111 GSM-HR-08/8000 -> rc=0
1: 112 GSM-HR-08/8000/2 -> rc=-22
@@ -1474,12 +1505,15 @@ Testing mgcp_codec_find_convertible()
- add codecs on conn1:
0: 122 GSM-HR-08/8000/2 -> rc=-22
1: 121 GSM-HR-08/8000/1 -> rc=0
- - mgcp_codec_from_pt(conn0, 111) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn1, GSM-HR-08) -> GSM-HR-08 -> 121
- - mgcp_codec_from_pt(conn1, 121) -> GSM-HR-08
- - mgcp_codec_find_convertible(conn0, GSM-HR-08) -> GSM-HR-08 -> 111
- - mgcp_codec_from_pt(conn0, 112) -> NO RESULT
- - mgcp_codec_from_pt(conn0, 113) -> NO RESULT
+ - mgcp_codec_decide(&conn[0], &conn[1]):
+ Codec decision result:
+ conn[0]: codec:GSM-HR-08, pt:111
+ conn[1]: codec:GSM-HR-08, pt:121
+ - mgcp_codec_decide(&conn[1], &conn[0]):
+ Codec decision result:
+ conn[1]: codec:GSM-HR-08, pt:121
+ conn[0]: codec:GSM-HR-08, pt:111
+ ===> SUCCESS: codec decision as expected!
Testing test_conn_id_matching
needle='23AB' found '000023AB'