osmo-mgw: refactor endpoint and trunk handling
The trunk and endpoint handling in osmo-mgw is still very complex and
implemented in various places (mostly mgcp_protocol.c). Also we use
still integers for endpoint identification, which is not flexible enough
to address timeslots/subslots on an E1 trunk. Some refactoring is needed.
- get rid of integers as endpoint identifiers, use strings instead and
find the endpoint based on its string name on the trunk.
- identify the trunk based on the trunk prefix given in the endpoint
name.
- refactor trunk and endpoint allocation. Aggregate functionality in
in mgcp_endp.c and mgcp_trunk.c. Also remove non-reusable code that
relates to the still exisiting, but unfinished E1 trunk support.
- refactor rate counters, put them into a separate module and do no
longer allocate them per trunk. Allocate them globally instead.
Change-Id: Ia8cf4d6caf05a4e13f1f507dc68cbabb7e6239aa
Related: OS#2659
diff --git a/src/libosmo-mgcp/mgcp_vty.c b/src/libosmo-mgcp/mgcp_vty.c
index 7278c1c..54b139a 100644
--- a/src/libosmo-mgcp/mgcp_vty.c
+++ b/src/libosmo-mgcp/mgcp_vty.c
@@ -29,6 +29,7 @@
#include <osmocom/mgcp/vty.h>
#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_endp.h>
+#include <osmocom/mgcp/mgcp_trunk.h>
#include <string.h>
#include <inttypes.h>
@@ -49,7 +50,7 @@
if (nr == 0)
trunk = cfg->virt_trunk;
else
- trunk = mgcp_trunk_num(cfg, nr);
+ trunk = mgcp_trunk_by_num(cfg, nr);
return trunk;
}
@@ -208,15 +209,13 @@
end->force_output_ptime, VTY_NEWLINE);
}
-static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp, int epidx,
+static void dump_endpoint(struct vty *vty, struct mgcp_endpoint *endp,
int trunk_nr, enum mgcp_trunk_type trunk_type, int show_stats)
{
struct mgcp_conn *conn;
- vty_out(vty, "%s trunk %d endpoint %s%.2x:%s",
- trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr,
- trunk_type == MGCP_TRUNK_VIRTUAL ? MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK : "",
- epidx, VTY_NEWLINE);
+ vty_out(vty, "%s trunk %d endpoint %s:%s",
+ trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1", trunk_nr, endp->name, VTY_NEWLINE);
if (llist_empty(&endp->conns)) {
vty_out(vty, " No active connections%s", VTY_NEWLINE);
@@ -244,50 +243,84 @@
}
}
-static void dump_trunk(struct vty *vty, struct mgcp_trunk *cfg, int show_stats)
+static void dump_ratectr_global(struct vty *vty, struct mgcp_ratectr_global *ratectr)
+{
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "Rate counters (global):%s", VTY_NEWLINE);
+
+ if (ratectr->mgcp_general_ctr_group) {
+ vty_out(vty, " %s:%s",
+ ratectr->mgcp_general_ctr_group->desc->
+ group_description, VTY_NEWLINE);
+ vty_out_rate_ctr_group_fmt(vty,
+ " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
+ ratectr->mgcp_general_ctr_group);
+ }
+}
+
+static void dump_ratectr_trunk(struct vty *vty, struct mgcp_ratectr_trunk *ratectr)
+{
+ vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "Rate counters (trunk):%s", VTY_NEWLINE);
+
+ if (ratectr->mgcp_crcx_ctr_group) {
+ vty_out(vty, " %s:%s",
+ ratectr->mgcp_crcx_ctr_group->desc->group_description,
+ VTY_NEWLINE);
+ vty_out_rate_ctr_group_fmt(vty,
+ " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
+ ratectr->mgcp_crcx_ctr_group);
+ }
+ if (ratectr->mgcp_dlcx_ctr_group) {
+ vty_out(vty, " %s:%s",
+ ratectr->mgcp_dlcx_ctr_group->desc->group_description,
+ VTY_NEWLINE);
+ vty_out_rate_ctr_group_fmt(vty,
+ " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
+ ratectr->mgcp_dlcx_ctr_group);
+ }
+ if (ratectr->mgcp_mdcx_ctr_group) {
+ vty_out(vty, " %s:%s",
+ ratectr->mgcp_mdcx_ctr_group->desc->group_description,
+ VTY_NEWLINE);
+ vty_out_rate_ctr_group_fmt(vty,
+ " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
+ ratectr->mgcp_mdcx_ctr_group);
+ }
+ if (ratectr->all_rtp_conn_stats) {
+ vty_out(vty, " %s:%s",
+ ratectr->all_rtp_conn_stats->desc->group_description,
+ VTY_NEWLINE);
+ vty_out_rate_ctr_group_fmt(vty,
+ " %25n: %10c (%S/s %M/m %H/h %D/d) %d",
+ ratectr->all_rtp_conn_stats);
+ }
+}
+
+
+static void dump_trunk(struct vty *vty, struct mgcp_trunk *trunk, int show_stats)
{
int i;
vty_out(vty, "%s trunk %d with %d endpoints:%s",
- cfg->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
- cfg->trunk_nr, cfg->number_endpoints - 1, VTY_NEWLINE);
+ trunk->trunk_type == MGCP_TRUNK_VIRTUAL ? "Virtual" : "E1",
+ trunk->trunk_nr, trunk->number_endpoints - 1, VTY_NEWLINE);
- if (!cfg->endpoints) {
+ if (!trunk->endpoints) {
vty_out(vty, "No endpoints allocated yet.%s", VTY_NEWLINE);
return;
}
- for (i = 0; i < cfg->number_endpoints; ++i) {
- struct mgcp_endpoint *endp = &cfg->endpoints[i];
- dump_endpoint(vty, endp, i, cfg->trunk_nr, cfg->trunk_type, show_stats);
- if (i < cfg->number_endpoints - 1)
+ for (i = 0; i < trunk->number_endpoints; ++i) {
+ struct mgcp_endpoint *endp = trunk->endpoints[i];
+ dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type,
+ show_stats);
+ if (i < trunk->number_endpoints - 1)
vty_out(vty, "%s", VTY_NEWLINE);
}
- if (show_stats) {
- vty_out(vty, "%s", VTY_NEWLINE);
- vty_out(vty, "Rate counters:%s", VTY_NEWLINE);
- }
- if (show_stats && cfg->mgcp_general_ctr_group) {
- vty_out(vty, " %s:%s", cfg->mgcp_general_ctr_group->desc->group_description, VTY_NEWLINE);
- vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->mgcp_general_ctr_group);
- }
- if (show_stats && cfg->mgcp_crcx_ctr_group) {
- vty_out(vty, " %s:%s", cfg->mgcp_crcx_ctr_group->desc->group_description, VTY_NEWLINE);
- vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->mgcp_crcx_ctr_group);
- }
- if (show_stats && cfg->mgcp_dlcx_ctr_group) {
- vty_out(vty, " %s:%s", cfg->mgcp_dlcx_ctr_group->desc->group_description, VTY_NEWLINE);
- vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->mgcp_dlcx_ctr_group);
- }
- if (show_stats && cfg->mgcp_mdcx_ctr_group) {
- vty_out(vty, " %s:%s", cfg->mgcp_mdcx_ctr_group->desc->group_description, VTY_NEWLINE);
- vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->mgcp_mdcx_ctr_group);
- }
- if (show_stats && cfg->all_rtp_conn_stats) {
- vty_out(vty, " %s:%s", cfg->all_rtp_conn_stats->desc->group_description, VTY_NEWLINE);
- vty_out_rate_ctr_group_fmt(vty, " %25n: %10c (%S/s %M/m %H/h %D/d) %d", cfg->all_rtp_conn_stats);
- }
+ if (show_stats)
+ dump_ratectr_trunk(vty, &trunk->ratectr);
}
#define SHOW_MGCP_STR "Display information about the MGCP Media Gateway\n"
@@ -304,44 +337,41 @@
dump_trunk(vty, g_cfg->virt_trunk, show_stats);
llist_for_each_entry(trunk, &g_cfg->trunks, entry)
- dump_trunk(vty, trunk, show_stats);
+ dump_trunk(vty, trunk, show_stats);
if (g_cfg->osmux)
vty_out(vty, "Osmux used CID: %d%s", osmux_cid_pool_count_used(),
VTY_NEWLINE);
+ if (show_stats)
+ dump_ratectr_global(vty, &g_cfg->ratectr);
+
return CMD_SUCCESS;
}
static void
dump_mgcp_endpoint(struct vty *vty, struct mgcp_trunk *trunk, const char *epname)
{
- const size_t virt_prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK) - 1;
- unsigned long epidx;
- char *endp;
- int i;
+ struct mgcp_endpoint *endp;
- if (strncmp(epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, virt_prefix_len) == 0)
- epname += virt_prefix_len;
- errno = 0;
- epidx = strtoul(epname, &endp, 16);
- if (epname[0] == '\0' || *endp != '\0') {
- vty_out(vty, "endpoint name '%s' is not a hex number%s", epname, VTY_NEWLINE);
- return;
- }
- if ((errno == ERANGE && epidx == ULONG_MAX) /* parsed value out of range */
- || epidx >= trunk->number_endpoints) {
- vty_out(vty, "endpoint %.2lx not configured on trunk %d%s", epidx, trunk->trunk_nr, VTY_NEWLINE);
- return;
- }
-
- for (i = 0; i < trunk->number_endpoints; ++i) {
- struct mgcp_endpoint *endp = &trunk->endpoints[i];
- if (i == epidx) {
- dump_endpoint(vty, endp, i, trunk->trunk_nr, trunk->trunk_type, true);
- break;
+ if (trunk) {
+ /* If a trunk is given, search on that specific trunk only */
+ endp = mgcp_endp_by_name_trunk(NULL, epname, trunk);
+ if (!endp) {
+ vty_out(vty, "endpoint %s not configured on trunk %d%s", epname, trunk->trunk_nr, VTY_NEWLINE);
+ return;
+ }
+ } else {
+ /* If no trunk is given, search on all possible trunks */
+ endp = mgcp_endp_by_name(NULL, epname, g_cfg);
+ if (!endp) {
+ vty_out(vty, "endpoint %s not configured%s", epname, VTY_NEWLINE);
+ return;
}
}
+
+ trunk = endp->trunk;
+ dump_endpoint(vty, endp, trunk->trunk_nr, trunk->trunk_type, true);
}
DEFUN(show_mcgp_endpoint, show_mgcp_endpoint_cmd,
@@ -350,12 +380,7 @@
SHOW_MGCP_STR
"Display information about an endpoint\n" "The name of the endpoint\n")
{
- struct mgcp_trunk *trunk;
-
- dump_mgcp_endpoint(vty, g_cfg->virt_trunk, argv[0]);
- llist_for_each_entry(trunk, &g_cfg->trunks, entry)
- dump_mgcp_endpoint(vty, trunk, argv[0]);
-
+ dump_mgcp_endpoint(vty, NULL, argv[0]);
return CMD_SUCCESS;
}
@@ -810,7 +835,7 @@
struct mgcp_trunk *trunk;
int index = atoi(argv[0]);
- trunk = mgcp_trunk_num(g_cfg, index);
+ trunk = mgcp_trunk_by_num(g_cfg, index);
if (!trunk) {
trunk = mgcp_trunk_alloc(g_cfg, MGCP_TRUNK_E1, index);
if (!trunk) {
@@ -1138,7 +1163,7 @@
return CMD_WARNING;
}
- endp = &trunk->endpoints[endp_no];
+ endp = trunk->endpoints[endp_no];
int loop = atoi(argv[2]);
llist_for_each_entry(conn, &endp->conns, entry) {
if (conn->type == MGCP_CONN_TYPE_RTP)
@@ -1197,7 +1222,7 @@
return CMD_WARNING;
}
- endp = &trunk->endpoints[endp_no];
+ endp = trunk->endpoints[endp_no];
conn_id = argv[2];
conn = mgcp_conn_get_rtp(endp, conn_id);
@@ -1250,7 +1275,7 @@
return CMD_WARNING;
}
- endp = &trunk->endpoints[endp_no];
+ endp = trunk->endpoints[endp_no];
mgcp_endp_release(endp);
return CMD_SUCCESS;
}
@@ -1283,8 +1308,8 @@
return CMD_WARNING;
}
- endp = &trunk->endpoints[endp_no];
- rc = mgcp_send_reset_ep(endp, ENDPOINT_NUMBER(endp));
+ endp = trunk->endpoints[endp_no];
+ rc = mgcp_send_reset_ep(endp);
if (rc < 0) {
vty_out(vty, "Error %d sending reset.%s", rc, VTY_NEWLINE);
return CMD_WARNING;
@@ -1521,7 +1546,7 @@
return -1;
}
- if (mgcp_endpoints_allocate(g_cfg->virt_trunk) != 0) {
+ if (mgcp_trunk_alloc_endpts(g_cfg->virt_trunk) != 0) {
LOGP(DLMGCP, LOGL_ERROR,
"Failed to initialize the virtual trunk (%d endpoints)\n",
g_cfg->virt_trunk->number_endpoints);
@@ -1529,7 +1554,7 @@
}
llist_for_each_entry(trunk, &g_cfg->trunks, entry) {
- if (mgcp_endpoints_allocate(trunk) != 0) {
+ if (mgcp_trunk_alloc_endpts(trunk) != 0) {
LOGP(DLMGCP, LOGL_ERROR,
"Failed to initialize trunk %d (%d endpoints)\n",
trunk->trunk_nr, trunk->number_endpoints);