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.orgdexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-mgw/+/18372 )
Change subject: osmo-mgw: refactor endpoint and trunk handling
......................................................................
osmo-mgw: refactor endpoint and trunk handling
The trunk and endpoint handling in osmo-mgw is still very complex and
implemented in various placed (mostly mgcp_protocol.c). Also we use
still integers for endpoint identification, which is not flexible enough
to address timeslots/subslots on an E1 trunk. Some refactoring is
needed.
- get rid of integers as endpoint identifiers, use strings instead and
find the endpoint based on its string name on the trunk.
- identify the trunk based on the trunk prefix given in the endpoint
name.
- rename struct mgcp_trunk_config to mgcp_trunk and "tcfg" to "trunk"
in order to better match the reality.
- refactor trunk and endpoint allocation. Aggregate functionality in
in mgcp_endp.c and mgcp_trunk.c.
Change-Id: Ice8aaf03faa2fd99074f8665eea3a696d30c5eb3
Related: OS#2659
---
M include/osmocom/mgcp/Makefile.am
M include/osmocom/mgcp/mgcp.h
M include/osmocom/mgcp/mgcp_common.h
M include/osmocom/mgcp/mgcp_endp.h
M include/osmocom/mgcp/mgcp_internal.h
A include/osmocom/mgcp/mgcp_trunk.h
A include/osmocom/mgcp_client/mgcp_common.h
M src/libosmo-mgcp/Makefile.am
M src/libosmo-mgcp/mgcp_codec.c
M src/libosmo-mgcp/mgcp_conn.c
M src/libosmo-mgcp/mgcp_endp.c
M src/libosmo-mgcp/mgcp_msg.c
M src/libosmo-mgcp/mgcp_network.c
M src/libosmo-mgcp/mgcp_osmux.c
M src/libosmo-mgcp/mgcp_protocol.c
M src/libosmo-mgcp/mgcp_sdp.c
A src/libosmo-mgcp/mgcp_trunk.c
M src/libosmo-mgcp/mgcp_vty.c
M src/osmo-mgw/mgw_main.c
M tests/mgcp/mgcp_test.c
20 files changed, 1,054 insertions(+), 782 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/72/18372/1
diff --git a/include/osmocom/mgcp/Makefile.am b/include/osmocom/mgcp/Makefile.am
index 036b4ca..0d5f5f6 100644
--- a/include/osmocom/mgcp/Makefile.am
+++ b/include/osmocom/mgcp/Makefile.am
@@ -7,5 +7,6 @@
mgcp_sdp.h \
mgcp_codec.h \
mgcp_ctrl.h \
+ mgcp_trunk.h \
debug.h \
$(NULL)
diff --git a/include/osmocom/mgcp/mgcp.h b/include/osmocom/mgcp/mgcp.h
index 43f480e..99c12a1 100644
--- a/include/osmocom/mgcp/mgcp.h
+++ b/include/osmocom/mgcp/mgcp.h
@@ -42,7 +42,7 @@
*/
struct mgcp_endpoint;
struct mgcp_config;
-struct mgcp_trunk_config;
+struct mgcp_trunk;
struct mgcp_rtp_end;
#define MGCP_ENDP_CRCX 1
@@ -59,10 +59,9 @@
#define MGCP_POLICY_REJECT 5
#define MGCP_POLICY_DEFER 6
-typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint);
-typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state);
-typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id);
-typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg);
+typedef int (*mgcp_change)(struct mgcp_endpoint *endp, int state);
+typedef int (*mgcp_policy)(struct mgcp_endpoint *endp, int state, const char *transaction_id);
+typedef int (*mgcp_reset)(struct mgcp_trunk *cfg);
typedef int (*mgcp_rqnt)(struct mgcp_endpoint *endp, char tone);
/**
@@ -178,57 +177,6 @@
MGCP_DLCX_DEFERRED_BY_POLICY,
};
-struct mgcp_trunk_config {
- struct llist_head entry;
-
- struct mgcp_config *cfg;
-
- int trunk_nr;
- int trunk_type;
-
- char *audio_fmtp_extra;
- char *audio_name;
- int audio_payload;
- int audio_send_ptime;
- int audio_send_name;
- int audio_loop;
-
- int no_audio_transcoding;
-
- int omit_rtcp;
- int keepalive_interval;
-
- /* RTP patching */
- int force_constant_ssrc; /* 0: don't, 1: once */
- int force_aligned_timing;
- bool rfc5993_hr_convert;
-
- /* spec handling */
- int force_realloc;
-
- /* timer */
- struct osmo_timer_list keepalive_timer;
-
- /* When set, incoming RTP packets are not filtered
- * when ports and ip-address do not match (debug) */
- int rtp_accept_all;
-
- unsigned int number_endpoints;
- int vty_number_endpoints;
- struct mgcp_endpoint *endpoints;
-
- /* Rate counter group which contains stats for generic MGCP events. */
- struct rate_ctr_group *mgcp_general_ctr_group;
- /* Rate counter group which contains stats for processed CRCX commands. */
- struct rate_ctr_group *mgcp_crcx_ctr_group;
- /* Rate counter group which contains stats for processed MDCX commands. */
- struct rate_ctr_group *mgcp_mdcx_ctr_group;
- /* Rate counter group which contains stats for processed DLCX commands. */
- struct rate_ctr_group *mgcp_dlcx_ctr_group;
- /* Rate counter group which aggregates stats of individual RTP connections. */
- struct rate_ctr_group *all_rtp_conn_stats;
-};
-
enum mgcp_role {
MGCP_BSC = 0,
MGCP_BSC_NAT,
@@ -256,14 +204,13 @@
mgcp_change change_cb;
mgcp_policy policy_cb;
mgcp_reset reset_cb;
- mgcp_realloc realloc_cb;
mgcp_rqnt rqnt_cb;
void *data;
uint32_t last_call_id;
/* trunk handling */
- struct mgcp_trunk_config trunk;
+ struct mgcp_trunk *trunk;
struct llist_head trunks;
enum mgcp_role role;
@@ -301,8 +248,7 @@
int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
enum mgcp_role role);
int mgcp_vty_init(void);
-int mgcp_endpoints_allocate(struct mgcp_trunk_config *cfg);
-void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval);
+void mgcp_trunk_set_keepalive(struct mgcp_trunk *trunk, int interval);
/*
* format helper functions
@@ -310,7 +256,7 @@
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
-int mgcp_send_reset_ep(struct mgcp_endpoint *endp, int endpoint);
+int mgcp_send_reset_ep(struct mgcp_endpoint *endp);
int mgcp_send_reset_all(struct mgcp_config *cfg);
diff --git a/include/osmocom/mgcp/mgcp_common.h b/include/osmocom/mgcp/mgcp_common.h
index a1bbb19..07d8d37 100644
--- a/include/osmocom/mgcp/mgcp_common.h
+++ b/include/osmocom/mgcp/mgcp_common.h
@@ -100,6 +100,10 @@
/* A prefix to denote the virtual trunk (RTP on both ends) */
#define MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK "rtpbridge/"
+/* A prefix to denote the e1 trunk
+ * (see also RFC3435 section E.2) */
+#define MGCP_ENDPOINT_PREFIX_E1_TRUNK "ds/e1-"
+
/* Maximal number of payload types / codecs that can be negotiated via SDP at
* at once. */
#define MGCP_MAX_CODECS 10
diff --git a/include/osmocom/mgcp/mgcp_endp.h b/include/osmocom/mgcp/mgcp_endp.h
index 75f093d..79399a4 100644
--- a/include/osmocom/mgcp/mgcp_endp.h
+++ b/include/osmocom/mgcp/mgcp_endp.h
@@ -63,6 +63,9 @@
/*! MGCP endpoint model */
struct mgcp_endpoint {
+ /*! Unique endpoint name, used for addressing via MGCP */
+ char *name;
+
/*! Call identifier string (as supplied by the call agant) */
char *callid;
@@ -75,8 +78,8 @@
/*! Backpointer to the MGW configuration */
struct mgcp_config *cfg;
- /*! Backpointer to the Trunk specific configuration */
- struct mgcp_trunk_config *tcfg;
+ /*! Backpointer to the related trunk */
+ struct mgcp_trunk *trunk;
/*! Endpoint properties (see above) */
const struct mgcp_endpoint_type *type;
@@ -95,7 +98,9 @@
uint32_t x_osmo_ign;
};
-/*! Extract endpoint number for a given endpoint */
-#define ENDPOINT_NUMBER(endp) abs((int)(endp - endp->tcfg->endpoints))
-
+struct mgcp_endpoint *mgcp_endp_alloc(struct mgcp_trunk *trunk, char *name);
void mgcp_endp_release(struct mgcp_endpoint *endp);
+struct mgcp_endpoint *mgcp_endp_by_name_trunk(int *cause, const char *epname,
+ struct mgcp_trunk *trunk);
+struct mgcp_endpoint *mgcp_endp_by_name(int *cause, const char *epname,
+ struct mgcp_config *cfg);
diff --git a/include/osmocom/mgcp/mgcp_internal.h b/include/osmocom/mgcp/mgcp_internal.h
index e9d5d2d..557559f 100644
--- a/include/osmocom/mgcp/mgcp_internal.h
+++ b/include/osmocom/mgcp/mgcp_internal.h
@@ -282,9 +282,6 @@
return endpoint + 60;
}
-struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int index);
-struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index);
-
char *get_lco_identifier(const char *options);
int check_local_cx_options(void *ctx, const char *options);
void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,
@@ -342,8 +339,8 @@
void mgcp_conn_watchdog_kick(struct mgcp_conn *conn);
#define LOGPENDP(endp, cat, level, fmt, args...) \
-LOGP(cat, level, "endpoint:0x%x " fmt, \
- endp ? ENDPOINT_NUMBER(endp) : -1, \
+LOGP(cat, level, "endpoint:%s " fmt, \
+ endp ? endp->name : "none", \
## args)
#define LOGPCONN(conn, cat, level, fmt, args...) \
diff --git a/include/osmocom/mgcp/mgcp_trunk.h b/include/osmocom/mgcp/mgcp_trunk.h
new file mode 100644
index 0000000..7c37ead
--- /dev/null
+++ b/include/osmocom/mgcp/mgcp_trunk.h
@@ -0,0 +1,57 @@
+#pragma once
+
+struct mgcp_trunk {
+ struct llist_head entry;
+
+ struct mgcp_config *cfg;
+
+ int trunk_nr;
+ int trunk_type;
+
+ char *audio_fmtp_extra;
+ char *audio_name;
+ int audio_payload;
+ int audio_send_ptime;
+ int audio_send_name;
+ int audio_loop;
+
+ int no_audio_transcoding;
+
+ int omit_rtcp;
+ int keepalive_interval;
+
+ /* RTP patching */
+ int force_constant_ssrc; /* 0: don't, 1: once */
+ int force_aligned_timing;
+ bool rfc5993_hr_convert;
+
+ /* spec handling */
+ int force_realloc;
+
+ /* timer */
+ struct osmo_timer_list keepalive_timer;
+
+ /* When set, incoming RTP packets are not filtered
+ * when ports and ip-address do not match (debug) */
+ int rtp_accept_all;
+
+ unsigned int number_endpoints;
+ int vty_number_endpoints;
+ struct mgcp_endpoint **endpoints;
+
+ /* Rate counter group which contains stats for generic MGCP events. */
+ struct rate_ctr_group *mgcp_general_ctr_group;
+ /* Rate counter group which contains stats for processed CRCX commands. */
+ struct rate_ctr_group *mgcp_crcx_ctr_group;
+ /* Rate counter group which contains stats for processed MDCX commands. */
+ struct rate_ctr_group *mgcp_mdcx_ctr_group;
+ /* Rate counter group which contains stats for processed DLCX commands. */
+ struct rate_ctr_group *mgcp_dlcx_ctr_group;
+ /* Rate counter group which aggregates stats of individual RTP connections. */
+ struct rate_ctr_group *all_rtp_conn_stats;
+};
+
+struct mgcp_trunk *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr, int trunk_type);
+int mgcp_trunk_alloc_endpts(struct mgcp_trunk *tcfg);
+struct mgcp_trunk *mgcp_trunk_by_num(struct mgcp_config *cfg, int index);
+struct mgcp_trunk *mgcp_trunk_by_name(const char *epname, struct mgcp_config *cfg);
diff --git a/include/osmocom/mgcp_client/mgcp_common.h b/include/osmocom/mgcp_client/mgcp_common.h
new file mode 100644
index 0000000..058d94a
--- /dev/null
+++ b/include/osmocom/mgcp_client/mgcp_common.h
@@ -0,0 +1,118 @@
+/*
+
+ DO NOT EDIT THIS FILE!
+ THIS IS OVERWRITTEN DURING BUILD
+ This is an automatic copy of <osmocom/mgcp/mgcp_common.h>
+
+ */
+/* MGCP common implementations.
+ * These are used in libosmo-mgcp as well as libosmo-mgcp-client.
+ * To avoid interdependency, these are implemented in .h file only. */
+
+/*
+ * (C) 2017 by sysmocom s.f.m.c. GmbH <info at sysmocom.de>
+ * (C) 2009-2012 by Holger Hans Peter Freyther <zecke at selfish.org>
+ * (C) 2009-2012 by On-Waves
+ * All Rights Reserved
+ *
+ * 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/>.
+ *
+ */
+
+/* Two copies of this file are kept in osmocom/mgcp/ and osmocom/mgcp_client/.
+ * Since both are by definition identical, use the old header exclusion ifdefs
+ * instead of '#pragma once' to avoid including both of these files.
+ * Though at the time of writing there are no such users, this allows including
+ * both libosmo-mgcp and libosmo-mgcp-client headers in the same file. */
+#ifndef OSMO_MGCP_COMMON_H
+#define OSMO_MGCP_COMMON_H
+
+#include <string.h>
+#include <errno.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+
+#define for_each_non_empty_line(line, save) \
+ for (line = strtok_r(NULL, "\r\n", &save); line; \
+ line = strtok_r(NULL, "\r\n", &save))
+
+enum mgcp_connection_mode {
+ MGCP_CONN_NONE = 0,
+ MGCP_CONN_RECV_ONLY = 1,
+ MGCP_CONN_SEND_ONLY = 2,
+ MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
+ MGCP_CONN_LOOPBACK = 4 | MGCP_CONN_RECV_SEND,
+};
+
+#define MGCP_X_OSMO_IGN_HEADER "X-Osmo-IGN:"
+#define MGCP_X_OSMO_OSMUX_HEADER "X-Osmux:"
+
+/* Values should be bitwise-OR-able */
+enum mgcp_x_osmo_ign {
+ MGCP_X_OSMO_IGN_NONE = 0,
+ MGCP_X_OSMO_IGN_CALLID = 1,
+};
+
+/* Codec parameters (communicated via SDP/fmtp) */
+struct mgcp_codec_param {
+ bool amr_octet_aligned_present;
+ bool amr_octet_aligned;
+};
+
+/* Ensure that the msg->l2h is NUL terminated. */
+static inline int mgcp_msg_terminate_nul(struct msgb *msg)
+{
+ unsigned char *tail = msg->l2h + msgb_l2len(msg); /* char after l2 data */
+ if (tail[-1] == '\0')
+ /* nothing to do */;
+ else if (msgb_tailroom(msg) > 0)
+ tail[0] = '\0';
+ else if (tail[-1] == '\r' || tail[-1] == '\n')
+ tail[-1] = '\0';
+ else {
+ LOGP(DLMGCP, LOGL_ERROR, "Cannot NUL terminate MGCP message: "
+ "Length: %d, Buffer size: %d\n",
+ msgb_l2len(msg), msg->data_len);
+ return -ENOTSUP;
+ }
+ return 0;
+}
+
+/* Maximum length of the comment field */
+#define MGCP_COMMENT_MAXLEN 256
+
+/* Maximum allowed String length of Connection Identifiers as per spec
+ * (see also RFC3435 2.1.3.2 Names of Connections), plus one for '\0'. */
+#define MGCP_CONN_ID_MAXLEN 32+1
+
+/* Deprecated: old name of MGCP_CONN_ID_MAXLEN. */
+#define MGCP_CONN_ID_LENGTH MGCP_CONN_ID_MAXLEN
+
+/* String length of Endpoint Identifiers.
+/ (see also RFC3435 section 3.2.1.3) */
+#define MGCP_ENDPOINT_MAXLEN (255*2+1+1)
+
+/* A prefix to denote the virtual trunk (RTP on both ends) */
+#define MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK "rtpbridge/"
+
+/* A prefix to denote the e1 trunk
+ * (see also RFC3435 section E.2) */
+#define MGCP_ENDPOINT_PREFIX_E1_TRUNK "ds/e1-"
+
+/* Maximal number of payload types / codecs that can be negotiated via SDP at
+ * at once. */
+#define MGCP_MAX_CODECS 10
+
+#endif
diff --git a/src/libosmo-mgcp/Makefile.am b/src/libosmo-mgcp/Makefile.am
index a0c015b..142ff75 100644
--- a/src/libosmo-mgcp/Makefile.am
+++ b/src/libosmo-mgcp/Makefile.am
@@ -40,5 +40,6 @@
mgcp_conn.c \
mgcp_stat.c \
mgcp_endp.c \
+ mgcp_trunk.c \
mgcp_ctrl.c \
$(NULL)
diff --git a/src/libosmo-mgcp/mgcp_codec.c b/src/libosmo-mgcp/mgcp_codec.c
index 9e55ab0..c251317 100644
--- a/src/libosmo-mgcp/mgcp_codec.c
+++ b/src/libosmo-mgcp/mgcp_codec.c
@@ -19,6 +19,7 @@
*/
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <errno.h>
/* Helper function to dump codec information of a specified codec to a printable
@@ -292,7 +293,7 @@
* We do not compare to the full audio_name because we expect that
* "GSM", "GSM/8000" and "GSM/8000/1" are all compatible when the
* audio name of the codec is set to "GSM" */
- if (sscanf(endp->tcfg->audio_name, "%63[^/]/%*d/%*d", codec_name) < 1)
+ if (sscanf(endp->trunk->audio_name, "%63[^/]/%*d/%*d", codec_name) < 1)
return false;
/* Finally we check if the subtype_name we have generated from the
@@ -302,9 +303,9 @@
return true;
/* FIXME: It is questinable that the method to pick a compatible
- * codec can work properly. Since this useses tcfg->audio_name, as
+ * codec can work properly. Since this useses trunk->audio_name, as
* a reference, which is set to "AMR/8000" permanently.
- * tcfg->audio_name must be updated by the first connection that
+ * trunk->audio_name must be updated by the first connection that
* has been made on an endpoint, so that the second connection
* can make a meaningful decision here */
@@ -335,7 +336,7 @@
for (i = 0; i < rtp->codecs_assigned; i++) {
/* When no transcoding is available, avoid codecs that would
* require transcoding. */
- if (endp->tcfg->no_audio_transcoding && !is_codec_compatible(endp, &rtp->codecs[i])) {
+ 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;
diff --git a/src/libosmo-mgcp/mgcp_conn.c b/src/libosmo-mgcp/mgcp_conn.c
index 7a86274..6bbcbbc 100644
--- a/src/libosmo-mgcp/mgcp_conn.c
+++ b/src/libosmo-mgcp/mgcp_conn.c
@@ -25,6 +25,7 @@
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/mgcp/mgcp_common.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <osmocom/mgcp/mgcp_sdp.h>
#include <osmocom/mgcp/mgcp_codec.h>
#include <osmocom/gsm/gsm_utils.h>
@@ -255,7 +256,7 @@
}
static void
-aggregate_rtp_conn_stats(struct mgcp_trunk_config *trunk, struct mgcp_conn_rtp *conn_rtp)
+aggregate_rtp_conn_stats(struct mgcp_trunk *trunk, struct mgcp_conn_rtp *conn_rtp)
{
struct rate_ctr_group *all_stats = trunk->all_rtp_conn_stats;
struct rate_ctr_group *conn_stats = conn_rtp->rate_ctr_group;
@@ -296,7 +297,7 @@
switch (conn->type) {
case MGCP_CONN_TYPE_RTP:
- aggregate_rtp_conn_stats(endp->tcfg, &conn->u.rtp);
+ aggregate_rtp_conn_stats(endp->trunk, &conn->u.rtp);
mgcp_rtp_conn_cleanup(&conn->u.rtp);
break;
default:
diff --git a/src/libosmo-mgcp/mgcp_endp.c b/src/libosmo-mgcp/mgcp_endp.c
index eec46bf..80eb5b8 100644
--- a/src/libosmo-mgcp/mgcp_endp.c
+++ b/src/libosmo-mgcp/mgcp_endp.c
@@ -1,7 +1,7 @@
/* Endpoint types */
/*
- * (C) 2017 by sysmocom s.f.m.c. GmbH <info at sysmocom.de>
+ * (C) 2017-2020 by sysmocom s.f.m.c. GmbH <info at sysmocom.de>
* All Rights Reserved
*
* Author: Philipp Maier
@@ -23,6 +23,7 @@
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
/* Endpoint typeset definition */
const struct mgcp_endpoint_typeset ep_typeset = {
@@ -32,6 +33,38 @@
.rtp.cleanup_cb = mgcp_cleanup_rtp_bridge_cb
};
+/*! allocate an endpoint and set default values.
+ * \param[in] trunk configuration
+ * \returns endpoint on success, NULL on failure */
+struct mgcp_endpoint *mgcp_endp_alloc(struct mgcp_trunk *trunk, char *name)
+{
+ struct mgcp_endpoint *endp;
+
+ endp = talloc_zero(trunk->endpoints, struct mgcp_endpoint);
+ if (!endp)
+ return NULL;
+
+ INIT_LLIST_HEAD(&endp->conns);
+ endp->cfg = trunk->cfg;
+ endp->trunk = trunk;
+ endp->name = talloc_strdup(endp, name);
+
+ switch (trunk->trunk_type) {
+ case MGCP_TRUNK_VIRTUAL:
+ endp->type = &ep_typeset.rtp;
+ break;
+ case MGCP_TRUNK_E1:
+ /* FIXME: Implement E1 allocation */
+ LOGP(DLMGCP, LOGL_FATAL, "E1 trunks not implemented!\n");
+ break;
+ default:
+ osmo_panic("Cannot allocate unimplemented trunk type %d! %s:%d\n",
+ trunk->trunk_type, __FILE__, __LINE__);
+ }
+
+ return endp;
+}
+
/*! release endpoint, all open connections are closed.
* \param[in] endp endpoint to release */
void mgcp_endp_release(struct mgcp_endpoint *endp)
@@ -53,3 +86,183 @@
endp->local_options.codec = NULL;
endp->wildcarded_req = false;
}
+
+/* Check if the endpoint name contains the prefix, and chop it off, if it
+ * exists (per trunk the prefix is the same for all endpoints, so no ambiguity
+ * is introduced) */
+static const char *chop_endp_prefix(struct mgcp_trunk *trunk,
+ const char *epname)
+{
+ size_t prefix_len;
+ switch (trunk->trunk_type) {
+ case MGCP_TRUNK_VIRTUAL:
+ prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK) - 1;
+ if (strncmp
+ (epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK,
+ prefix_len) == 0)
+ return epname + prefix_len;
+ case MGCP_TRUNK_E1:
+ prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_E1_TRUNK) - 1;
+ if (strncmp
+ (epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK,
+ prefix_len) == 0)
+ return epname + prefix_len;
+ }
+
+ return epname;
+}
+
+/* Check for suffixes that can be omitted and return the true length of the
+ * endpoint name */
+static unsigned int ep_name_len(struct mgcp_trunk *trunk,
+ const char *epname)
+{
+ char *suffix_begin;
+
+ switch (trunk->trunk_type) {
+ case MGCP_TRUNK_VIRTUAL:
+ suffix_begin = strchr(epname, '@');
+ if (!suffix_begin)
+ return strlen(epname);
+ return suffix_begin - epname;
+ case MGCP_TRUNK_E1:
+ return strlen(epname);
+ }
+
+ return strlen(epname);
+}
+
+/*! Find an endpoint by its name on a specified trunk.
+ * \param[out] cause, pointer to store cause code, can be NULL.
+ * \param[in] epname endpoint name to lookup (may lack trunk prefix and domain name).
+ * \param[in] trunk where the endpoint is located.
+ * \returns endpoint or NULL if endpoint was not found. */
+struct mgcp_endpoint *mgcp_endp_by_name_trunk(int *cause, const char *epname,
+ struct mgcp_trunk *trunk)
+{
+ struct mgcp_endpoint *endp;
+ unsigned int i;
+ char epname_lc[MGCP_ENDPOINT_MAXLEN];
+ const char *epname_ch;
+ unsigned int epname_ch_len;
+
+ if (cause)
+ *cause = 0;
+
+ osmo_str_tolower_buf(epname_lc, sizeof(epname_lc), epname);
+ epname = epname_lc;
+ epname_ch = chop_endp_prefix(trunk, epname);
+ epname_ch_len = ep_name_len(trunk, epname_ch);
+
+ /* At the moment we only support a primitive ('*'-only) method of
+ * wildarded endpoint searches that picks the next free endpoint on
+ * a trunk. */
+ if (strncmp(epname_ch, "*", epname_ch_len) == 0) {
+ for (i = 0; i < trunk->number_endpoints; i++) {
+ endp = trunk->endpoints[i];
+ if (endp->callid == NULL) {
+ LOGPENDP(endp, DLMGCP, LOGL_DEBUG,
+ "(trunk:%i) found free endpoint: %s\n",
+ trunk->trunk_nr, endp->name);
+ endp->wildcarded_req = true;
+ return endp;
+ }
+ }
+
+ LOGP(DLMGCP, LOGL_ERROR,
+ "(trunk:%i) Not able to find a free endpoint\n",
+ trunk->trunk_nr);
+ if (cause)
+ *cause = -403;
+ return NULL;
+ }
+
+ /* Find an enspoint by its name (if wildcarded request is not
+ * applicable) */
+ for (i = 0; i < trunk->number_endpoints; i++) {
+ endp = trunk->endpoints[i];
+ if (strncmp
+ (chop_endp_prefix(trunk, endp->name), epname_ch,
+ epname_ch_len) == 0) {
+ LOGPENDP(endp, DLMGCP, LOGL_DEBUG,
+ "(trunk:%i) found endpoint: %s\n",
+ trunk->trunk_nr, endp->name);
+ endp->wildcarded_req = false;
+ return endp;
+ }
+ }
+
+ LOGP(DLMGCP, LOGL_ERROR,
+ "(trunk:%i) Not able to find specified endpoint: %s\n",
+ trunk->trunk_nr, epname);
+ if (cause)
+ *cause = -500;
+
+ return NULL;
+}
+
+/* Check if the domain name, which is supplied with the endpoint name
+ * matches the configuration. */
+static int check_domain_name(const char *epname, struct mgcp_config *cfg)
+{
+ char *domain_to_check;
+
+ domain_to_check = strstr(epname, "@");
+ if (!domain_to_check) {
+ LOGP(DLMGCP, LOGL_ERROR, "(endpoint:%s) missing domain name, expecting '%s'\n",
+ epname, cfg->domain);
+ return -EINVAL;
+ }
+
+ /* Accept any domain if configured as "*" */
+ if (!strcmp(cfg->domain, "*"))
+ return 0;
+
+ if (strcmp(domain_to_check+1, cfg->domain) != 0) {
+ LOGP(DLMGCP, LOGL_ERROR, "(endpoint:%s) wrong domain name, expecting '%s'\n",
+ epname, cfg->domain);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*! Find an endpoint by its name, search at all trunks.
+ * \param[out] cause, pointer to store cause code, can be NULL.
+ * \param[in] epname, must contain trunk prefix.
+ * \param[in] cfg, mgcp configuration (trunks).
+ * \returns endpoint or NULL if endpoint was not found. */
+struct mgcp_endpoint *mgcp_endp_by_name(int *cause, const char *epname,
+ struct mgcp_config *cfg)
+{
+ struct mgcp_trunk *trunk;
+ struct mgcp_endpoint *endp;
+ char epname_lc[MGCP_ENDPOINT_MAXLEN];
+
+ osmo_str_tolower_buf(epname_lc, sizeof(epname_lc), epname);
+ epname = epname_lc;
+
+ if (cause)
+ *cause = -500;
+
+ /* Identify the trunk where the endpoint is located */
+ trunk = mgcp_trunk_by_name(epname, cfg);
+ if (!trunk)
+ return NULL;
+
+ /* Virtual endpoints require a domain name (see RFC3435, section E.3) */
+ if (trunk->trunk_type == MGCP_TRUNK_VIRTUAL) {
+ if (check_domain_name(epname, cfg))
+ return NULL;
+ }
+
+ /* Identify the endpoint on the trunk */
+ endp = mgcp_endp_by_name_trunk(cause, epname, trunk);
+ if (!endp) {
+ return NULL;
+ }
+
+ if (cause)
+ *cause = 0;
+ return endp;
+}
diff --git a/src/libosmo-mgcp/mgcp_msg.c b/src/libosmo-mgcp/mgcp_msg.c
index 3e95ed1..019466e 100644
--- a/src/libosmo-mgcp/mgcp_msg.c
+++ b/src/libosmo-mgcp/mgcp_msg.c
@@ -129,166 +129,6 @@
return ret;
}
-/* We have a null terminated string with the endpoint name here. We only
- * support two kinds. Simple ones as seen on the BSC level and the ones
- * seen on the trunk side. (helper function for find_endpoint()) */
-static struct mgcp_endpoint *find_e1_endpoint(struct mgcp_config *cfg,
- const char *mgcp)
-{
- char *rest = NULL;
- struct mgcp_trunk_config *tcfg;
- int trunk, endp;
- struct mgcp_endpoint *endp_ptr;
-
- trunk = strtoul(mgcp + 6, &rest, 10);
- if (rest == NULL || rest[0] != '/' || trunk < 1) {
- LOGP(DLMGCP, LOGL_ERROR, "Wrong trunk name '%s'\n", mgcp);
- return NULL;
- }
-
- endp = strtoul(rest + 1, &rest, 10);
- if (rest == NULL || rest[0] != '@') {
- LOGP(DLMGCP, LOGL_ERROR, "Wrong endpoint name '%s'\n", mgcp);
- return NULL;
- }
-
- /* signalling is on timeslot 1 */
- if (endp == 1)
- return NULL;
-
- tcfg = mgcp_trunk_num(cfg, trunk);
- if (!tcfg) {
- LOGP(DLMGCP, LOGL_ERROR, "The trunk %d is not declared.\n",
- trunk);
- return NULL;
- }
-
- if (!tcfg->endpoints) {
- LOGP(DLMGCP, LOGL_ERROR,
- "Endpoints of trunk %d not allocated.\n", trunk);
- return NULL;
- }
-
- if (endp < 1 || endp >= tcfg->number_endpoints) {
- LOGP(DLMGCP, LOGL_ERROR, "Failed to find endpoint '%s'\n",
- mgcp);
- return NULL;
- }
-
- endp_ptr = &tcfg->endpoints[endp];
- endp_ptr->wildcarded_req = false;
- return endp_ptr;
-}
-
-/* Find an endpoint that is not in use. Do this by going through the endpoint
- * array, check the callid. A callid nullpointer indicates that the endpoint
- * is free */
-static struct mgcp_endpoint *find_free_endpoint(struct mgcp_endpoint *endpoints,
- unsigned int number_endpoints)
-{
- struct mgcp_endpoint *endp;
- unsigned int i;
-
- for (i = 0; i < number_endpoints; i++) {
- if (endpoints[i].callid == NULL) {
- endp = &endpoints[i];
- LOGPENDP(endp, DLMGCP, LOGL_DEBUG,
- "found free endpoint\n");
- endp->wildcarded_req = true;
- return endp;
- }
- }
-
- LOGP(DLMGCP, LOGL_ERROR, "Not able to find a free endpoint\n");
- return NULL;
-}
-
-/* Check if the domain name, which is supplied with the endpoint name
- * matches the configuration. */
-static int check_domain_name(struct mgcp_config *cfg, const char *mgcp)
-{
- char *domain_to_check;
-
- domain_to_check = strstr(mgcp, "@");
- if (!domain_to_check)
- return -EINVAL;
-
- /* Accept any domain if configured as "*" */
- if (!strcmp(cfg->domain, "*"))
- return 0;
-
- if (strcmp(domain_to_check+1, cfg->domain) != 0) {
- LOGP(DLMGCP, LOGL_ERROR, "Wrong domain name '%s', expecting '%s'\n", mgcp, cfg->domain);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* Search the endpoint pool for the endpoint that had been selected via the
- * MGCP message (helper function for mgcp_analyze_header()) */
-static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg,
- const char *mgcp,
- int *cause)
-{
- char *endptr = NULL;
- unsigned int gw = INT_MAX;
- const char *endpoint_number_str;
- struct mgcp_endpoint *endp;
-
- *cause = 0;
-
- /* Check if the domainname in the request is correct */
- if (check_domain_name(cfg, mgcp)) {
- *cause = -500;
- return NULL;
- }
-
- /* Check if the E1 trunk is requested */
- if (strncmp(mgcp, "ds/e1", 5) == 0) {
- endp = find_e1_endpoint(cfg, mgcp);
- if (!endp)
- *cause = -500;
- return endp;
- }
-
- /* Check if the virtual trunk is addressed (new, correct way with prefix) */
- if (strncmp
- (mgcp, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK,
- strlen(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK)) == 0) {
- endpoint_number_str =
- mgcp + strlen(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK);
- if (endpoint_number_str[0] == '*') {
- endp = find_free_endpoint(cfg->trunk.endpoints,
- cfg->trunk.number_endpoints);
- if (!endp)
- *cause = -403;
- return endp;
- }
- gw = strtoul(endpoint_number_str, &endptr, 16);
- if (gw < cfg->trunk.number_endpoints && endptr[0] == '@') {
- endp = &cfg->trunk.endpoints[gw];
- endp->wildcarded_req = false;
- return endp;
- }
- }
-
- /* Deprecated method without prefix */
- LOGP(DLMGCP, LOGL_NOTICE,
- "Addressing virtual trunk without prefix (deprecated), please use %s: '%s'\n",
- MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, mgcp);
- gw = strtoul(mgcp, &endptr, 16);
- if (gw < cfg->trunk.number_endpoints && endptr[0] == '@') {
- endp = &cfg->trunk.endpoints[gw];
- endp->wildcarded_req = false;
- return endp;
- }
-
- LOGP(DLMGCP, LOGL_ERROR, "Not able to find the endpoint: '%s'\n", mgcp);
- *cause = -500;
- return NULL;
-}
-
/*! Analyze and parse the the hader of an MGCP messeage string.
* \param[out] pdata caller provided memory to store the parsing results
* \param[in] data mgcp message string
@@ -316,7 +156,7 @@
pdata->trans = elem;
break;
case 1:
- pdata->endp = find_endpoint(pdata->cfg, elem, &cause);
+ pdata->endp = mgcp_endp_by_name(&cause, elem, pdata->cfg);
if (!pdata->endp) {
LOGP(DLMGCP, LOGL_ERROR,
"Unable to find Endpoint `%s'\n", elem);
@@ -390,8 +230,8 @@
const size_t line_len = strlen(line);
if (line[0] != '\0' && line_len < 2) {
LOGP(DLMGCP, LOGL_ERROR,
- "Wrong MGCP option format: '%s' on 0x%x\n",
- line, ENDPOINT_NUMBER(endp));
+ "Wrong MGCP option format: '%s' on %s\n",
+ line, endp->name);
return 0;
}
diff --git a/src/libosmo-mgcp/mgcp_network.c b/src/libosmo-mgcp/mgcp_network.c
index 608a93b..d3c7de8 100644
--- a/src/libosmo-mgcp/mgcp_network.c
+++ b/src/libosmo-mgcp/mgcp_network.c
@@ -42,6 +42,7 @@
#include <osmocom/mgcp/osmux.h>
#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <osmocom/mgcp/mgcp_codec.h>
#include <osmocom/mgcp/debug.h>
#include <osmocom/codec/codec.h>
@@ -61,7 +62,7 @@
int id, int inc)
{
struct rate_ctr_group *conn_stats = conn_rtp->rate_ctr_group;
- struct rate_ctr_group *trunk_stats = endp->tcfg->all_rtp_conn_stats;
+ struct rate_ctr_group *trunk_stats = endp->trunk->all_rtp_conn_stats;
/* add to both the per-connection and the per-trunk global stats */
rate_ctr_add(&conn_stats->ctr[id], inc);
@@ -187,7 +188,7 @@
if (rc == -1)
goto failed;
- if (endp->tcfg->omit_rtcp)
+ if (endp->trunk->omit_rtcp)
return rc;
was_rtcp = 1;
@@ -649,8 +650,8 @@
#if 0
DEBUGP(DRTP,
- "endpoint:0x%x payload hdr payload %u -> endp payload %u\n",
- ENDPOINT_NUMBER(endp), rtp_hdr->payload_type, payload);
+ "endpoint:%s payload hdr payload %u -> endp payload %u\n",
+ endp->name, rtp_hdr->payload_type, payload);
rtp_hdr->payload_type = payload;
#endif
}
@@ -819,7 +820,7 @@
* connection in loopback mode exists), then the source connection
* shall be specified as destination connection */
- struct mgcp_trunk_config *tcfg = endp->tcfg;
+ struct mgcp_trunk *trunk = endp->trunk;
struct mgcp_rtp_end *rtp_end;
struct mgcp_rtp_state *rtp_state;
char *dest_name;
@@ -835,7 +836,7 @@
}
LOGPENDP(endp, DRTP, LOGL_DEBUG, "loop:%d, mode:%d%s\n",
- tcfg->audio_loop, conn_src->conn->mode,
+ trunk->audio_loop, conn_src->conn->mode,
conn_src->conn->mode == MGCP_CONN_LOOPBACK ? " (loopback)" : "");
/* FIXME: It is legal that the payload type on the egress connection is
@@ -947,7 +948,7 @@
buflen = cont;
} while (buflen > 0);
return nbytes;
- } else if (!tcfg->omit_rtcp) {
+ } else if (!trunk->omit_rtcp) {
LOGPENDP(endp, DRTP, LOGL_DEBUG,
"send to %s %s rtp_port:%u rtcp_port:%u\n",
dest_name, inet_ntoa(rtp_end->addr),
@@ -1150,12 +1151,12 @@
{
struct mgcp_endpoint *endp;
struct mgcp_conn_rtp *conn;
- struct mgcp_trunk_config *tcfg;
+ struct mgcp_trunk *trunk;
int rc;
conn = (struct mgcp_conn_rtp*) fd->data;
endp = conn->conn->endp;
- tcfg = endp->tcfg;
+ trunk = endp->trunk;
LOGPCONN(conn->conn, DRTP, LOGL_DEBUG, "receiving RTP/RTCP packet...\n");
@@ -1190,7 +1191,7 @@
LOGPENDP(endp, DRTP, LOGL_DEBUG, "conn:%s\n", mgcp_conn_dump(conn->conn));
/* Check if the origin of the RTP packet seems plausible */
- if (tcfg->rtp_accept_all == 0) {
+ if (trunk->rtp_accept_all == 0) {
if (check_rtp_origin(conn, addr) != 0)
return -1;
}
@@ -1436,11 +1437,10 @@
/* Bind RTP and RTCP port (helper function for mgcp_bind_net_rtp_port()) */
static int bind_rtp(struct mgcp_config *cfg, const char *source_addr,
- struct mgcp_rtp_end *rtp_end, int endpno)
+ struct mgcp_rtp_end *rtp_end, struct mgcp_endpoint *endp)
{
/* NOTE: The port that is used for RTCP is the RTP port incremented by one
* (e.g. RTP-Port = 16000 ==> RTCP-Port = 16001) */
- struct mgcp_endpoint *endp = &cfg->trunk.endpoints[endpno];
if (mgcp_create_bind(source_addr, &rtp_end->rtp,
rtp_end->local_port) != 0) {
@@ -1527,8 +1527,7 @@
mgcp_get_local_addr(local_ip_addr, conn);
- return bind_rtp(endp->cfg, local_ip_addr, end,
- ENDPOINT_NUMBER(endp));
+ return bind_rtp(endp->cfg, local_ip_addr, end, endp);
}
/*! free allocated RTP and RTCP ports.
diff --git a/src/libosmo-mgcp/mgcp_osmux.c b/src/libosmo-mgcp/mgcp_osmux.c
index a1121de..29ad45f 100644
--- a/src/libosmo-mgcp/mgcp_osmux.c
+++ b/src/libosmo-mgcp/mgcp_osmux.c
@@ -27,6 +27,7 @@
#include <osmocom/mgcp/osmux.h>
#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
static struct osmo_fd osmux_fd;
@@ -202,9 +203,9 @@
struct mgcp_conn_rtp * conn_rtp;
int i;
- for (i=0; i<cfg->trunk.number_endpoints; i++) {
+ for (i=0; i<cfg->trunk->number_endpoints; i++) {
- endp = &cfg->trunk.endpoints[i];
+ endp = cfg->trunk->endpoints[i];
llist_for_each_entry(conn, &endp->conns, entry) {
if (conn->type != MGCP_CONN_TYPE_RTP)
diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c
index 82c10aa..c66d984 100644
--- a/src/libosmo-mgcp/mgcp_protocol.c
+++ b/src/libosmo-mgcp/mgcp_protocol.c
@@ -32,7 +32,6 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
-#include <osmocom/core/stats.h>
#include <osmocom/mgcp/mgcp.h>
#include <osmocom/mgcp/mgcp_common.h>
@@ -40,6 +39,7 @@
#include <osmocom/mgcp/mgcp_stat.h>
#include <osmocom/mgcp/mgcp_msg.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <osmocom/mgcp/mgcp_sdp.h>
#include <osmocom/mgcp/mgcp_codec.h>
#include <osmocom/mgcp/mgcp_conn.h>
@@ -53,101 +53,6 @@
#define MGCP_REQUEST(NAME, REQ, DEBUG_NAME) \
{ .name = NAME, .handle_request = REQ, .debug_name = DEBUG_NAME },
-static const struct rate_ctr_desc mgcp_general_ctr_desc[] = {
- /* rx_msgs = rx_msgs_retransmitted + rx_msgs_handled + rx_msgs_unhandled + err_rx_msg_parse + err_rx_no_endpoint */
- [MGCP_GENERAL_RX_MSGS_TOTAL] = {"mgcp:rx_msgs", "total number of MGCP messages received."},
- [MGCP_GENERAL_RX_MSGS_RETRANSMITTED] = {"mgcp:rx_msgs_retransmitted", "number of received retransmissions."},
- [MGCP_GENERAL_RX_MSGS_HANDLED] = {"mgcp:rx_msgs_handled", "number of handled MGCP messages."},
- [MGCP_GENERAL_RX_MSGS_UNHANDLED] = {"mgcp:rx_msgs_unhandled", "number of unhandled MGCP messages."},
- [MGCP_GENERAL_RX_FAIL_MSG_PARSE] = {"mgcp:err_rx_msg_parse", "error parsing MGCP message."},
- [MGCP_GENERAL_RX_FAIL_NO_ENDPOINT] = {"mgcp:err_rx_no_endpoint", "can't find MGCP endpoint, probably we've used all allocated endpoints."},
-};
-
-const static struct rate_ctr_group_desc mgcp_general_ctr_group_desc = {
- .group_name_prefix = "mgcp",
- .group_description = "mgcp general statistics",
- .class_id = OSMO_STATS_CLASS_GLOBAL,
- .num_ctr = ARRAY_SIZE(mgcp_general_ctr_desc),
- .ctr_desc = mgcp_general_ctr_desc
-};
-
-static const struct rate_ctr_desc mgcp_crcx_ctr_desc[] = {
- [MGCP_CRCX_SUCCESS] = {"crcx:success", "CRCX command processed successfully."},
- [MGCP_CRCX_FAIL_BAD_ACTION] = {"crcx:bad_action", "bad action in CRCX command."},
- [MGCP_CRCX_FAIL_UNHANDLED_PARAM] = {"crcx:unhandled_param", "unhandled parameter in CRCX command."},
- [MGCP_CRCX_FAIL_MISSING_CALLID] = {"crcx:missing_callid", "missing CallId in CRCX command."},
- [MGCP_CRCX_FAIL_INVALID_MODE] = {"crcx:invalid_mode", "invalid connection mode in CRCX command."},
- [MGCP_CRCX_FAIL_LIMIT_EXCEEDED] = {"crcx:limit_exceeded", "limit of concurrent connections was reached."},
- [MGCP_CRCX_FAIL_UNKNOWN_CALLID] = {"crcx:unkown_callid", "unknown CallId in CRCX command."},
- [MGCP_CRCX_FAIL_ALLOC_CONN] = {"crcx:alloc_conn_fail", "connection allocation failure."},
- [MGCP_CRCX_FAIL_NO_REMOTE_CONN_DESC] = {"crcx:no_remote_conn_desc", "no opposite end specified for connection."},
- [MGCP_CRCX_FAIL_START_RTP] = {"crcx:start_rtp_failure", "failure to start RTP processing."},
- [MGCP_CRCX_FAIL_REJECTED_BY_POLICY] = {"crcx:conn_rejected", "connection rejected by policy."},
- [MGCP_CRCX_FAIL_NO_OSMUX] = {"crcx:no_osmux", "no osmux offered by peer."},
- [MGCP_CRCX_FAIL_INVALID_CONN_OPTIONS] = {"crcx:conn_opt", "connection options invalid."},
- [MGCP_CRCX_FAIL_CODEC_NEGOTIATION] = {"crcx:codec_nego", "codec negotiation failure."},
- [MGCP_CRCX_FAIL_BIND_PORT] = {"crcx:bind_port", "port bind failure."},
-};
-
-const static struct rate_ctr_group_desc mgcp_crcx_ctr_group_desc = {
- .group_name_prefix = "crcx",
- .group_description = "crxc statistics",
- .class_id = OSMO_STATS_CLASS_GLOBAL,
- .num_ctr = ARRAY_SIZE(mgcp_crcx_ctr_desc),
- .ctr_desc = mgcp_crcx_ctr_desc
-};
-
-static const struct rate_ctr_desc mgcp_mdcx_ctr_desc[] = {
- [MGCP_MDCX_SUCCESS] = {"mdcx:success", "MDCX command processed successfully."},
- [MGCP_MDCX_FAIL_WILDCARD] = {"mdcx:wildcard", "wildcard endpoint names in MDCX commands are unsupported."},
- [MGCP_MDCX_FAIL_NO_CONN] = {"mdcx:no_conn", "endpoint specified in MDCX command has no active connections."},
- [MGCP_MDCX_FAIL_INVALID_CALLID] = {"mdcx:callid", "invalid CallId specified in MDCX command."},
- [MGCP_MDCX_FAIL_INVALID_CONNID] = {"mdcx:connid", "invalid connection ID specified in MDCX command."},
- [MGCP_MDCX_FAIL_UNHANDLED_PARAM] = {"crcx:unhandled_param", "unhandled parameter in MDCX command."},
- [MGCP_MDCX_FAIL_NO_CONNID] = {"mdcx:no_connid", "no connection ID specified in MDCX command."},
- [MGCP_MDCX_FAIL_CONN_NOT_FOUND] = {"mdcx:conn_not_found", "connection specified in MDCX command does not exist."},
- [MGCP_MDCX_FAIL_INVALID_MODE] = {"mdcx:invalid_mode", "invalid connection mode in MDCX command."},
- [MGCP_MDCX_FAIL_INVALID_CONN_OPTIONS] = {"mdcx:conn_opt", "connection options invalid."},
- [MGCP_MDCX_FAIL_NO_REMOTE_CONN_DESC] = {"mdcx:no_remote_conn_desc", "no opposite end specified for connection."},
- [MGCP_MDCX_FAIL_START_RTP] = {"mdcx:start_rtp_failure", "failure to start RTP processing."},
- [MGCP_MDCX_FAIL_REJECTED_BY_POLICY] = {"mdcx:conn_rejected", "connection rejected by policy."},
- [MGCP_MDCX_DEFERRED_BY_POLICY] = {"mdcx:conn_deferred", "connection deferred by policy."},
-};
-
-const static struct rate_ctr_group_desc mgcp_mdcx_ctr_group_desc = {
- .group_name_prefix = "mdcx",
- .group_description = "mdcx statistics",
- .class_id = OSMO_STATS_CLASS_GLOBAL,
- .num_ctr = ARRAY_SIZE(mgcp_mdcx_ctr_desc),
- .ctr_desc = mgcp_mdcx_ctr_desc
-};
-
-static const struct rate_ctr_desc mgcp_dlcx_ctr_desc[] = {
- [MGCP_DLCX_SUCCESS] = {"dlcx:success", "DLCX command processed successfully."},
- [MGCP_DLCX_FAIL_WILDCARD] = {"dlcx:wildcard", "wildcard names in DLCX commands are unsupported."},
- [MGCP_DLCX_FAIL_NO_CONN] = {"dlcx:no_conn", "endpoint specified in DLCX command has no active connections."},
- [MGCP_DLCX_FAIL_INVALID_CALLID] = {"dlcx:callid", "CallId specified in DLCX command mismatches endpoint's CallId ."},
- [MGCP_DLCX_FAIL_INVALID_CONNID] = {"dlcx:connid", "connection ID specified in DLCX command does not exist on endpoint."},
- [MGCP_DLCX_FAIL_UNHANDLED_PARAM] = {"dlcx:unhandled_param", "unhandled parameter in DLCX command."},
- [MGCP_DLCX_FAIL_REJECTED_BY_POLICY] = {"dlcx:rejected", "connection deletion rejected by policy."},
- [MGCP_DLCX_DEFERRED_BY_POLICY] = {"dlcx:deferred", "connection deletion deferred by policy."},
-};
-
-const static struct rate_ctr_group_desc mgcp_dlcx_ctr_group_desc = {
- .group_name_prefix = "dlcx",
- .group_description = "dlcx statistics",
- .class_id = OSMO_STATS_CLASS_GLOBAL,
- .num_ctr = ARRAY_SIZE(mgcp_dlcx_ctr_desc),
- .ctr_desc = mgcp_dlcx_ctr_desc
-};
-
-const static struct rate_ctr_group_desc all_rtp_conn_rate_ctr_group_desc = {
- .group_name_prefix = "all_rtp_conn",
- .group_description = "aggregated statistics for all rtp connections",
- .class_id = 1,
- .num_ctr = ARRAY_SIZE(all_rtp_conn_rate_ctr_desc),
- .ctr_desc = all_rtp_conn_rate_ctr_desc
-};
static struct msgb *handle_audit_endpoint(struct mgcp_parse_data *data);
static struct msgb *handle_create_con(struct mgcp_parse_data *data);
@@ -254,11 +159,11 @@
* Remember the last transmission per endpoint.
*/
if (endp) {
- struct mgcp_trunk_config *tcfg = endp->tcfg;
+ struct mgcp_trunk *trunk = endp->trunk;
talloc_free(endp->last_response);
talloc_free(endp->last_trans);
- endp->last_trans = talloc_strdup(tcfg->endpoints, trans);
- endp->last_response = talloc_strndup(tcfg->endpoints,
+ endp->last_trans = talloc_strdup(trunk->endpoints, trans);
+ endp->last_response = talloc_strndup(trunk->endpoints,
(const char *)res->l2h,
msgb_l2len(res));
}
@@ -296,10 +201,8 @@
/* NOTE: Only in the virtual trunk we allow dynamic endpoint names */
if (endp->wildcarded_req
- && endp->tcfg->trunk_type == MGCP_TRUNK_VIRTUAL) {
- rc = msgb_printf(msg, "Z: %s%x@%s\r\n",
- MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK,
- ENDPOINT_NUMBER(endp), endp->cfg->domain);
+ && endp->trunk->trunk_type == MGCP_TRUNK_VIRTUAL) {
+ rc = msgb_printf(msg, "Z: %s\r\n", endp->name);
if (rc < 0)
return -EINVAL;
}
@@ -379,8 +282,8 @@
* - or a response (three numbers, space, transaction id) */
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg)
{
- struct mgcp_trunk_config *tcfg = &cfg->trunk;
- struct rate_ctr_group *rate_ctrs = tcfg->mgcp_general_ctr_group;
+ struct mgcp_trunk *trunk = cfg->trunk;
+ struct rate_ctr_group *rate_ctrs = trunk->mgcp_general_ctr_group;
struct mgcp_parse_data pdata;
int rc, i, code, handled = 0;
struct msgb *resp = NULL;
@@ -692,13 +595,13 @@
void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,
struct mgcp_rtp_end *rtp)
{
- struct mgcp_trunk_config *tcfg = endp->tcfg;
+ struct mgcp_trunk *trunk = endp->trunk;
- int patch_ssrc = expect_ssrc_change && tcfg->force_constant_ssrc;
+ int patch_ssrc = expect_ssrc_change && trunk->force_constant_ssrc;
- rtp->force_aligned_timing = tcfg->force_aligned_timing;
+ rtp->force_aligned_timing = trunk->force_aligned_timing;
rtp->force_constant_ssrc = patch_ssrc ? 1 : 0;
- rtp->rfc5993_hr_convert = tcfg->rfc5993_hr_convert;
+ rtp->rfc5993_hr_convert = trunk->rfc5993_hr_convert;
LOGPENDP(endp, DLMGCP, LOGL_DEBUG,
"Configuring RTP endpoint: local port %d%s%s\n",
@@ -830,9 +733,9 @@
/* CRCX command handler, processes the received command */
static struct msgb *handle_create_con(struct mgcp_parse_data *p)
{
- struct mgcp_trunk_config *tcfg = p->endp->tcfg;
+ struct mgcp_trunk *trunk = p->endp->trunk;
struct mgcp_endpoint *endp = p->endp;
- struct rate_ctr_group *rate_ctrs = tcfg->mgcp_crcx_ctr_group;
+ struct rate_ctr_group *rate_ctrs = trunk->mgcp_crcx_ctr_group;
int error_code = 400;
const char *local_options = NULL;
const char *callid = NULL;
@@ -915,7 +818,7 @@
LOGPENDP(endp, DLMGCP, LOGL_ERROR,
"CRCX: endpoint full, max. %i connections allowed!\n",
endp->type->max_conns);
- if (tcfg->force_realloc) {
+ if (trunk->force_realloc) {
/* There is no more room for a connection, make some
* room by blindly tossing the oldest of the two two
* connections */
@@ -934,7 +837,7 @@
LOGPENDP(endp, DLMGCP, LOGL_ERROR,
"CRCX: already seized by other call (%s)\n",
endp->callid);
- if (tcfg->force_realloc)
+ if (trunk->force_realloc)
/* This is not our call, toss everything by releasing
* the entire endpoint. (rude!) */
mgcp_endp_release(endp);
@@ -949,10 +852,10 @@
/* Set the callid, creation of another connection will only be possible
* when the callid matches up. (Connections are distinguished by their
* connection ids) */
- endp->callid = talloc_strdup(tcfg->endpoints, callid);
+ endp->callid = talloc_strdup(trunk->endpoints, callid);
snprintf(conn_name, sizeof(conn_name), "%s", callid);
- _conn = mgcp_conn_alloc(tcfg->endpoints, endp, MGCP_CONN_TYPE_RTP, conn_name);
+ _conn = mgcp_conn_alloc(trunk->endpoints, endp, MGCP_CONN_TYPE_RTP, conn_name);
if (!_conn) {
LOGPENDP(endp, DLMGCP, LOGL_ERROR,
"CRCX: unable to allocate RTP connection\n");
@@ -987,7 +890,7 @@
/* Set local connection options, if present */
if (local_options) {
- rc = set_local_cx_options(endp->tcfg->endpoints,
+ rc = set_local_cx_options(endp->trunk->endpoints,
&endp->local_options, local_options);
if (rc != 0) {
LOGPCONN(_conn, DLMGCP, LOGL_ERROR,
@@ -1007,8 +910,8 @@
goto error2;
}
- conn->end.fmtp_extra = talloc_strdup(tcfg->endpoints,
- tcfg->audio_fmtp_extra);
+ conn->end.fmtp_extra = talloc_strdup(trunk->endpoints,
+ trunk->audio_fmtp_extra);
if (p->cfg->force_ptime) {
conn->end.packet_duration_ms = p->cfg->force_ptime;
@@ -1043,8 +946,7 @@
/* policy CB */
if (p->cfg->policy_cb) {
int rc;
- rc = p->cfg->policy_cb(tcfg, ENDPOINT_NUMBER(endp),
- MGCP_ENDP_CRCX, p->trans);
+ rc = p->cfg->policy_cb(endp, MGCP_ENDP_CRCX, p->trans);
switch (rc) {
case MGCP_POLICY_REJECT:
LOGPCONN(_conn, DLMGCP, LOGL_NOTICE,
@@ -1066,12 +968,12 @@
LOGPCONN(conn->conn, DLMGCP, LOGL_DEBUG,
"CRCX: Creating connection: port: %u\n", conn->end.local_port);
if (p->cfg->change_cb)
- p->cfg->change_cb(tcfg, ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX);
+ p->cfg->change_cb(endp, MGCP_ENDP_CRCX);
/* Send dummy packet, see also comments in mgcp_keepalive_timer_cb() */
- OSMO_ASSERT(tcfg->keepalive_interval >= MGCP_KEEPALIVE_ONCE);
+ OSMO_ASSERT(trunk->keepalive_interval >= MGCP_KEEPALIVE_ONCE);
if (conn->conn->mode & MGCP_CONN_RECV_ONLY
- && tcfg->keepalive_interval != MGCP_KEEPALIVE_NEVER)
+ && trunk->keepalive_interval != MGCP_KEEPALIVE_NEVER)
send_dummy(endp, conn);
LOGPCONN(_conn, DLMGCP, LOGL_NOTICE,
@@ -1085,16 +987,12 @@
return create_err_response(endp, error_code, "CRCX", p->trans);
}
-
-
-
-
/* MDCX command handler, processes the received command */
static struct msgb *handle_modify_con(struct mgcp_parse_data *p)
{
- struct mgcp_trunk_config *tcfg = p->endp->tcfg;
+ struct mgcp_trunk *trunk = p->endp->trunk;
struct mgcp_endpoint *endp = p->endp;
- struct rate_ctr_group *rate_ctrs = tcfg->mgcp_mdcx_ctr_group;
+ struct rate_ctr_group *rate_ctrs = trunk->mgcp_mdcx_ctr_group;
int error_code = 500;
int silent = 0;
int have_sdp = 0;
@@ -1202,7 +1100,7 @@
/* Set local connection options, if present */
if (local_options) {
- rc = set_local_cx_options(endp->tcfg->endpoints,
+ rc = set_local_cx_options(endp->trunk->endpoints,
&endp->local_options, local_options);
if (rc != 0) {
LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,
@@ -1261,8 +1159,7 @@
/* policy CB */
if (p->cfg->policy_cb) {
int rc;
- rc = p->cfg->policy_cb(endp->tcfg, ENDPOINT_NUMBER(endp),
- MGCP_ENDP_MDCX, p->trans);
+ rc = p->cfg->policy_cb(endp, MGCP_ENDP_MDCX, p->trans);
switch (rc) {
case MGCP_POLICY_REJECT:
LOGPCONN(conn->conn, DLMGCP, LOGL_NOTICE,
@@ -1291,13 +1188,12 @@
LOGPCONN(conn->conn, DLMGCP, LOGL_DEBUG,
"MDCX: modified conn:%s\n", mgcp_conn_dump(conn->conn));
if (p->cfg->change_cb)
- p->cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp),
- MGCP_ENDP_MDCX);
+ p->cfg->change_cb(endp, MGCP_ENDP_MDCX);
/* Send dummy packet, see also comments in mgcp_keepalive_timer_cb() */
- OSMO_ASSERT(endp->tcfg->keepalive_interval >= MGCP_KEEPALIVE_ONCE);
+ OSMO_ASSERT(endp->trunk->keepalive_interval >= MGCP_KEEPALIVE_ONCE);
if (conn->conn->mode & MGCP_CONN_RECV_ONLY
- && endp->tcfg->keepalive_interval != MGCP_KEEPALIVE_NEVER)
+ && endp->trunk->keepalive_interval != MGCP_KEEPALIVE_NEVER)
send_dummy(endp, conn);
rate_ctr_inc(&rate_ctrs->ctr[MGCP_MDCX_SUCCESS]);
@@ -1318,9 +1214,9 @@
/* DLCX command handler, processes the received command */
static struct msgb *handle_delete_con(struct mgcp_parse_data *p)
{
- struct mgcp_trunk_config *tcfg = p->endp->tcfg;
+ struct mgcp_trunk *trunk = p->endp->trunk;
struct mgcp_endpoint *endp = p->endp;
- struct rate_ctr_group *rate_ctrs = tcfg->mgcp_dlcx_ctr_group;
+ struct rate_ctr_group *rate_ctrs = trunk->mgcp_dlcx_ctr_group;
int error_code = 400;
int silent = 0;
char *line;
@@ -1381,8 +1277,7 @@
/* policy CB */
if (p->cfg->policy_cb) {
int rc;
- rc = p->cfg->policy_cb(endp->tcfg, ENDPOINT_NUMBER(endp),
- MGCP_ENDP_DLCX, p->trans);
+ rc = p->cfg->policy_cb(endp, MGCP_ENDP_DLCX, p->trans);
switch (rc) {
case MGCP_POLICY_REJECT:
LOGPENDP(endp, DLMGCP, LOGL_NOTICE, "DLCX: rejected by policy\n");
@@ -1446,8 +1341,7 @@
}
if (p->cfg->change_cb)
- p->cfg->change_cb(endp->tcfg, ENDPOINT_NUMBER(endp),
- MGCP_ENDP_DLCX);
+ p->cfg->change_cb(endp, MGCP_ENDP_DLCX);
rate_ctr_inc(&rate_ctrs->ctr[MGCP_DLCX_SUCCESS]);
if (silent)
@@ -1476,7 +1370,7 @@
LOGP(DLMGCP, LOGL_NOTICE, "RSIP: resetting all endpoints ...\n");
if (p->cfg->reset_cb)
- p->cfg->reset_cb(p->endp->tcfg);
+ p->cfg->reset_cb(p->endp->trunk);
return NULL;
}
@@ -1522,37 +1416,37 @@
/* Connection keepalive timer, will take care that dummy packets are send
* regularly, so that NAT connections stay open */
-static void mgcp_keepalive_timer_cb(void *_tcfg)
+static void mgcp_keepalive_timer_cb(void *_trunk)
{
- struct mgcp_trunk_config *tcfg = _tcfg;
+ struct mgcp_trunk *trunk = _trunk;
struct mgcp_conn *conn;
int i;
LOGP(DLMGCP, LOGL_DEBUG, "triggered trunk %d keepalive timer\n",
- tcfg->trunk_nr);
+ trunk->trunk_nr);
/* Do not accept invalid configuration values
* valid is MGCP_KEEPALIVE_NEVER, MGCP_KEEPALIVE_ONCE and
* values greater 0 */
- OSMO_ASSERT(tcfg->keepalive_interval >= MGCP_KEEPALIVE_ONCE);
+ OSMO_ASSERT(trunk->keepalive_interval >= MGCP_KEEPALIVE_ONCE);
/* The dummy packet functionality has been disabled, we will exit
* immediately, no further timer is scheduled, which means we will no
* longer send dummy packets even when we did before */
- if (tcfg->keepalive_interval == MGCP_KEEPALIVE_NEVER)
+ if (trunk->keepalive_interval == MGCP_KEEPALIVE_NEVER)
return;
/* In cases where only one dummy packet is sent, we do not need
* the timer since the functions that handle the CRCX and MDCX are
* triggering the sending of the dummy packet. So we behave like in
* the MGCP_KEEPALIVE_NEVER case */
- if (tcfg->keepalive_interval == MGCP_KEEPALIVE_ONCE)
+ if (trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
return;
/* Send walk over all endpoints and send out dummy packets through
* every connection present on each endpoint */
- for (i = 1; i < tcfg->number_endpoints; ++i) {
- struct mgcp_endpoint *endp = &tcfg->endpoints[i];
+ for (i = 1; i < trunk->number_endpoints; ++i) {
+ struct mgcp_endpoint *endp = trunk->endpoints[i];
llist_for_each_entry(conn, &endp->conns, entry) {
if (conn->mode == MGCP_CONN_RECV_ONLY)
send_dummy(endp, &conn->u.rtp);
@@ -1561,77 +1455,21 @@
/* Schedule the keepalive timer for the next round */
LOGP(DLMGCP, LOGL_DEBUG, "rescheduling trunk %d keepalive timer\n",
- tcfg->trunk_nr);
- osmo_timer_schedule(&tcfg->keepalive_timer, tcfg->keepalive_interval,
+ trunk->trunk_nr);
+ osmo_timer_schedule(&trunk->keepalive_timer, trunk->keepalive_interval,
0);
}
-void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval)
+void mgcp_trunk_set_keepalive(struct mgcp_trunk *trunk, int interval)
{
- tcfg->keepalive_interval = interval;
- osmo_timer_setup(&tcfg->keepalive_timer, mgcp_keepalive_timer_cb, tcfg);
+ trunk->keepalive_interval = interval;
+ osmo_timer_setup(&trunk->keepalive_timer, mgcp_keepalive_timer_cb, trunk);
if (interval <= 0)
- osmo_timer_del(&tcfg->keepalive_timer);
+ osmo_timer_del(&trunk->keepalive_timer);
else
- osmo_timer_schedule(&tcfg->keepalive_timer,
- tcfg->keepalive_interval, 0);
-}
-
-static int free_rate_counter_group(struct rate_ctr_group *rate_ctr_group)
-{
- rate_ctr_group_free(rate_ctr_group);
- return 0;
-}
-
-static int alloc_mgcp_rate_counters(struct mgcp_trunk_config *trunk, void *ctx)
-{
- /* FIXME: Each new rate counter group requires a unique index. At the
- * moment we generate an index using a counter, but perhaps there is
- * a better way of assigning indices? */
- static unsigned int general_rate_ctr_index = 0;
- static unsigned int crcx_rate_ctr_index = 0;
- static unsigned int mdcx_rate_ctr_index = 0;
- static unsigned int dlcx_rate_ctr_index = 0;
- static unsigned int all_rtp_conn_rate_ctr_index = 0;
-
- if (trunk->mgcp_general_ctr_group == NULL) {
- trunk->mgcp_general_ctr_group = rate_ctr_group_alloc(ctx, &mgcp_general_ctr_group_desc, general_rate_ctr_index);
- if (!trunk->mgcp_general_ctr_group)
- return -1;
- talloc_set_destructor(trunk->mgcp_general_ctr_group, free_rate_counter_group);
- general_rate_ctr_index++;
- }
- if (trunk->mgcp_crcx_ctr_group == NULL) {
- trunk->mgcp_crcx_ctr_group = rate_ctr_group_alloc(ctx, &mgcp_crcx_ctr_group_desc, crcx_rate_ctr_index);
- if (!trunk->mgcp_crcx_ctr_group)
- return -1;
- talloc_set_destructor(trunk->mgcp_crcx_ctr_group, free_rate_counter_group);
- crcx_rate_ctr_index++;
- }
- if (trunk->mgcp_mdcx_ctr_group == NULL) {
- trunk->mgcp_mdcx_ctr_group = rate_ctr_group_alloc(ctx, &mgcp_mdcx_ctr_group_desc, mdcx_rate_ctr_index);
- if (!trunk->mgcp_mdcx_ctr_group)
- return -1;
- talloc_set_destructor(trunk->mgcp_mdcx_ctr_group, free_rate_counter_group);
- mdcx_rate_ctr_index++;
- }
- if (trunk->mgcp_dlcx_ctr_group == NULL) {
- trunk->mgcp_dlcx_ctr_group = rate_ctr_group_alloc(ctx, &mgcp_dlcx_ctr_group_desc, dlcx_rate_ctr_index);
- if (!trunk->mgcp_dlcx_ctr_group)
- return -1;
- talloc_set_destructor(trunk->mgcp_dlcx_ctr_group, free_rate_counter_group);
- dlcx_rate_ctr_index++;
- }
- if (trunk->all_rtp_conn_stats == NULL) {
- trunk->all_rtp_conn_stats = rate_ctr_group_alloc(ctx, &all_rtp_conn_rate_ctr_group_desc,
- all_rtp_conn_rate_ctr_index);
- if (!trunk->all_rtp_conn_stats)
- return -1;
- talloc_set_destructor(trunk->all_rtp_conn_stats, free_rate_counter_group);
- all_rtp_conn_rate_ctr_index++;
- }
- return 0;
+ osmo_timer_schedule(&trunk->keepalive_timer,
+ trunk->keepalive_interval, 0);
}
/*! allocate configuration with default values.
@@ -1661,113 +1499,19 @@
cfg->get_net_downlink_format_cb = &mgcp_get_net_downlink_format_default;
- /* default trunk handling; TODO: avoid duplication with mgcp_trunk_alloc() below */
- cfg->trunk.cfg = cfg;
- cfg->trunk.trunk_nr = 0;
- cfg->trunk.trunk_type = MGCP_TRUNK_VIRTUAL;
- cfg->trunk.audio_name = talloc_strdup(cfg, "AMR/8000");
- cfg->trunk.audio_payload = 126;
- cfg->trunk.audio_send_ptime = 1;
- cfg->trunk.audio_send_name = 1;
- cfg->trunk.vty_number_endpoints = 33;
- cfg->trunk.omit_rtcp = 0;
- mgcp_trunk_set_keepalive(&cfg->trunk, MGCP_KEEPALIVE_ONCE);
- if (alloc_mgcp_rate_counters(&cfg->trunk, cfg) < 0) {
+ /* Allocate virtual trunk */
+ cfg->trunk = mgcp_trunk_alloc(cfg, 0, MGCP_TRUNK_VIRTUAL);
+ if (!cfg->trunk) {
talloc_free(cfg);
return NULL;
}
+ /* Initalize list head for user configurable trunks */
INIT_LLIST_HEAD(&cfg->trunks);
return cfg;
}
-/*! allocate configuration with default values.
- * (called once at startup by VTY)
- * \param[in] cfg mgcp configuration
- * \param[in] nr trunk number
- * \returns pointer to allocated trunk configuration */
-struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr)
-{
- struct mgcp_trunk_config *trunk;
-
- trunk = talloc_zero(cfg, struct mgcp_trunk_config);
- if (!trunk) {
- LOGP(DLMGCP, LOGL_ERROR, "Failed to allocate.\n");
- return NULL;
- }
-
- trunk->cfg = cfg;
- trunk->trunk_type = MGCP_TRUNK_E1;
- trunk->trunk_nr = nr;
- trunk->audio_name = talloc_strdup(cfg, "AMR/8000");
- trunk->audio_payload = 126;
- trunk->audio_send_ptime = 1;
- trunk->audio_send_name = 1;
- trunk->vty_number_endpoints = 33;
- trunk->omit_rtcp = 0;
- mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
- alloc_mgcp_rate_counters(trunk, trunk);
- llist_add_tail(&trunk->entry, &cfg->trunks);
-
- return trunk;
-}
-
-/*! get trunk configuration by trunk number (index).
- * \param[in] cfg mgcp configuration
- * \param[in] index trunk number
- * \returns pointer to trunk configuration, NULL on error */
-struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index)
-{
- struct mgcp_trunk_config *trunk;
-
- llist_for_each_entry(trunk, &cfg->trunks, entry)
- if (trunk->trunk_nr == index)
- return trunk;
-
- return NULL;
-}
-
-/*! allocate endpoints and set default values.
- * (called once at startup by VTY)
- * \param[in] tcfg trunk configuration
- * \returns 0 on success, -1 on failure */
-int mgcp_endpoints_allocate(struct mgcp_trunk_config *tcfg)
-{
- int i;
-
- tcfg->endpoints = _talloc_zero_array(tcfg->cfg,
- sizeof(struct mgcp_endpoint),
- tcfg->vty_number_endpoints,
- "endpoints");
- if (!tcfg->endpoints)
- return -1;
-
- for (i = 0; i < tcfg->vty_number_endpoints; ++i) {
- INIT_LLIST_HEAD(&tcfg->endpoints[i].conns);
- tcfg->endpoints[i].cfg = tcfg->cfg;
- tcfg->endpoints[i].tcfg = tcfg;
-
- switch (tcfg->trunk_type) {
- case MGCP_TRUNK_VIRTUAL:
- tcfg->endpoints[i].type = &ep_typeset.rtp;
- break;
- case MGCP_TRUNK_E1:
- /* FIXME: Implement E1 allocation */
- LOGP(DLMGCP, LOGL_FATAL, "E1 trunks not implemented!\n");
- break;
- default:
- osmo_panic("Cannot allocate unimplemented trunk type %d! %s:%d\n",
- tcfg->trunk_type, __FILE__, __LINE__);
- }
- }
-
- tcfg->number_endpoints = tcfg->vty_number_endpoints;
- alloc_mgcp_rate_counters(tcfg, tcfg->cfg);
-
- return 0;
-}
-
static int send_agent(struct mgcp_config *cfg, const char *buf, int len)
{
return write(cfg->gw_fd.bfd.fd, buf, len);
@@ -1798,17 +1542,16 @@
/*! Reset a single endpoint by sending RSIP message to self.
* (called by VTY)
- * \param[in] endp trunk endpoint
- * \param[in] endpoint number
+ * \param[in] endp to reset
* \returns 0 on success, -1 on error */
-int mgcp_send_reset_ep(struct mgcp_endpoint *endp, int endpoint)
+int mgcp_send_reset_ep(struct mgcp_endpoint *endp)
{
char buf[MGCP_ENDPOINT_MAXLEN + 128];
int len;
int rc;
len = snprintf(buf, sizeof(buf),
- "RSIP 39 %x@%s MGCP 1.0\r\n", endpoint, endp->cfg->domain);
+ "RSIP 39 %s MGCP 1.0\r\n", endp->name);
if (len < 0)
return -1;
diff --git a/src/libosmo-mgcp/mgcp_sdp.c b/src/libosmo-mgcp/mgcp_sdp.c
index 01e7968..f811fac 100644
--- a/src/libosmo-mgcp/mgcp_sdp.c
+++ b/src/libosmo-mgcp/mgcp_sdp.c
@@ -25,6 +25,7 @@
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/mgcp/mgcp_msg.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <osmocom/mgcp/mgcp_codec.h>
#include <osmocom/mgcp/mgcp_sdp.h>
@@ -358,10 +359,11 @@
break;
default:
if (p->endp)
+ /* TODO: Check spec: We used the bare endpoint number before,
+ * now we use the endpoint name as a whole? Is this allowed? */
LOGP(DLMGCP, LOGL_NOTICE,
- "Unhandled SDP option: '%c'/%d on 0x%x\n",
- line[0], line[0],
- ENDPOINT_NUMBER(p->endp));
+ "Unhandled SDP option: '%c'/%d on %s\n",
+ line[0], line[0], endp->name);
else
LOGP(DLMGCP, LOGL_NOTICE,
"Unhandled SDP option: '%c'/%d\n",
@@ -381,7 +383,7 @@
codec_param = param_by_pt(codecs[i].payload_type, fmtp_params, fmtp_used);
rc = mgcp_codec_add(conn, codecs[i].payload_type, codecs[i].map_line, codec_param);
if (rc < 0)
- LOGP(DLMGCP, LOGL_NOTICE, "endpoint:0x%x, failed to add codec\n", ENDPOINT_NUMBER(p->endp));
+ LOGP(DLMGCP, LOGL_NOTICE, "endpoint:%s, failed to add codec\n", endp->name);
}
talloc_free(tmp_ctx);
@@ -557,7 +559,7 @@
if (rc < 0)
goto buffer_too_small;
- if (endp->tcfg->audio_send_name) {
+ if (endp->trunk->audio_send_name) {
rc = add_rtpmap(sdp, payload_type, audio_name);
if (rc < 0)
goto buffer_too_small;
@@ -573,7 +575,7 @@
if (rc < 0)
goto buffer_too_small;
}
- if (conn->end.packet_duration_ms > 0 && endp->tcfg->audio_send_ptime) {
+ if (conn->end.packet_duration_ms > 0 && endp->trunk->audio_send_ptime) {
rc = msgb_printf(sdp, "a=ptime:%u\r\n",
conn->end.packet_duration_ms);
if (rc < 0)
diff --git a/src/libosmo-mgcp/mgcp_trunk.c b/src/libosmo-mgcp/mgcp_trunk.c
new file mode 100644
index 0000000..41495e5
--- /dev/null
+++ b/src/libosmo-mgcp/mgcp_trunk.c
@@ -0,0 +1,339 @@
+/* Trunk handling */
+
+/*
+ * (C) 2009-2012 by Holger Hans Peter Freyther <zecke at selfish.org>
+ * (C) 2009-2012 by On-Waves
+ * (C) 2017-2020 by sysmocom s.f.m.c. GmbH <info at sysmocom.de>
+ * All Rights Reserved
+ *
+ * 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 <osmocom/core/stats.h>
+#include <osmocom/mgcp/mgcp_internal.h>
+#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
+#include <osmocom/mgcp/mgcp_stat.h>
+
+static const struct rate_ctr_desc mgcp_general_ctr_desc[] = {
+ /* rx_msgs = rx_msgs_retransmitted + rx_msgs_handled + rx_msgs_unhandled + err_rx_msg_parse + err_rx_no_endpoint */
+ [MGCP_GENERAL_RX_MSGS_TOTAL] = { "mgcp:rx_msgs", "total number of MGCP messages received." },
+ [MGCP_GENERAL_RX_MSGS_RETRANSMITTED] = { "mgcp:rx_msgs_retransmitted", "number of received retransmissions." },
+ [MGCP_GENERAL_RX_MSGS_HANDLED] = { "mgcp:rx_msgs_handled", "number of handled MGCP messages." },
+ [MGCP_GENERAL_RX_MSGS_UNHANDLED] = { "mgcp:rx_msgs_unhandled", "number of unhandled MGCP messages." },
+ [MGCP_GENERAL_RX_FAIL_MSG_PARSE] = { "mgcp:err_rx_msg_parse", "error parsing MGCP message." },
+ [MGCP_GENERAL_RX_FAIL_NO_ENDPOINT] =
+ { "mgcp:err_rx_no_endpoint", "can't find MGCP endpoint, probably we've used all allocated endpoints." },
+};
+
+const static struct rate_ctr_group_desc mgcp_general_ctr_group_desc = {
+ .group_name_prefix = "mgcp",
+ .group_description = "mgcp general statistics",
+ .class_id = OSMO_STATS_CLASS_GLOBAL,
+ .num_ctr = ARRAY_SIZE(mgcp_general_ctr_desc),
+ .ctr_desc = mgcp_general_ctr_desc
+};
+
+static const struct rate_ctr_desc mgcp_crcx_ctr_desc[] = {
+ [MGCP_CRCX_SUCCESS] = { "crcx:success", "CRCX command processed successfully." },
+ [MGCP_CRCX_FAIL_BAD_ACTION] = { "crcx:bad_action", "bad action in CRCX command." },
+ [MGCP_CRCX_FAIL_UNHANDLED_PARAM] = { "crcx:unhandled_param", "unhandled parameter in CRCX command." },
+ [MGCP_CRCX_FAIL_MISSING_CALLID] = { "crcx:missing_callid", "missing CallId in CRCX command." },
+ [MGCP_CRCX_FAIL_INVALID_MODE] = { "crcx:invalid_mode", "invalid connection mode in CRCX command." },
+ [MGCP_CRCX_FAIL_LIMIT_EXCEEDED] = { "crcx:limit_exceeded", "limit of concurrent connections was reached." },
+ [MGCP_CRCX_FAIL_UNKNOWN_CALLID] = { "crcx:unkown_callid", "unknown CallId in CRCX command." },
+ [MGCP_CRCX_FAIL_ALLOC_CONN] = { "crcx:alloc_conn_fail", "connection allocation failure." },
+ [MGCP_CRCX_FAIL_NO_REMOTE_CONN_DESC] =
+ { "crcx:no_remote_conn_desc", "no opposite end specified for connection." },
+ [MGCP_CRCX_FAIL_START_RTP] = { "crcx:start_rtp_failure", "failure to start RTP processing." },
+ [MGCP_CRCX_FAIL_REJECTED_BY_POLICY] = { "crcx:conn_rejected", "connection rejected by policy." },
+ [MGCP_CRCX_FAIL_NO_OSMUX] = { "crcx:no_osmux", "no osmux offered by peer." },
+ [MGCP_CRCX_FAIL_INVALID_CONN_OPTIONS] = { "crcx:conn_opt", "connection options invalid." },
+ [MGCP_CRCX_FAIL_CODEC_NEGOTIATION] = { "crcx:codec_nego", "codec negotiation failure." },
+ [MGCP_CRCX_FAIL_BIND_PORT] = { "crcx:bind_port", "port bind failure." },
+};
+
+const static struct rate_ctr_group_desc mgcp_crcx_ctr_group_desc = {
+ .group_name_prefix = "crcx",
+ .group_description = "crxc statistics",
+ .class_id = OSMO_STATS_CLASS_GLOBAL,
+ .num_ctr = ARRAY_SIZE(mgcp_crcx_ctr_desc),
+ .ctr_desc = mgcp_crcx_ctr_desc
+};
+
+static const struct rate_ctr_desc mgcp_mdcx_ctr_desc[] = {
+ [MGCP_MDCX_SUCCESS] = { "mdcx:success", "MDCX command processed successfully." },
+ [MGCP_MDCX_FAIL_WILDCARD] = { "mdcx:wildcard", "wildcard endpoint names in MDCX commands are unsupported." },
+ [MGCP_MDCX_FAIL_NO_CONN] = { "mdcx:no_conn", "endpoint specified in MDCX command has no active connections." },
+ [MGCP_MDCX_FAIL_INVALID_CALLID] = { "mdcx:callid", "invalid CallId specified in MDCX command." },
+ [MGCP_MDCX_FAIL_INVALID_CONNID] = { "mdcx:connid", "invalid connection ID specified in MDCX command." },
+ [MGCP_MDCX_FAIL_UNHANDLED_PARAM] = { "crcx:unhandled_param", "unhandled parameter in MDCX command." },
+ [MGCP_MDCX_FAIL_NO_CONNID] = { "mdcx:no_connid", "no connection ID specified in MDCX command." },
+ [MGCP_MDCX_FAIL_CONN_NOT_FOUND] =
+ { "mdcx:conn_not_found", "connection specified in MDCX command does not exist." },
+ [MGCP_MDCX_FAIL_INVALID_MODE] = { "mdcx:invalid_mode", "invalid connection mode in MDCX command." },
+ [MGCP_MDCX_FAIL_INVALID_CONN_OPTIONS] = { "mdcx:conn_opt", "connection options invalid." },
+ [MGCP_MDCX_FAIL_NO_REMOTE_CONN_DESC] =
+ { "mdcx:no_remote_conn_desc", "no opposite end specified for connection." },
+ [MGCP_MDCX_FAIL_START_RTP] = { "mdcx:start_rtp_failure", "failure to start RTP processing." },
+ [MGCP_MDCX_FAIL_REJECTED_BY_POLICY] = { "mdcx:conn_rejected", "connection rejected by policy." },
+ [MGCP_MDCX_DEFERRED_BY_POLICY] = { "mdcx:conn_deferred", "connection deferred by policy." },
+};
+
+const static struct rate_ctr_group_desc mgcp_mdcx_ctr_group_desc = {
+ .group_name_prefix = "mdcx",
+ .group_description = "mdcx statistics",
+ .class_id = OSMO_STATS_CLASS_GLOBAL,
+ .num_ctr = ARRAY_SIZE(mgcp_mdcx_ctr_desc),
+ .ctr_desc = mgcp_mdcx_ctr_desc
+};
+
+static const struct rate_ctr_desc mgcp_dlcx_ctr_desc[] = {
+ [MGCP_DLCX_SUCCESS] = { "dlcx:success", "DLCX command processed successfully." },
+ [MGCP_DLCX_FAIL_WILDCARD] = { "dlcx:wildcard", "wildcard names in DLCX commands are unsupported." },
+ [MGCP_DLCX_FAIL_NO_CONN] = { "dlcx:no_conn", "endpoint specified in DLCX command has no active connections." },
+ [MGCP_DLCX_FAIL_INVALID_CALLID] =
+ { "dlcx:callid", "CallId specified in DLCX command mismatches endpoint's CallId ." },
+ [MGCP_DLCX_FAIL_INVALID_CONNID] =
+ { "dlcx:connid", "connection ID specified in DLCX command does not exist on endpoint." },
+ [MGCP_DLCX_FAIL_UNHANDLED_PARAM] = { "dlcx:unhandled_param", "unhandled parameter in DLCX command." },
+ [MGCP_DLCX_FAIL_REJECTED_BY_POLICY] = { "dlcx:rejected", "connection deletion rejected by policy." },
+ [MGCP_DLCX_DEFERRED_BY_POLICY] = { "dlcx:deferred", "connection deletion deferred by policy." },
+};
+
+const static struct rate_ctr_group_desc mgcp_dlcx_ctr_group_desc = {
+ .group_name_prefix = "dlcx",
+ .group_description = "dlcx statistics",
+ .class_id = OSMO_STATS_CLASS_GLOBAL,
+ .num_ctr = ARRAY_SIZE(mgcp_dlcx_ctr_desc),
+ .ctr_desc = mgcp_dlcx_ctr_desc
+};
+
+const static struct rate_ctr_group_desc all_rtp_conn_rate_ctr_group_desc = {
+ .group_name_prefix = "all_rtp_conn",
+ .group_description = "aggregated statistics for all rtp connections",
+ .class_id = 1,
+ .num_ctr = ARRAY_SIZE(all_rtp_conn_rate_ctr_desc),
+ .ctr_desc = all_rtp_conn_rate_ctr_desc
+};
+
+static int free_rate_counter_group(struct rate_ctr_group *rate_ctr_group)
+{
+ rate_ctr_group_free(rate_ctr_group);
+ return 0;
+}
+
+static int alloc_mgcp_rate_counters(struct mgcp_trunk *trunk, void *ctx)
+{
+ /* FIXME: Each new rate counter group requires a unique index. At the
+ * moment we generate an index using a counter, but perhaps there is
+ * a better way of assigning indices? */
+ static unsigned int general_rate_ctr_index = 0;
+ static unsigned int crcx_rate_ctr_index = 0;
+ static unsigned int mdcx_rate_ctr_index = 0;
+ static unsigned int dlcx_rate_ctr_index = 0;
+ static unsigned int all_rtp_conn_rate_ctr_index = 0;
+
+ if (trunk->mgcp_general_ctr_group == NULL) {
+ trunk->mgcp_general_ctr_group =
+ rate_ctr_group_alloc(ctx, &mgcp_general_ctr_group_desc, general_rate_ctr_index);
+ if (!trunk->mgcp_general_ctr_group)
+ return -1;
+ talloc_set_destructor(trunk->mgcp_general_ctr_group, free_rate_counter_group);
+ general_rate_ctr_index++;
+ }
+ if (trunk->mgcp_crcx_ctr_group == NULL) {
+ trunk->mgcp_crcx_ctr_group = rate_ctr_group_alloc(ctx, &mgcp_crcx_ctr_group_desc, crcx_rate_ctr_index);
+ if (!trunk->mgcp_crcx_ctr_group)
+ return -1;
+ talloc_set_destructor(trunk->mgcp_crcx_ctr_group, free_rate_counter_group);
+ crcx_rate_ctr_index++;
+ }
+ if (trunk->mgcp_mdcx_ctr_group == NULL) {
+ trunk->mgcp_mdcx_ctr_group = rate_ctr_group_alloc(ctx, &mgcp_mdcx_ctr_group_desc, mdcx_rate_ctr_index);
+ if (!trunk->mgcp_mdcx_ctr_group)
+ return -1;
+ talloc_set_destructor(trunk->mgcp_mdcx_ctr_group, free_rate_counter_group);
+ mdcx_rate_ctr_index++;
+ }
+ if (trunk->mgcp_dlcx_ctr_group == NULL) {
+ trunk->mgcp_dlcx_ctr_group = rate_ctr_group_alloc(ctx, &mgcp_dlcx_ctr_group_desc, dlcx_rate_ctr_index);
+ if (!trunk->mgcp_dlcx_ctr_group)
+ return -1;
+ talloc_set_destructor(trunk->mgcp_dlcx_ctr_group, free_rate_counter_group);
+ dlcx_rate_ctr_index++;
+ }
+ if (trunk->all_rtp_conn_stats == NULL) {
+ trunk->all_rtp_conn_stats = rate_ctr_group_alloc(ctx, &all_rtp_conn_rate_ctr_group_desc,
+ all_rtp_conn_rate_ctr_index);
+ if (!trunk->all_rtp_conn_stats)
+ return -1;
+ talloc_set_destructor(trunk->all_rtp_conn_stats, free_rate_counter_group);
+ all_rtp_conn_rate_ctr_index++;
+ }
+ return 0;
+}
+
+/*! allocate trunk and at id (if required) to the trunk list
+ * (called once at startup by VTY)
+ * \param[in] cfg mgcp configuration
+ * \param[in] nr trunk number
+ * \param[in] type trunk type
+ * \returns pointer to allocated trunk, NULL on failure */
+struct mgcp_trunk *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr, int trunk_type)
+{
+ struct mgcp_trunk *trunk;
+
+ trunk = talloc_zero(cfg, struct mgcp_trunk);
+ if (!trunk) {
+ LOGP(DLMGCP, LOGL_ERROR, "Failed to allocate.\n");
+ return NULL;
+ }
+
+ trunk->cfg = cfg;
+ trunk->trunk_type = trunk_type;
+ trunk->trunk_nr = nr;
+
+ trunk->audio_name = talloc_strdup(cfg, "AMR/8000");
+ trunk->audio_payload = 126;
+ trunk->audio_send_ptime = 1;
+ trunk->audio_send_name = 1;
+ trunk->vty_number_endpoints = 33;
+ trunk->omit_rtcp = 0;
+
+ mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
+
+ if (alloc_mgcp_rate_counters(trunk, trunk) < 0) {
+ talloc_free(trunk);
+ return NULL;
+ }
+
+ /* Note: Trunk Nr.0 is reserved as "virtual trunk",
+ * it is not stored using a separate pointer and
+ * not in the trunk list. */
+ if (nr > 0)
+ llist_add_tail(&trunk->entry, &cfg->trunks);
+
+ return trunk;
+}
+
+/*! allocate endpoints and set default values.
+ * (called once at startup by VTY)
+ * \param[in] trunk trunk configuration
+ * \returns 0 on success, -1 on failure */
+int mgcp_trunk_alloc_endpts(struct mgcp_trunk *trunk)
+{
+ int i;
+ char ep_name_buf[MGCP_ENDPOINT_MAXLEN];
+ struct mgcp_endpoint *endp;
+
+ /* (re)allocate pointer array for the endpoints */
+ trunk->number_endpoints = 0;
+ if (trunk->endpoints)
+ talloc_free(trunk->endpoints);
+ trunk->endpoints = _talloc_zero_array(trunk->cfg,
+ sizeof(struct mgcp_endpoint *), trunk->vty_number_endpoints, "endpoints");
+ if (!trunk->endpoints)
+ return -1;
+
+ /* create endpoints */
+ for (i = 0; i < trunk->vty_number_endpoints; ++i) {
+ switch (trunk->trunk_type) {
+ case MGCP_TRUNK_VIRTUAL:
+ snprintf(ep_name_buf, sizeof(ep_name_buf), "%s%x@%s", MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, i,
+ trunk->cfg->domain);
+ break;
+ case MGCP_TRUNK_E1:
+ /* FIXME: E1 trunk implementation is work in progress, this endpoint
+ * name is incomplete (subslots) */
+ snprintf(ep_name_buf, sizeof(ep_name_buf), "%s-1/%x", MGCP_ENDPOINT_PREFIX_E1_TRUNK, i);
+ break;
+ default:
+ osmo_panic("Cannot allocate unimplemented trunk type %d! %s:%d\n",
+ trunk->trunk_type, __FILE__, __LINE__);
+ }
+
+ endp = mgcp_endp_alloc(trunk, ep_name_buf);
+ if (!endp) {
+ talloc_free(trunk->endpoints);
+ return -1;
+ }
+ trunk->endpoints[i] = endp;
+ }
+
+ /* make the endpoints we just created available to the MGW code */
+ trunk->number_endpoints = trunk->vty_number_endpoints;
+
+ return 0;
+}
+
+/*! get trunk configuration by trunk number (index).
+ * \param[in] cfg mgcp configuration
+ * \param[in] index trunk number
+ * \returns pointer to trunk configuration, NULL on error */
+struct mgcp_trunk *mgcp_trunk_by_num(struct mgcp_config *cfg, int index)
+{
+ struct mgcp_trunk *trunk;
+
+ llist_for_each_entry(trunk, &cfg->trunks, entry)
+ if (trunk->trunk_nr == index)
+ return trunk;
+
+ return NULL;
+}
+
+/*! Find a trunk by the trunk prefix in the endpoint name.
+ * \param[in] epname endpoint name with trunk prefix to look up.
+ * \param[in] cfg that contains the trunks where the endpoint is located.
+ * \returns trunk or NULL if endpoint was not found. */
+struct mgcp_trunk *mgcp_trunk_by_name(const char *epname, struct mgcp_config *cfg)
+{
+ size_t prefix_len;
+ char epname_lc[MGCP_ENDPOINT_MAXLEN];
+
+ osmo_str_tolower_buf(epname_lc, sizeof(epname_lc), epname);
+ epname = epname_lc;
+
+ prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK) - 1;
+ if (strncmp(epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, prefix_len) == 0) {
+ return cfg->trunk;
+ }
+
+ /* E1 trunks are not implemented yet, so we deny any request for an
+ * e1 trunk for now. */
+ prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_E1_TRUNK) - 1;
+ if (strncmp(epname, MGCP_ENDPOINT_PREFIX_E1_TRUNK, prefix_len) == 0) {
+ LOGP(DLMGCP, LOGL_ERROR,
+ "(endpoint:%s) e1 trunks not implemented in this version of osmo-mgw!\n", epname);
+ return NULL;
+ }
+
+ /* Earlier versions of osmo-mgw were accepting endpoint names
+ * without trunk prefix. This is normally not allowed, each MGCP
+ * request should supply an endpoint name with trunk prefix.
+ * However in order to stay compatible with old versions of
+ * osmo-bsc and osmo-msc we still accept endpoint names without
+ * trunk prefix and just assume that the virtual trunk should
+ * be selected. There is even a TTCN3 test for this, see also:
+ * MGCP_Test.TC_crcx_noprefix */
+ if ((epname[0] >= '0' && epname[0] <= '9') || (epname[0] >= 'a' && epname[0] <= 'f')) {
+ LOGP(DLMGCP, LOGL_ERROR, "(endpoint:%s) missing trunk prefix, assuming trunk \"%s\"!\n", epname,
+ MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK);
+ return cfg->trunk;
+ }
+
+ LOGP(DLMGCP, LOGL_ERROR, "(endpoint:%s) unable to find trunk!\n", epname);
+ return NULL;
+}
diff --git a/src/libosmo-mgcp/mgcp_vty.c b/src/libosmo-mgcp/mgcp_vty.c
index 76d674f..0df805d 100644
--- a/src/libosmo-mgcp/mgcp_vty.c
+++ b/src/libosmo-mgcp/mgcp_vty.c
@@ -29,6 +29,7 @@
#include <osmocom/mgcp/vty.h>
#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <string.h>
#include <inttypes.h>
@@ -42,14 +43,14 @@
static struct mgcp_config *g_cfg = NULL;
-static struct mgcp_trunk_config *find_trunk(struct mgcp_config *cfg, int nr)
+static struct mgcp_trunk *find_trunk(struct mgcp_config *cfg, int nr)
{
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
if (nr == 0)
- trunk = &cfg->trunk;
+ trunk = cfg->trunk;
else
- trunk = mgcp_trunk_num(cfg, nr);
+ trunk = mgcp_trunk_by_num(cfg, nr);
return trunk;
}
@@ -85,50 +86,50 @@
else
vty_out(vty, " no rtp ip-probing%s", VTY_NEWLINE);
vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
- if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
+ if (g_cfg->trunk->keepalive_interval == MGCP_KEEPALIVE_ONCE)
vty_out(vty, " rtp keep-alive once%s", VTY_NEWLINE);
- else if (g_cfg->trunk.keepalive_interval)
+ else if (g_cfg->trunk->keepalive_interval)
vty_out(vty, " rtp keep-alive %d%s",
- g_cfg->trunk.keepalive_interval, VTY_NEWLINE);
+ g_cfg->trunk->keepalive_interval, VTY_NEWLINE);
else
vty_out(vty, " no rtp keep-alive%s", VTY_NEWLINE);
- if (g_cfg->trunk.omit_rtcp)
+ if (g_cfg->trunk->omit_rtcp)
vty_out(vty, " rtcp-omit%s", VTY_NEWLINE);
else
vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
- if (g_cfg->trunk.force_constant_ssrc
- || g_cfg->trunk.force_aligned_timing
- || g_cfg->trunk.rfc5993_hr_convert) {
+ if (g_cfg->trunk->force_constant_ssrc
+ || g_cfg->trunk->force_aligned_timing
+ || g_cfg->trunk->rfc5993_hr_convert) {
vty_out(vty, " %srtp-patch ssrc%s",
- g_cfg->trunk.force_constant_ssrc ? "" : "no ",
+ g_cfg->trunk->force_constant_ssrc ? "" : "no ",
VTY_NEWLINE);
vty_out(vty, " %srtp-patch timestamp%s",
- g_cfg->trunk.force_aligned_timing ? "" : "no ",
+ g_cfg->trunk->force_aligned_timing ? "" : "no ",
VTY_NEWLINE);
vty_out(vty, " %srtp-patch rfc5993hr%s",
- g_cfg->trunk.rfc5993_hr_convert ? "" : "no ",
+ g_cfg->trunk->rfc5993_hr_convert ? "" : "no ",
VTY_NEWLINE);
} else
vty_out(vty, " no rtp-patch%s", VTY_NEWLINE);
- if (g_cfg->trunk.audio_payload != -1)
+ if (g_cfg->trunk->audio_payload != -1)
vty_out(vty, " sdp audio-payload number %d%s",
- g_cfg->trunk.audio_payload, VTY_NEWLINE);
- if (g_cfg->trunk.audio_name)
+ g_cfg->trunk->audio_payload, VTY_NEWLINE);
+ if (g_cfg->trunk->audio_name)
vty_out(vty, " sdp audio-payload name %s%s",
- g_cfg->trunk.audio_name, VTY_NEWLINE);
- if (g_cfg->trunk.audio_fmtp_extra)
+ g_cfg->trunk->audio_name, VTY_NEWLINE);
+ if (g_cfg->trunk->audio_fmtp_extra)
vty_out(vty, " sdp audio fmtp-extra %s%s",
- g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
+ g_cfg->trunk->audio_fmtp_extra, VTY_NEWLINE);
vty_out(vty, " %ssdp audio-payload send-ptime%s",
- g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
+ g_cfg->trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %ssdp audio-payload send-name%s",
- g_cfg->trunk.audio_send_name ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " loop %u%s", ! !g_cfg->trunk.audio_loop, VTY_NEWLINE);
+ g_cfg->trunk->audio_send_name ? "" : "no ", VTY_NEWLINE);
+ vty_out(vty, " loop %u%s", ! !g_cfg->trunk->audio_loop, VTY_NEWLINE);
vty_out(vty, " number endpoints %u%s",
- g_cfg->trunk.vty_number_endpoints - 1, VTY_NEWLINE);
+ g_cfg->trunk->vty_number_endpoints - 1, VTY_NEWLINE);
vty_out(vty, " %sallow-transcoding%s",
- g_cfg->trunk.no_audio_transcoding ? "no " : "", VTY_NEWLINE);
+ g_cfg->trunk->no_audio_transcoding ? "no " : "", VTY_NEWLINE);
if (g_cfg->call_agent_addr)
vty_out(vty, " call-agent ip %s%s", g_cfg->call_agent_addr,
VTY_NEWLINE);
@@ -206,15 +207,13 @@
end->force_output_ptime, VTY_NEWLINE);
}
-static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp, int epidx,
+static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
{
struct mgcp_conn *conn;
- vty_out(vty, "%s trunk %d endpoint %s%.2x:%s",
- trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr,
- trunk_type == MGCP_TRUNK_VIRTUAL ? MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK : "",
- epidx, VTY_NEWLINE);
+ vty_out(vty, "%s trunk %d endpoint %s:%s",
+ trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
if (llist_empty(&endp->conns)) {
vty_out(vty, " No active connections%s", VTY_NEWLINE);
@@ -242,7 +241,7 @@
}
}
-static void dump_trunk(struct vty *vty, struct mgcp_trunk_config *cfg, int show_stats)
+static void dump_trunk(struct vty *vty, struct mgcp_trunk *cfg, int show_stats)
{
int i;
@@ -256,8 +255,8 @@
}
for (i = 0; i < cfg->number_endpoints; ++i) {
- struct mgcp_endpoint *endp = &cfg->endpoints[i];
- dump_endpoint(vty, endp, i, cfg->trunk_nr, cfg->trunk_type, show_stats);
+ struct mgcp_endpoint *endp = cfg->endpoints[i];
+ dump_endpoint(vty, endp, cfg->trunk_nr, cfg->trunk_type, show_stats);
if (i < cfg->number_endpoints - 1)
vty_out(vty, "%s", VTY_NEWLINE);
}
@@ -296,10 +295,10 @@
SHOW_MGCP_STR
"Include Statistics\n")
{
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
int show_stats = argc >= 1;
- dump_trunk(vty, &g_cfg->trunk, show_stats);
+ dump_trunk(vty, g_cfg->trunk, show_stats);
llist_for_each_entry(trunk, &g_cfg->trunks, entry)
dump_trunk(vty, trunk, show_stats);
@@ -312,34 +311,28 @@
}
static void
-dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk_config *trunk, const char *epname)
+dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
{
- const size_t virt_prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK) - 1;
- unsigned long epidx;
- char *endp;
- int i;
+ struct mgcp_endpoint *endp;
- if (strncmp(epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, virt_prefix_len) == 0)
- epname += virt_prefix_len;
- errno = 0;
- epidx = strtoul(epname, &endp, 16);
- if (epname[0] == '\0' || *endp != '\0') {
- vty_out(vty, "endpoint name '%s' is not a hex number%s", epname, VTY_NEWLINE);
- return;
- }
- if ((errno == ERANGE && epidx == ULONG_MAX) /* parsed value out of range */
- || epidx >= trunk->number_endpoints) {
- vty_out(vty, "endpoint %.2lx not configured on trunk %d%s", epidx, trunk->trunk_nr, VTY_NEWLINE);
- return;
- }
-
- for (i = 0; i < trunk->number_endpoints; ++i) {
- struct mgcp_endpoint *endp = &trunk->endpoints[i];
- if (i == epidx) {
- dump_endpoint(vty, endp, i, trunk->trunk_nr, trunk->trunk_type, true);
- break;
+ if (trunk) {
+ /* If a trunk is given, search on that specific trunk only */
+ endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
+ if (!endp) {
+ vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
+ return;
+ }
+ } else {
+ /* If no trunk is given, search on all possible trunks */
+ endp = mgcp_endp_by_name(NULL, epname, g_cfg);
+ if (!endp) {
+ vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
+ return;
}
}
+
+ trunk = endp->trunk;
+ dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
}
DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
@@ -348,12 +341,7 @@
SHOW_MGCP_STR
"Display information about an endpoint\n" "The name of the endpoint\n")
{
- struct mgcp_trunk_config *trunk;
-
- dump_mgcp_endpoint(vty, &g_cfg->trunk, argv[0]);
- llist_for_each_entry(trunk, &g_cfg->trunks, entry)
- dump_mgcp_endpoint(vty, trunk, argv[0]);
-
+ dump_mgcp_endpoint(vty, NULL, argv[0]);
return CMD_SUCCESS;
}
@@ -364,7 +352,7 @@
"Display information about a trunk\n" "Trunk number\n"
"Display information about an endpoint\n" "The name of the endpoint\n")
{
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
int trunkidx = atoi(argv[0]);
trunk = find_trunk(g_cfg, trunkidx);
@@ -561,7 +549,7 @@
if (!txt)
return CMD_WARNING;
- osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_fmtp_extra, txt);
+ osmo_talloc_replace_string(g_cfg, &g_cfg->trunk->audio_fmtp_extra, txt);
talloc_free(txt);
return CMD_SUCCESS;
}
@@ -570,7 +558,7 @@
cfg_mgcp_allow_transcoding_cmd,
"allow-transcoding", "Allow transcoding\n")
{
- g_cfg->trunk.no_audio_transcoding = 0;
+ g_cfg->trunk->no_audio_transcoding = 0;
return CMD_SUCCESS;
}
@@ -578,7 +566,7 @@
cfg_mgcp_no_allow_transcoding_cmd,
"no allow-transcoding", NO_STR "Allow transcoding\n")
{
- g_cfg->trunk.no_audio_transcoding = 1;
+ g_cfg->trunk->no_audio_transcoding = 1;
return CMD_SUCCESS;
}
@@ -590,7 +578,7 @@
SDP_STR AUDIO_STR "Number\n" "Payload number\n")
{
unsigned int payload = atoi(argv[0]);
- g_cfg->trunk.audio_payload = payload;
+ g_cfg->trunk->audio_payload = payload;
return CMD_SUCCESS;
}
@@ -604,7 +592,7 @@
"sdp audio-payload name NAME",
SDP_STR AUDIO_STR "Name\n" "Payload name\n")
{
- osmo_talloc_replace_string(g_cfg, &g_cfg->trunk.audio_name, argv[0]);
+ osmo_talloc_replace_string(g_cfg, &g_cfg->trunk->audio_name, argv[0]);
return CMD_SUCCESS;
}
@@ -617,7 +605,7 @@
"sdp audio-payload send-ptime",
SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
{
- g_cfg->trunk.audio_send_ptime = 1;
+ g_cfg->trunk->audio_send_ptime = 1;
return CMD_SUCCESS;
}
@@ -626,7 +614,7 @@
"no sdp audio-payload send-ptime",
NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
{
- g_cfg->trunk.audio_send_ptime = 0;
+ g_cfg->trunk->audio_send_ptime = 0;
return CMD_SUCCESS;
}
@@ -635,7 +623,7 @@
"sdp audio-payload send-name",
SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
{
- g_cfg->trunk.audio_send_name = 1;
+ g_cfg->trunk->audio_send_name = 1;
return CMD_SUCCESS;
}
@@ -644,7 +632,7 @@
"no sdp audio-payload send-name",
NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
{
- g_cfg->trunk.audio_send_name = 0;
+ g_cfg->trunk->audio_send_name = 0;
return CMD_SUCCESS;
}
@@ -657,7 +645,7 @@
vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
return CMD_WARNING;
}
- g_cfg->trunk.audio_loop = atoi(argv[0]);
+ g_cfg->trunk->audio_loop = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -667,7 +655,7 @@
"Force endpoint reallocation when the endpoint is still seized\n"
"Don't force reallocation\n" "force reallocation\n")
{
- g_cfg->trunk.force_realloc = atoi(argv[0]);
+ g_cfg->trunk->force_realloc = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -677,7 +665,7 @@
"Accept all RTP packets, even when the originating IP/Port does not match\n"
"enable filter\n" "disable filter\n")
{
- g_cfg->trunk.rtp_accept_all = atoi(argv[0]);
+ g_cfg->trunk->rtp_accept_all = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -687,20 +675,20 @@
"Number options\n" "Endpoints available\n" "Number endpoints\n")
{
/* + 1 as we start counting at one */
- g_cfg->trunk.vty_number_endpoints = atoi(argv[0]) + 1;
+ g_cfg->trunk->vty_number_endpoints = atoi(argv[0]) + 1;
return CMD_SUCCESS;
}
DEFUN(cfg_mgcp_omit_rtcp, cfg_mgcp_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
{
- g_cfg->trunk.omit_rtcp = 1;
+ g_cfg->trunk->omit_rtcp = 1;
return CMD_SUCCESS;
}
DEFUN(cfg_mgcp_no_omit_rtcp,
cfg_mgcp_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
{
- g_cfg->trunk.omit_rtcp = 0;
+ g_cfg->trunk->omit_rtcp = 0;
return CMD_SUCCESS;
}
@@ -708,7 +696,7 @@
cfg_mgcp_patch_rtp_ssrc_cmd,
"rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
{
- g_cfg->trunk.force_constant_ssrc = 1;
+ g_cfg->trunk->force_constant_ssrc = 1;
return CMD_SUCCESS;
}
@@ -716,7 +704,7 @@
cfg_mgcp_no_patch_rtp_ssrc_cmd,
"no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
{
- g_cfg->trunk.force_constant_ssrc = 0;
+ g_cfg->trunk->force_constant_ssrc = 0;
return CMD_SUCCESS;
}
@@ -724,7 +712,7 @@
cfg_mgcp_patch_rtp_ts_cmd,
"rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
{
- g_cfg->trunk.force_aligned_timing = 1;
+ g_cfg->trunk->force_aligned_timing = 1;
return CMD_SUCCESS;
}
@@ -732,7 +720,7 @@
cfg_mgcp_no_patch_rtp_ts_cmd,
"no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
{
- g_cfg->trunk.force_aligned_timing = 0;
+ g_cfg->trunk->force_aligned_timing = 0;
return CMD_SUCCESS;
}
@@ -740,7 +728,7 @@
cfg_mgcp_patch_rtp_rfc5993hr_cmd,
"rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
{
- g_cfg->trunk.rfc5993_hr_convert = true;
+ g_cfg->trunk->rfc5993_hr_convert = true;
return CMD_SUCCESS;
}
@@ -748,16 +736,16 @@
cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,
"no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
{
- g_cfg->trunk.rfc5993_hr_convert = false;
+ g_cfg->trunk->rfc5993_hr_convert = false;
return CMD_SUCCESS;
}
DEFUN(cfg_mgcp_no_patch_rtp,
cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
{
- g_cfg->trunk.force_constant_ssrc = 0;
- g_cfg->trunk.force_aligned_timing = 0;
- g_cfg->trunk.rfc5993_hr_convert = false;
+ g_cfg->trunk->force_constant_ssrc = 0;
+ g_cfg->trunk->force_aligned_timing = 0;
+ g_cfg->trunk->rfc5993_hr_convert = false;
return CMD_SUCCESS;
}
@@ -766,7 +754,7 @@
"rtp keep-alive <1-120>",
RTP_STR RTP_KEEPALIVE_STR "Keep alive interval in secs\n")
{
- mgcp_trunk_set_keepalive(&g_cfg->trunk, atoi(argv[0]));
+ mgcp_trunk_set_keepalive(g_cfg->trunk, atoi(argv[0]));
return CMD_SUCCESS;
}
@@ -775,7 +763,7 @@
"rtp keep-alive once",
RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
{
- mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
+ mgcp_trunk_set_keepalive(g_cfg->trunk, MGCP_KEEPALIVE_ONCE);
return CMD_SUCCESS;
}
@@ -783,7 +771,7 @@
cfg_mgcp_no_rtp_keepalive_cmd,
"no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
{
- mgcp_trunk_set_keepalive(&g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
+ mgcp_trunk_set_keepalive(g_cfg->trunk, MGCP_KEEPALIVE_NEVER);
return CMD_SUCCESS;
}
@@ -805,12 +793,12 @@
DEFUN(cfg_mgcp_trunk, cfg_mgcp_trunk_cmd,
"trunk <1-64>", "Configure a SS7 trunk\n" "Trunk Nr\n")
{
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
int index = atoi(argv[0]);
- trunk = mgcp_trunk_num(g_cfg, index);
+ trunk = mgcp_trunk_by_num(g_cfg, index);
if (!trunk)
- trunk = mgcp_trunk_alloc(g_cfg, index);
+ trunk = mgcp_trunk_alloc(g_cfg, index, MGCP_TRUNK_E1);
if (!trunk) {
vty_out(vty, "%%Unable to allocate trunk %u.%s",
@@ -825,7 +813,7 @@
static int config_write_trunk(struct vty *vty)
{
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
vty_out(vty, " trunk %d%s", trunk->trunk_nr, VTY_NEWLINE);
@@ -855,7 +843,7 @@
else
vty_out(vty, " no rtcp-omit%s", VTY_NEWLINE);
if (trunk->force_constant_ssrc || trunk->force_aligned_timing
- || g_cfg->trunk.rfc5993_hr_convert) {
+ || g_cfg->trunk->rfc5993_hr_convert) {
vty_out(vty, " %srtp-patch ssrc%s",
trunk->force_constant_ssrc ? "" : "no ",
VTY_NEWLINE);
@@ -883,7 +871,7 @@
"Add extra fmtp for the SDP file\n" "Audio\n" "Fmtp-extra\n"
"Extra Information\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
char *txt = argv_concat(argv, argc, 0);
if (!txt)
return CMD_WARNING;
@@ -898,7 +886,7 @@
"sdp audio-payload number <0-255>",
SDP_STR AUDIO_STR "Number\n" "Payload Number\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
unsigned int payload = atoi(argv[0]);
trunk->audio_payload = payload;
@@ -914,7 +902,7 @@
"sdp audio-payload name NAME",
SDP_STR AUDIO_STR "Payload\n" "Payload Name\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
osmo_talloc_replace_string(g_cfg, &trunk->audio_name, argv[0]);
return CMD_SUCCESS;
@@ -929,7 +917,7 @@
"loop (0|1)",
"Loop audio for all endpoints on this trunk\n" "Don't Loop\n" "Loop\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
if (g_cfg->osmux) {
vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
@@ -944,7 +932,7 @@
"sdp audio-payload send-ptime",
SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->audio_send_ptime = 1;
return CMD_SUCCESS;
}
@@ -954,7 +942,7 @@
"no sdp audio-payload send-ptime",
NO_STR SDP_STR AUDIO_STR "Send SDP ptime (packet duration) attribute\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->audio_send_ptime = 0;
return CMD_SUCCESS;
}
@@ -964,7 +952,7 @@
"sdp audio-payload send-name",
SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->audio_send_name = 1;
return CMD_SUCCESS;
}
@@ -974,14 +962,14 @@
"no sdp audio-payload send-name",
NO_STR SDP_STR AUDIO_STR "Send SDP rtpmap with the audio name\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->audio_send_name = 0;
return CMD_SUCCESS;
}
DEFUN(cfg_trunk_omit_rtcp, cfg_trunk_omit_rtcp_cmd, "rtcp-omit", RTCP_OMIT_STR)
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->omit_rtcp = 1;
return CMD_SUCCESS;
}
@@ -989,7 +977,7 @@
DEFUN(cfg_trunk_no_omit_rtcp,
cfg_trunk_no_omit_rtcp_cmd, "no rtcp-omit", NO_STR RTCP_OMIT_STR)
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->omit_rtcp = 0;
return CMD_SUCCESS;
}
@@ -998,7 +986,7 @@
cfg_trunk_patch_rtp_ssrc_cmd,
"rtp-patch ssrc", RTP_PATCH_STR "Force a fixed SSRC\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->force_constant_ssrc = 1;
return CMD_SUCCESS;
}
@@ -1007,7 +995,7 @@
cfg_trunk_no_patch_rtp_ssrc_cmd,
"no rtp-patch ssrc", NO_STR RTP_PATCH_STR "Force a fixed SSRC\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->force_constant_ssrc = 0;
return CMD_SUCCESS;
}
@@ -1016,7 +1004,7 @@
cfg_trunk_patch_rtp_ts_cmd,
"rtp-patch timestamp", RTP_PATCH_STR "Adjust RTP timestamp\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->force_aligned_timing = 1;
return CMD_SUCCESS;
}
@@ -1025,7 +1013,7 @@
cfg_trunk_no_patch_rtp_ts_cmd,
"no rtp-patch timestamp", NO_STR RTP_PATCH_STR "Adjust RTP timestamp\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->force_aligned_timing = 0;
return CMD_SUCCESS;
}
@@ -1034,7 +1022,7 @@
cfg_trunk_patch_rtp_rfc5993hr_cmd,
"rtp-patch rfc5993hr", RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->rfc5993_hr_convert = true;
return CMD_SUCCESS;
}
@@ -1043,7 +1031,7 @@
cfg_trunk_no_patch_rtp_rfc5993hr_cmd,
"no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR RTP_TS101318_RFC5993_CONV_STR)
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->rfc5993_hr_convert = false;
return CMD_SUCCESS;
}
@@ -1051,7 +1039,7 @@
DEFUN(cfg_trunk_no_patch_rtp,
cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->force_constant_ssrc = 0;
trunk->force_aligned_timing = 0;
trunk->rfc5993_hr_convert = false;
@@ -1063,7 +1051,7 @@
"rtp keep-alive <1-120>",
RTP_STR RTP_KEEPALIVE_STR "Keep-alive interval in secs\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
mgcp_trunk_set_keepalive(trunk, atoi(argv[0]));
return CMD_SUCCESS;
}
@@ -1073,7 +1061,7 @@
"rtp keep-alive once",
RTP_STR RTP_KEEPALIVE_STR "Send dummy packet only once after CRCX/MDCX\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
mgcp_trunk_set_keepalive(trunk, MGCP_KEEPALIVE_ONCE);
return CMD_SUCCESS;
}
@@ -1082,7 +1070,7 @@
cfg_trunk_no_rtp_keepalive_cmd,
"no rtp keep-alive", NO_STR RTP_STR RTP_KEEPALIVE_STR)
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
mgcp_trunk_set_keepalive(trunk, 0);
return CMD_SUCCESS;
}
@@ -1091,7 +1079,7 @@
cfg_trunk_allow_transcoding_cmd,
"allow-transcoding", "Allow transcoding\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->no_audio_transcoding = 0;
return CMD_SUCCESS;
}
@@ -1100,7 +1088,7 @@
cfg_trunk_no_allow_transcoding_cmd,
"no allow-transcoding", NO_STR "Allow transcoding\n")
{
- struct mgcp_trunk_config *trunk = vty->index;
+ struct mgcp_trunk *trunk = vty->index;
trunk->no_audio_transcoding = 1;
return CMD_SUCCESS;
}
@@ -1112,7 +1100,7 @@
"The name in hex of the endpoint\n" "Disable the loop\n"
"Enable the loop\n")
{
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
struct mgcp_endpoint *endp;
struct mgcp_conn *conn;
@@ -1136,7 +1124,7 @@
return CMD_WARNING;
}
- endp = &trunk->endpoints[endp_no];
+ endp = trunk->endpoints[endp_no];
int loop = atoi(argv[2]);
llist_for_each_entry(conn, &endp->conns, entry) {
if (conn->type == MGCP_CONN_TYPE_RTP)
@@ -1170,7 +1158,7 @@
"destination IP of the data\n" "destination port\n")
{
struct mgcp_rtp_tap *tap;
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
struct mgcp_endpoint *endp;
struct mgcp_conn_rtp *conn;
const char *conn_id = NULL;
@@ -1195,7 +1183,7 @@
return CMD_WARNING;
}
- endp = &trunk->endpoints[endp_no];
+ endp = trunk->endpoints[endp_no];
conn_id = argv[2];
conn = mgcp_conn_get_rtp(endp, conn_id);
@@ -1225,7 +1213,7 @@
"free-endpoint <0-64> NUMBER",
"Free the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
{
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
struct mgcp_endpoint *endp;
trunk = find_trunk(g_cfg, atoi(argv[0]));
@@ -1248,7 +1236,7 @@
return CMD_WARNING;
}
- endp = &trunk->endpoints[endp_no];
+ endp = trunk->endpoints[endp_no];
mgcp_endp_release(endp);
return CMD_SUCCESS;
}
@@ -1257,7 +1245,7 @@
"reset-endpoint <0-64> NUMBER",
"Reset the given endpoint\n" "Trunk number\n" "Endpoint number in hex.\n")
{
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
struct mgcp_endpoint *endp;
int endp_no, rc;
@@ -1281,8 +1269,8 @@
return CMD_WARNING;
}
- endp = &trunk->endpoints[endp_no];
- rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
+ endp = trunk->endpoints[endp_no];
+ rc = mgcp_send_reset_ep(endp);
if (rc < 0) {
vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
return CMD_WARNING;
@@ -1318,7 +1306,7 @@
else if (strcmp(argv[0], "only") == 0)
g_cfg->osmux = OSMUX_USAGE_ONLY;
- if (g_cfg->trunk.audio_loop) {
+ if (g_cfg->trunk->audio_loop) {
vty_out(vty, "Cannot use `loop' with `osmux'.%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1500,7 +1488,7 @@
enum mgcp_role role)
{
int rc;
- struct mgcp_trunk_config *trunk;
+ struct mgcp_trunk *trunk;
cfg->osmux_port = OSMUX_PORT;
cfg->osmux_batch = 4;
@@ -1519,15 +1507,15 @@
return -1;
}
- if (mgcp_endpoints_allocate(&g_cfg->trunk) != 0) {
+ if (mgcp_trunk_alloc_endpts(g_cfg->trunk) != 0) {
LOGP(DLMGCP, LOGL_ERROR,
"Failed to initialize the virtual trunk (%d endpoints)\n",
- g_cfg->trunk.number_endpoints);
+ g_cfg->trunk->number_endpoints);
return -1;
}
llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
- if (mgcp_endpoints_allocate(trunk) != 0) {
+ if (mgcp_trunk_alloc_endpts(trunk) != 0) {
LOGP(DLMGCP, LOGL_ERROR,
"Failed to initialize trunk %d (%d endpoints)\n",
trunk->trunk_nr, trunk->number_endpoints);
diff --git a/src/osmo-mgw/mgw_main.c b/src/osmo-mgw/mgw_main.c
index 48869c4..99e2499 100644
--- a/src/osmo-mgw/mgw_main.c
+++ b/src/osmo-mgw/mgw_main.c
@@ -38,6 +38,7 @@
#include <osmocom/mgcp/vty.h>
#include <osmocom/mgcp/debug.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <osmocom/mgcp/mgcp_ctrl.h>
#include <osmocom/core/application.h>
@@ -71,7 +72,7 @@
/* FIXME: Make use of the rtp proxy code */
static struct mgcp_config *cfg;
-static struct mgcp_trunk_config *reset_trunk;
+static struct mgcp_trunk *reset_trunk;
static int reset_endpoints = 0;
static int daemonize = 0;
@@ -148,13 +149,13 @@
/* Callback function to be called when the RSIP ("Reset in Progress") mgcp
* command is received */
-static int mgcp_rsip_cb(struct mgcp_trunk_config *tcfg)
+static int mgcp_rsip_cb(struct mgcp_trunk *trunk)
{
/* Set flag so that, when read_call_agent() is called next time
* the reset can progress */
reset_endpoints = 1;
- reset_trunk = tcfg;
+ reset_trunk = trunk;
return 0;
}
@@ -203,7 +204,7 @@
/* Walk over all endpoints and trigger a release, this will release all
* endpoints, possible open connections are forcefully dropped */
for (i = 1; i < reset_trunk->number_endpoints; ++i)
- mgcp_endp_release(&reset_trunk->endpoints[i]);
+ mgcp_endp_release(reset_trunk->endpoints[i]);
}
return 0;
diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c
index c72382e..1f74b01 100644
--- a/tests/mgcp/mgcp_test.c
+++ b/tests/mgcp/mgcp_test.c
@@ -26,6 +26,7 @@
#include <osmocom/mgcp/mgcp_stat.h>
#include <osmocom/mgcp/mgcp_msg.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <osmocom/mgcp/mgcp_sdp.h>
#include <osmocom/mgcp/mgcp_codec.h>
@@ -70,7 +71,7 @@
}
#define AUEP1 "AUEP 158663169 ds/e1-1/2 at mgw MGCP 1.0\r\n"
-#define AUEP1_RET "200 158663169 OK\r\n"
+#define AUEP1_RET "500 158663169 FAIL\r\n"
#define AUEP2 "AUEP 18983213 ds/e1-2/1 at mgw MGCP 1.0\r\n"
#define AUEP2_RET "500 18983213 FAIL\r\n"
#define EMPTY "\r\n"
@@ -81,7 +82,7 @@
#define MDCX_WRONG_EP "MDCX 18983213 ds/e1-3/1 at mgw MGCP 1.0\r\n"
#define MDCX_ERR_RET "500 18983213 FAIL\r\n"
#define MDCX_UNALLOCATED "MDCX 18983214 ds/e1-1/2 at mgw MGCP 1.0\r\n"
-#define MDCX_RET "400 18983214 FAIL\r\n"
+#define MDCX_RET "500 18983214 FAIL\r\n"
#define MDCX3 \
"MDCX 18983215 1 at mgw MGCP 1.0\r\n" \
@@ -593,12 +594,22 @@
static int last_endpoint = -1;
-static int mgcp_test_policy_cb(struct mgcp_trunk_config *cfg, int endpoint,
- int state, const char *transactio_id)
+static int mgcp_test_policy_cb(struct mgcp_endpoint *endp,
+ int state, const char *transaction_id)
{
- fprintf(stderr, "Policy CB got state %d on endpoint 0x%x\n",
- state, endpoint);
- last_endpoint = endpoint;
+ unsigned int i;
+ struct mgcp_trunk *trunk;
+
+ fprintf(stderr, "Policy CB got state %d on endpoint %s\n",
+ state, endp->name);
+
+ trunk = endp->trunk;
+ last_endpoint = -1;
+ for (i = 0; i < trunk->vty_number_endpoints; i++) {
+ if (strcmp(endp->name, trunk->endpoints[i]->name) == 0)
+ last_endpoint = i;
+ }
+
return MGCP_POLICY_CONT;
}
@@ -641,11 +652,11 @@
return real_clock_gettime(clk_id, tp);
}
-static void mgcp_endpoints_release(struct mgcp_trunk_config *trunk)
+static void mgcp_endpoints_release(struct mgcp_trunk *trunk)
{
int i;
for (i = 1; i < trunk->number_endpoints; i++)
- mgcp_endp_release(&trunk->endpoints[i]);
+ mgcp_endp_release(trunk->endpoints[i]);
}
#define CONN_UNMODIFIED (0x1000)
@@ -749,7 +760,7 @@
{
struct mgcp_config *cfg;
struct mgcp_endpoint *endp;
- struct mgcp_trunk_config *trunk2;
+ struct mgcp_trunk *trunk2;
int i;
struct mgcp_conn_rtp *conn = NULL;
char last_conn_id[256];
@@ -757,14 +768,14 @@
cfg = mgcp_config_alloc();
- cfg->trunk.vty_number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
+ cfg->trunk->vty_number_endpoints = 64;
+ mgcp_trunk_alloc_endpts(cfg->trunk);
cfg->policy_cb = mgcp_test_policy_cb;
memset(last_conn_id, 0, sizeof(last_conn_id));
- trunk2 = mgcp_trunk_alloc(cfg, 1);
- mgcp_endpoints_allocate(trunk2);
+ trunk2 = mgcp_trunk_alloc(cfg, 1, MGCP_TRUNK_E1);
+ mgcp_trunk_alloc_endpts(trunk2);
for (i = 0; i < ARRAY_SIZE(tests); i++) {
const struct mgcp_test *t = &tests[i];
@@ -777,7 +788,7 @@
last_endpoint = -1;
dummy_packets = 0;
- osmo_talloc_replace_string(cfg, &cfg->trunk.audio_fmtp_extra,
+ osmo_talloc_replace_string(cfg, &cfg->trunk->audio_fmtp_extra,
t->extra_fmtp);
inp = create_msg(t->req, last_conn_id);
@@ -810,7 +821,7 @@
printf("Dummy packets: %d\n", dummy_packets);
if (last_endpoint != -1) {
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
conn = mgcp_conn_get_rtp(endp, "1");
if (conn) {
@@ -866,7 +877,7 @@
/* Check detected payload type */
if (conn && t->ptype != PTYPE_IGNORE) {
OSMO_ASSERT(last_endpoint != -1);
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
fprintf(stderr, "endpoint 0x%x: "
"payload type %d (expected %d)\n",
@@ -883,27 +894,27 @@
}
mgcp_endpoints_release(trunk2);
- mgcp_endpoints_release(&cfg->trunk);
+ mgcp_endpoints_release(cfg->trunk);
talloc_free(cfg);
}
static void test_retransmission(void)
{
struct mgcp_config *cfg;
- struct mgcp_trunk_config *trunk2;
+ struct mgcp_trunk *trunk2;
int i;
char last_conn_id[256];
int rc;
cfg = mgcp_config_alloc();
- cfg->trunk.vty_number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
+ cfg->trunk->vty_number_endpoints = 64;
+ mgcp_trunk_alloc_endpts(cfg->trunk);
memset(last_conn_id, 0, sizeof(last_conn_id));
- trunk2 = mgcp_trunk_alloc(cfg, 1);
- mgcp_endpoints_allocate(trunk2);
+ trunk2 = mgcp_trunk_alloc(cfg, 1, MGCP_TRUNK_E1);
+ mgcp_trunk_alloc_endpts(trunk2);
for (i = 0; i < ARRAY_SIZE(retransmit); i++) {
const struct mgcp_test *t = &retransmit[i];
@@ -944,7 +955,7 @@
}
mgcp_endpoints_release(trunk2);
- mgcp_endpoints_release(&cfg->trunk);
+ mgcp_endpoints_release(cfg->trunk);
talloc_free(cfg);
}
@@ -958,18 +969,18 @@
static void test_rqnt_cb(void)
{
struct mgcp_config *cfg;
- struct mgcp_trunk_config *trunk2;
+ struct mgcp_trunk *trunk2;
struct msgb *inp, *msg;
char conn_id[256];
cfg = mgcp_config_alloc();
cfg->rqnt_cb = rqnt_cb;
- cfg->trunk.vty_number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
+ cfg->trunk->vty_number_endpoints = 64;
+ mgcp_trunk_alloc_endpts(cfg->trunk);
- trunk2 = mgcp_trunk_alloc(cfg, 1);
- mgcp_endpoints_allocate(trunk2);
+ trunk2 = mgcp_trunk_alloc(cfg, 1, MGCP_TRUNK_E1);
+ mgcp_trunk_alloc_endpts(trunk2);
inp = create_msg(CRCX, NULL);
msg = mgcp_handle_message(cfg, inp);
@@ -999,7 +1010,7 @@
msgb_free(mgcp_handle_message(cfg, inp));
msgb_free(inp);
mgcp_endpoints_release(trunk2);
- mgcp_endpoints_release(&cfg->trunk);
+ mgcp_endpoints_release(cfg->trunk);
talloc_free(cfg);
}
@@ -1035,8 +1046,9 @@
{
int i;
struct mgcp_endpoint endp;
+ struct mgcp_endpoint *endpoints[1];
struct mgcp_config cfg = {0};
- struct mgcp_trunk_config trunk;
+ struct mgcp_trunk trunk;
printf("Testing packet loss calculation.\n");
@@ -1046,8 +1058,9 @@
endp.cfg = &cfg;
endp.type = &ep_typeset.rtp;
trunk.vty_number_endpoints = 1;
- trunk.endpoints = &endp;
- endp.tcfg = &trunk;
+ trunk.endpoints = endpoints;
+ trunk.endpoints[0] = &endp;
+ endp.trunk = &trunk;
INIT_LLIST_HEAD(&endp.conns);
for (i = 0; i < ARRAY_SIZE(pl_test_dat); ++i) {
@@ -1262,8 +1275,9 @@
{
int i;
- struct mgcp_trunk_config trunk;
+ struct mgcp_trunk trunk;
struct mgcp_endpoint endp;
+ struct mgcp_endpoint *endpoints[1];
struct mgcp_config cfg = {0};
struct mgcp_rtp_state state;
struct mgcp_rtp_end *rtp;
@@ -1296,11 +1310,12 @@
endp.type = &ep_typeset.rtp;
trunk.vty_number_endpoints = 1;
- trunk.endpoints = &endp;
+ trunk.endpoints = endpoints;
+ trunk.endpoints[0] = &endp;
trunk.force_constant_ssrc = patch_ssrc;
trunk.force_aligned_timing = patch_ts;
- endp.tcfg = &trunk;
+ endp.trunk = &trunk;
INIT_LLIST_HEAD(&endp.conns);
_conn = mgcp_conn_alloc(NULL, &endp, MGCP_CONN_TYPE_RTP,
@@ -1361,7 +1376,7 @@
static void test_multilple_codec(void)
{
struct mgcp_config *cfg;
- struct mgcp_trunk_config *trunk2;
+ struct mgcp_trunk *trunk2;
struct mgcp_endpoint *endp;
struct msgb *inp, *resp;
struct in_addr addr;
@@ -1371,12 +1386,12 @@
printf("Testing multiple payload types\n");
cfg = mgcp_config_alloc();
- cfg->trunk.vty_number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
+ cfg->trunk->vty_number_endpoints = 64;
+ mgcp_trunk_alloc_endpts(cfg->trunk);
cfg->policy_cb = mgcp_test_policy_cb;
- trunk2 = mgcp_trunk_alloc(cfg, 1);
- mgcp_endpoints_allocate(trunk2);
+ trunk2 = mgcp_trunk_alloc(cfg, 1, MGCP_TRUNK_E1);
+ mgcp_trunk_alloc_endpts(trunk2);
/* Allocate endpoint 1 at mgw with two codecs */
last_endpoint = -1;
@@ -1388,7 +1403,7 @@
msgb_free(resp);
OSMO_ASSERT(last_endpoint == 1);
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
conn = mgcp_conn_get_rtp(endp, conn_id);
OSMO_ASSERT(conn);
OSMO_ASSERT(conn->end.codec->payload_type == 18);
@@ -1403,7 +1418,7 @@
msgb_free(resp);
OSMO_ASSERT(last_endpoint == 2);
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
conn = mgcp_conn_get_rtp(endp, conn_id);
OSMO_ASSERT(conn);
OSMO_ASSERT(conn->end.codec->payload_type == 18);
@@ -1423,7 +1438,7 @@
msgb_free(resp);
OSMO_ASSERT(last_endpoint == 3);
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
conn = mgcp_conn_get_rtp(endp, conn_id);
OSMO_ASSERT(conn);
OSMO_ASSERT(conn->end.codec->payload_type == 0);
@@ -1438,7 +1453,7 @@
msgb_free(resp);
OSMO_ASSERT(last_endpoint == 4);
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
conn = mgcp_conn_get_rtp(endp, conn_id);
OSMO_ASSERT(conn);
OSMO_ASSERT(conn->end.codec->payload_type == 18);
@@ -1446,9 +1461,9 @@
/* Allocate 5 at mgw at select GSM.. */
last_endpoint = -1;
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;
+ 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);
@@ -1456,7 +1471,7 @@
msgb_free(resp);
OSMO_ASSERT(last_endpoint == 5);
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
conn = mgcp_conn_get_rtp(endp, conn_id);
OSMO_ASSERT(conn);
OSMO_ASSERT(conn->end.codec->payload_type == 3);
@@ -1467,7 +1482,7 @@
msgb_free(inp);
msgb_free(resp);
OSMO_ASSERT(last_endpoint == 5);
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
conn = mgcp_conn_get_rtp(endp, conn_id);
OSMO_ASSERT(conn);
OSMO_ASSERT(conn->end.codec->payload_type == 3);
@@ -1489,7 +1504,7 @@
last_endpoint = -1;
inp = create_msg(CRCX_MULT_GSM_EXACT, NULL);
- cfg->trunk.no_audio_transcoding = 0;
+ 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);
@@ -1497,13 +1512,13 @@
msgb_free(resp);
OSMO_ASSERT(last_endpoint == 5);
- endp = &cfg->trunk.endpoints[last_endpoint];
+ endp = cfg->trunk->endpoints[last_endpoint];
conn = mgcp_conn_get_rtp(endp, conn_id);
OSMO_ASSERT(conn);
OSMO_ASSERT(conn->end.codec->payload_type == 0);
mgcp_endpoints_release(trunk2);
- mgcp_endpoints_release(&cfg->trunk);
+ mgcp_endpoints_release(cfg->trunk);
talloc_free(cfg);
}
@@ -1517,10 +1532,10 @@
printf("Testing no sequence flow on initial packet\n");
cfg = mgcp_config_alloc();
- cfg->trunk.vty_number_endpoints = 64;
- mgcp_endpoints_allocate(&cfg->trunk);
+ cfg->trunk->vty_number_endpoints = 64;
+ mgcp_trunk_alloc_endpts(cfg->trunk);
- endp = &cfg->trunk.endpoints[1];
+ endp = cfg->trunk->endpoints[1];
_conn = mgcp_conn_alloc(NULL, endp, MGCP_CONN_TYPE_RTP,
"test-connection");
@@ -1552,27 +1567,27 @@
OSMO_ASSERT(conn->state.stats.cycles == UINT16_MAX + 1);
OSMO_ASSERT(conn->state.stats.max_seq == 0);
- mgcp_endpoints_release(&cfg->trunk);
+ mgcp_endpoints_release(cfg->trunk);
talloc_free(cfg);
}
static void test_no_name(void)
{
- struct mgcp_trunk_config *trunk2;
+ struct mgcp_trunk *trunk2;
struct mgcp_config *cfg;
struct msgb *inp, *msg;
printf("Testing no rtpmap name\n");
cfg = mgcp_config_alloc();
- cfg->trunk.vty_number_endpoints = 64;
- cfg->trunk.audio_send_name = 0;
- mgcp_endpoints_allocate(&cfg->trunk);
+ cfg->trunk->vty_number_endpoints = 64;
+ cfg->trunk->audio_send_name = 0;
+ mgcp_trunk_alloc_endpts(cfg->trunk);
cfg->policy_cb = mgcp_test_policy_cb;
- trunk2 = mgcp_trunk_alloc(cfg, 1);
- mgcp_endpoints_allocate(trunk2);
+ trunk2 = mgcp_trunk_alloc(cfg, 1, MGCP_TRUNK_E1);
+ mgcp_trunk_alloc_endpts(trunk2);
inp = create_msg(CRCX, NULL);
msg = mgcp_handle_message(cfg, inp);
@@ -1586,7 +1601,7 @@
msgb_free(msg);
mgcp_endpoints_release(trunk2);
- mgcp_endpoints_release(&cfg->trunk);
+ mgcp_endpoints_release(cfg->trunk);
talloc_free(cfg);
}
--
To view, visit https://gerrit.osmocom.org/c/osmo-mgw/+/18372
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-Change-Id: Ice8aaf03faa2fd99074f8665eea3a696d30c5eb3
Gerrit-Change-Number: 18372
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200519/eed4e750/attachment.htm>