neels has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-mgw/+/35434?usp=email )


Change subject: add fmtp.h
......................................................................

add fmtp.h

Upcoming patches will add handling of arbitrary ftmp strings to
osmo-mgw as well as libosmo-mgcp-client
(If58590bda8627519ff07e0b6f43aa47a274f052b).

Add generic API for handling ftmp strings. The primary intended user is
osmo-mgw, but this is also generally useful to libosmo-mgcp-client
callers for parsing the received fmtp.

We discussed that fmtp.[hc] should be published in libosmo-mgcp-client,
but also built within osmo-mgw. Hence:
- put fmtp.h and .c in libosmo-mgcp-client/
- in osmo-mgw code, use #include <mgcp_client/fmtp.h> and build the
  src/libosmo-mgcp-client/fmtp.c also into libosmo-mgcp.a.

(This is currently the quickest solution and without side effects since
fmtp.c is fully self-contained; an alternative would be adding a
not-installed libmgcp-common.a within the build tree)

Change-Id: I3eaea353dbd98c19212199b564342d0ac16cbc07
---
M include/Makefile.am
A include/osmocom/mgcp_client/fmtp.h
M src/libosmo-mgcp-client/Makefile.am
A src/libosmo-mgcp-client/fmtp.c
M src/libosmo-mgcp/Makefile.am
5 files changed, 179 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/34/35434/1

diff --git a/include/Makefile.am b/include/Makefile.am
index c72cba8..031e7e6 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -8,6 +8,7 @@
        osmocom/mgcp_client/mgcp_client_endpoint_fsm.h \
        osmocom/mgcp_client/mgcp_client_fsm.h \
        osmocom/mgcp_client/mgcp_client_pool.h \
+       osmocom/mgcp_client/fmtp.h \
        $(NULL)

 noinst_HEADERS = \
diff --git a/include/osmocom/mgcp_client/fmtp.h 
b/include/osmocom/mgcp_client/fmtp.h
new file mode 100644
index 0000000..863fc01
--- /dev/null
+++ b/include/osmocom/mgcp_client/fmtp.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdbool.h>
+
+#define OSMO_SDP_NAME_A "a"
+#define OSMO_SDP_NAME_FMTP "fmtp"
+#define OSMO_SDP_NAME_AMR_OCTET_ALIGN "octet-align"
+
+#define OSMO_SDP_VAL_AMR_OCTET_ALIGN_0 OSMO_SDP_NAME_AMR_OCTET_ALIGN "=0"
+#define OSMO_SDP_VAL_AMR_OCTET_ALIGN_1 OSMO_SDP_NAME_AMR_OCTET_ALIGN "=1"
+
+/* "fmtp:" */
+#define OSMO_SDP_PREFIX_FMTP OSMO_SDP_NAME_FMTP ":"
+/* "a=fmtp:" */
+#define OSMO_SDP_PREFIX_A_FMTP OSMO_SDP_NAME_A "=" OSMO_SDP_PREFIX_FMTP
+
+bool osmo_sdp_fmtp_get_val(char *val, size_t val_size, const char *fmtp, const 
char *option_name);
+int osmo_sdp_fmtp_get_int(const char *fmtp, const char *option_name, int 
default_value);
+
+/* Some AMR related fmtp parameters as in 
https://www.rfc-editor.org/rfc/rfc4867#section-8.1 that osmo-mgw needs.*/
+bool osmo_sdp_fmtp_amr_is_octet_aligned(const char *fmtp);
+
+/*! To compose AMR related fmtp indicating octet-align.
+ * Usage:
+ *   printf("%s", OSMO_SDP_AMR_SET_OCTET_ALIGN(oa_flag));
+ */
+#define OSMO_SDP_AMR_SET_OCTET_ALIGN(VAL) \
+       ((VAL) ? OSMO_SDP_VAL_AMR_OCTET_ALIGN_1 : 
OSMO_SDP_VAL_AMR_OCTET_ALIGN_0 )
diff --git a/src/libosmo-mgcp-client/Makefile.am 
b/src/libosmo-mgcp-client/Makefile.am
index b2bed9a..e120289 100644
--- a/src/libosmo-mgcp-client/Makefile.am
+++ b/src/libosmo-mgcp-client/Makefile.am
@@ -31,6 +31,7 @@
        mgcp_client_fsm.c \
        mgcp_client_endpoint_fsm.c \
        mgcp_client_pool.c \
+       fmtp.c \
        $(NULL)

 libosmo_mgcp_client_la_LDFLAGS = \
diff --git a/src/libosmo-mgcp-client/fmtp.c b/src/libosmo-mgcp-client/fmtp.c
new file mode 100644
index 0000000..b7a8bd9
--- /dev/null
+++ b/src/libosmo-mgcp-client/fmtp.c
@@ -0,0 +1,120 @@
+/*
+ * (C) 2023-2015 by sysmocom - s.f.m.c. GmbH <[email protected]>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <string.h>
+#include <ctype.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/mgcp_client/fmtp.h>
+
+static const char *fmtp_next_option(const char *fmtp)
+{
+       for (; fmtp && *fmtp && *fmtp != ';'; fmtp++);
+       for (; fmtp && isspace(*fmtp); fmtp++);
+       return fmtp;
+}
+
+/*! Parse a given SDP fmtp value string, returning the value of a specific 
option, if present.
+ *
+ * Example:
+ *
+ *   const char *fmtp_vals = "octet-align=1;mode-set=0,2,4,7";
+ *
+ *   char res[23];
+ *   if (osmo_sdp_fmtp_get_val(res, sizeof(res), fmtp_vals, "mode-set"))
+ *           use_modeset(res);
+ *   else
+ *           use_modeset(MY_DEFAULT_MODESET);
+ *
+ * \param[out] val  Buffer to write the option's value to.
+ * \param[in] val_size  Space available in val.
+ * \param[in] fmtp  fmtp value string to parse -- must not contain the 
"a=fmtp:N " prefix, only the value part.
+ * \param[in] option_name  Which fmtp option to get the value for.
+ * \return true when the option was found, false when it was not present.
+ */
+bool osmo_sdp_fmtp_get_val(char *val, size_t val_size, const char *fmtp, const 
char *option_name)
+{
+       const char *pos = fmtp;
+       const char *end;
+       int option_name_len = strlen(option_name);
+       for (; pos && *pos; pos = fmtp_next_option(pos)) {
+               if (!osmo_str_startswith(pos, option_name))
+                       continue;
+               pos += option_name_len;
+               if (*pos != '=')
+                       continue;
+               pos++;
+               break;
+       }
+
+       if (!pos || !*pos)
+               return false;
+
+       end = fmtp_next_option(pos);
+       OSMO_ASSERT(end);
+       if (val && val_size)
+               osmo_strlcpy(val, pos, OSMO_MIN(val_size, end - pos + 1));
+       return true;
+}
+
+/*! Parse a given SDP fmtp value string, returning the value of a specific 
integer option, if present.
+ *
+ * Example:
+ *
+ *   const char *fmtp_vals = "octet-align=1;mode-set=0,2,4,7";
+ *   bool oa = osmo_sdp_fmtp_get_int(fmtp_vals, OSMO_SDP_AMR_OCTET_ALIGN_NAME, 
1);
+ *
+ * \param[in] fmtp  fmtp value string to parse -- must not contain the 
"a=fmtp:N " prefix, only the value part.
+ * \param[in] option_name  Which fmtp option to get the value for.
+ * \param[in] default_value  If option_name is not present or cannot be parsed 
as integer, return this instead.
+ * \return the integer value when the option was found and actually an 
integer, default_value otherwise.
+ */
+int osmo_sdp_fmtp_get_int(const char *fmtp, const char *option_name, int 
default_value)
+{
+       char val[128];
+       if (!osmo_sdp_fmtp_get_val(val, sizeof(val), fmtp, option_name))
+               return default_value;
+       if (!val[0])
+               return default_value;
+       int i;
+       if (osmo_str_to_int(&i, val, 10, 0, 1)) {
+               /* error parsing number */
+               LOGP(DLMGCP, LOGL_ERROR, "Invalid number in fmtp parameter 
'%s': '%s'\n", option_name, val);
+               return default_value;
+       }
+       return i;
+}
+
+/*! Return true if octet-align is present and set to 1 in the given AMR 
related fmtp value.
+ * Default to octet-align=0, i.e. bandwidth-efficient mode.
+ *
+ * See RFC4867 "RTP Payload Format for AMR and AMR-WB" sections "8.1. AMR 
Media Type Registration" and "8.2. AMR-WB
+ * Media Type Registration":
+ *
+ *    octet-align: Permissible values are 0 and 1.  If 1, octet-align
+ *                 operation SHALL be used.  If 0 or if not present,
+ *                 bandwidth-efficient operation is employed.
+ *
+ * https://tools.ietf.org/html/rfc4867
+ */
+bool osmo_sdp_fmtp_amr_is_octet_aligned(const char *fmtp)
+{
+       return osmo_sdp_fmtp_get_int(fmtp, OSMO_SDP_NAME_AMR_OCTET_ALIGN, 0) == 
1;
+}
diff --git a/src/libosmo-mgcp/Makefile.am b/src/libosmo-mgcp/Makefile.am
index fa9a8eb..23c6b52 100644
--- a/src/libosmo-mgcp/Makefile.am
+++ b/src/libosmo-mgcp/Makefile.am
@@ -42,4 +42,5 @@
        mgcp_ratectr.c \
        mgcp_e1.c \
        mgcp_iuup.c \
+       $(top_srcdir)/src/libosmo-mgcp-client/fmtp.c \
        $(NULL)

--
To view, visit https://gerrit.osmocom.org/c/osmo-mgw/+/35434?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-Change-Id: I3eaea353dbd98c19212199b564342d0ac16cbc07
Gerrit-Change-Number: 35434
Gerrit-PatchSet: 1
Gerrit-Owner: neels <[email protected]>
Gerrit-MessageType: newchange

Reply via email to