mgw: Support uppercase LCO options
MGCP RFC3435 (https://tools.ietf.org/html/rfc3435) states almost all
text has to be handled in a case-insensitive way, except SDP parts.
Related: OS#4001
Change-Id: Ic28a5eacc4c441d68e8a20d2743956ab2e01125d
diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c
index 74926ad..9baf50d 100644
--- a/src/libosmo-mgcp/mgcp_protocol.c
+++ b/src/libosmo-mgcp/mgcp_protocol.c
@@ -590,7 +590,7 @@
static int set_local_cx_options(void *ctx, struct mgcp_lco *lco,
const char *options)
{
- char *p_opt, *a_opt;
+ char *lco_id;
char codec[17];
if (!options)
@@ -608,18 +608,33 @@
talloc_free(lco->string);
lco->string = talloc_strdup(ctx, options);
- p_opt = strstr(lco->string, "p:");
- if (p_opt && sscanf(p_opt, "p:%d-%d",
- &lco->pkt_period_min, &lco->pkt_period_max) == 1)
- lco->pkt_period_max = lco->pkt_period_min;
+ lco_id = lco->string;
+ while ((lco_id = get_lco_identifier(lco_id))) {
+ switch (tolower(lco_id[0])) {
+ case 'p':
+ if (sscanf(lco_id + 1, ":%d-%d",
+ &lco->pkt_period_min, &lco->pkt_period_max) == 1)
+ lco->pkt_period_max = lco->pkt_period_min;
+ break;
+ case 'a':
+ /* FIXME: LCO also supports the negotiation of more then one codec.
+ * (e.g. a:PCMU;G726-32) But this implementation only supports a single
+ * codec only. */
+ if (sscanf(lco_id + 1, ":%16[^,]", codec) == 1) {
+ talloc_free(lco->codec);
+ lco->codec = talloc_strdup(ctx, codec);
+ }
+ break;
+ default:
+ LOGP(DLMGCP, LOGL_NOTICE,
+ "LCO: unhandled option: '%c'/%d in \"%s\"\n",
+ *lco_id, *lco_id, lco->string);
+ break;
+ }
- /* FIXME: LCO also supports the negotiation of more then one codec.
- * (e.g. a:PCMU;G726-32) But this implementation only supports a single
- * codec only. */
- a_opt = strstr(lco->string, "a:");
- if (a_opt && sscanf(a_opt, "a:%16[^,]", codec) == 1) {
- talloc_free(lco->codec);
- lco->codec = talloc_strdup(ctx, codec);
+ lco_id = strchr(lco_id, ',');
+ if (!lco_id)
+ break;
}
LOGP(DLMGCP, LOGL_DEBUG,
diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c
index c4931b2..ab6d0ce 100644
--- a/tests/mgcp/mgcp_test.c
+++ b/tests/mgcp/mgcp_test.c
@@ -208,8 +208,24 @@
"a=rtpmap:99 AMR/8000\r\n" \
"a=ptime:40\r\n"
-#define MDCX4_SO \
+/* Test different upper/lower case in options */
+#define MDCX4_PT4 \
"MDCX 18983220 1@mgw MGCP 1.0\r\n" \
+ "M: sendrecv\r" \
+ "C: 2\r\n" \
+ "I: %s\r\n" \
+ "L: A:AMR, NT:IN\r\n" \
+ "\n" \
+ "v=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" \
+ "a=rtpmap:99 AMR/8000\r\n" \
+ "a=ptime:40\r\n"
+
+#define MDCX4_SO \
+ "MDCX 18983221 1@mgw MGCP 1.0\r\n" \
"M: sendonly\r" \
"C: 2\r\n" \
"I: %s\r\n" \
@@ -224,17 +240,17 @@
"a=ptime:40\r\n"
#define MDCX4_RO \
- "MDCX 18983221 1@mgw MGCP 1.0\r\n" \
+ "MDCX 18983222 1@mgw MGCP 1.0\r\n" \
"M: recvonly\r" \
"C: 2\r\n" \
"I: %s\r\n" \
"L: p:20, a:AMR, nt:IN\r\n"
#define MDCX_TOO_LONG_CI \
- "MDCX 18983222 1@mgw MGCP 1.0\r\n" \
+ "MDCX 18983223 1@mgw MGCP 1.0\r\n" \
"I: 123456789012345678901234567890123\n"
-#define MDCX_TOO_LONG_CI_RET "510 18983222 FAIL\r\n"
+#define MDCX_TOO_LONG_CI_RET "510 18983223 FAIL\r\n"
#define SHORT2 "CRCX 1"
#define SHORT2_RET "510 000000 FAIL\r\n"
@@ -526,8 +542,9 @@
{"MDCX4_PT1", MDCX4_PT1, MDCX4_RET("18983217"), 99},
{"MDCX4_PT2", MDCX4_PT2, MDCX4_RET("18983218"), 99},
{"MDCX4_PT3", MDCX4_PT3, MDCX4_RET("18983219"), 99},
- {"MDCX4_SO", MDCX4_SO, MDCX4_RET("18983220"), 99},
- {"MDCX4_RO", MDCX4_RO, MDCX4_RO_RET("18983221"), PTYPE_IGNORE},
+ {"MDCX4_PT4", MDCX4_PT4, MDCX4_RET("18983220"), 99},
+ {"MDCX4_SO", MDCX4_SO, MDCX4_RET("18983221"), 99},
+ {"MDCX4_RO", MDCX4_RO, MDCX4_RO_RET("18983222"), PTYPE_IGNORE},
{"DLCX", DLCX, DLCX_RET, PTYPE_IGNORE},
{"CRCX_ZYN", CRCX_ZYN, CRCX_ZYN_RET, 97},
{"EMPTY", EMPTY, EMPTY_RET},
diff --git a/tests/mgcp/mgcp_test.ok b/tests/mgcp/mgcp_test.ok
index d21eaa1..3929d79 100644
--- a/tests/mgcp/mgcp_test.ok
+++ b/tests/mgcp/mgcp_test.ok
Binary files differ