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

<div style="display:none"> Gerrit-Project: osmo-mgw </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ice8aaf03faa2fd99074f8665eea3a696d30c5eb3 </div>
<div style="display:none"> Gerrit-Change-Number: 18372 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>