implement intelligent matching of AMR fmtp
Change-Id: I5a1e11e762a0ac511085377aeeb0a371fd2940f5
This commit is contained in:
parent
cf3886b0eb
commit
a53177098f
|
@ -22,6 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <osmocom/core/utils.h>
|
#include <osmocom/core/utils.h>
|
||||||
|
@ -37,6 +38,49 @@ bool sdp_audio_codec_is_set(const struct sdp_audio_codec *a)
|
||||||
return a && a->subtype_name[0];
|
return a && a->subtype_name[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void strip_whitespace(char *str)
|
||||||
|
{
|
||||||
|
char *i = str;
|
||||||
|
char *o = str;
|
||||||
|
for (; *i; i++, o++) {
|
||||||
|
while (isspace(*i))
|
||||||
|
i++;
|
||||||
|
*o = *i;
|
||||||
|
if (!*i)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amr_fmtp_match(const char *a, const char *b)
|
||||||
|
{
|
||||||
|
char a_modeset[32] = {};
|
||||||
|
char b_modeset[32] = {};
|
||||||
|
|
||||||
|
/* octet-align=1. Omission means octet-align=0 */
|
||||||
|
if (osmo_sdp_fmtp_amr_is_octet_aligned(a) != osmo_sdp_fmtp_amr_is_octet_aligned(b))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* mode-set=0,1,2,3,4,5,6,7. Omission of 'mode-set' means, match any and all codec modes. So if either a or b
|
||||||
|
* have no 'mode-set', it's a match. If both have one, they must be identical to match. We expect the
|
||||||
|
* mode-set string to be in ascending order. */
|
||||||
|
if (osmo_sdp_fmtp_get_val(a_modeset, sizeof(a_modeset), a, "mode-set")
|
||||||
|
&& osmo_sdp_fmtp_get_val(b_modeset, sizeof(b_modeset), b, "mode-set")) {
|
||||||
|
/* Strip whitespace: We don't know what remote SDP peers may throw at us. There could be whitespace
|
||||||
|
* around the separators like 'mode-set=2,3 ; octet-align=1', which may show up here as whitespace in
|
||||||
|
* the value string as "2,3 ", which would mismatch "2,3". */
|
||||||
|
strip_whitespace(a_modeset);
|
||||||
|
strip_whitespace(b_modeset);
|
||||||
|
if (strcmp(a_modeset, b_modeset))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: treat other AMR traits, see RFC4867 8.1. Maybe generically match all values that are present?
|
||||||
|
* So far we have not seen any peer use other values than octet-align and mode-set. */
|
||||||
|
|
||||||
|
/* No mismatch found, it's a match */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compare name, rate and fmtp, returning typical cmp result: 0 on match, and -1 / 1 on mismatch.
|
/* Compare name, rate and fmtp, returning typical cmp result: 0 on match, and -1 / 1 on mismatch.
|
||||||
* If cmp_fmtp is false, do *not* compare the fmtp string; if true, compare fmtp 1:1 as strings.
|
* If cmp_fmtp is false, do *not* compare the fmtp string; if true, compare fmtp 1:1 as strings.
|
||||||
* If cmp_payload_type is false, do *not* compare the payload_type number.
|
* If cmp_payload_type is false, do *not* compare the payload_type number.
|
||||||
|
@ -60,6 +104,11 @@ int sdp_audio_codec_cmp(const struct sdp_audio_codec *a, const struct sdp_audio_
|
||||||
return cmp;
|
return cmp;
|
||||||
if (cmp_fmtp) {
|
if (cmp_fmtp) {
|
||||||
cmp = strncmp(a->fmtp, b->fmtp, sizeof(a->fmtp));
|
cmp = strncmp(a->fmtp, b->fmtp, sizeof(a->fmtp));
|
||||||
|
/* In case of AMR, allow logical matching; we only need to do that if the strings differ. */
|
||||||
|
if (cmp
|
||||||
|
&& !strcmp("AMR", a->subtype_name)
|
||||||
|
&& amr_fmtp_match(a->fmtp, b->fmtp))
|
||||||
|
cmp = 0;
|
||||||
if (cmp)
|
if (cmp)
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ AM_LDFLAGS = \
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(top_builddir)/src/libmsc/libmsc.a \
|
$(top_builddir)/src/libmsc/libmsc.a \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
|
$(LIBOSMOMGCPCLIENT_LIBS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
|
Loading…
Reference in New Issue