diff --git a/include/osmocom/mgcp/mgcp_ratectr.h b/include/osmocom/mgcp/mgcp_ratectr.h index 78c687b75..0bd6f88b7 100644 --- a/include/osmocom/mgcp/mgcp_ratectr.h +++ b/include/osmocom/mgcp/mgcp_ratectr.h @@ -95,3 +95,17 @@ struct mgcp_trunk; int mgcp_ratectr_global_alloc(struct mgcp_config *cfg); int mgcp_ratectr_trunk_alloc(struct mgcp_trunk *trunk); + +/* Trunk-global common stat items */ +enum { + TRUNK_STAT_ENDPOINTS_TOTAL, + TRUNK_STAT_ENDPOINTS_USED, +}; + +struct mgcp_stat_trunk { + /* Stat item group which contains general status values of the trunk. */ + struct osmo_stat_item_group *common; +}; + +int mgcp_stat_trunk_alloc(struct mgcp_trunk *trunk); + diff --git a/include/osmocom/mgcp/mgcp_trunk.h b/include/osmocom/mgcp/mgcp_trunk.h index 048ac5bca..d960428b7 100644 --- a/include/osmocom/mgcp/mgcp_trunk.h +++ b/include/osmocom/mgcp/mgcp_trunk.h @@ -52,8 +52,9 @@ struct mgcp_trunk { unsigned int number_endpoints; struct mgcp_endpoint **endpoints; - /* global rate counters to measure the trunks overall performance and health */ + /* rate counters and stat items to measure the trunks overall performance and health */ struct mgcp_ratectr_trunk ratectr; + struct mgcp_stat_trunk stats; union { /* Virtual trunk specific */ diff --git a/src/libosmo-mgcp/mgcp_endp.c b/src/libosmo-mgcp/mgcp_endp.c index ae376b099..7df4a8062 100644 --- a/src/libosmo-mgcp/mgcp_endp.c +++ b/src/libosmo-mgcp/mgcp_endp.c @@ -29,6 +29,7 @@ #include #include +#include #define E1_RATE_MAX 64 #define E1_OFFS_MAX 8 @@ -122,6 +123,12 @@ void mgcp_endp_release(struct mgcp_endpoint *endp) * RSIP is executed), free them all at once. */ mgcp_conn_free_all(endp); + /* We must only decrement the stat item when the endpoint as actually + * claimed. An endpoint is claimed when a call-id is set */ + if (endp->callid) + osmo_stat_item_dec(osmo_stat_item_group_get_item(endp->trunk->stats.common, + TRUNK_STAT_ENDPOINTS_USED), 1); + /* Reset endpoint parameters and states */ talloc_free(endp->callid); endp->callid = NULL; @@ -631,6 +638,8 @@ int mgcp_endp_claim(struct mgcp_endpoint *endp, const char *callid) * connection ids) */ endp->callid = talloc_strdup(endp, callid); OSMO_ASSERT(endp->callid); + osmo_stat_item_inc(osmo_stat_item_group_get_item(endp->trunk->stats.common, + TRUNK_STAT_ENDPOINTS_USED), 1); /* Allocate resources */ switch (endp->trunk->trunk_type) { diff --git a/src/libosmo-mgcp/mgcp_ratectr.c b/src/libosmo-mgcp/mgcp_ratectr.c index 1f8b23313..740a3b096 100644 --- a/src/libosmo-mgcp/mgcp_ratectr.c +++ b/src/libosmo-mgcp/mgcp_ratectr.c @@ -24,8 +24,11 @@ #include #include +#include #include #include +#include +#include #include static const struct rate_ctr_desc mgcp_general_ctr_desc[] = { @@ -248,3 +251,41 @@ int mgcp_ratectr_trunk_alloc(struct mgcp_trunk *trunk) } return 0; } + +const struct osmo_stat_item_desc trunk_stat_desc[] = { + [TRUNK_STAT_ENDPOINTS_TOTAL] = { "endpoints:total", + "Number of endpoints that exist on the trunk", + "", 60, 0 }, + [TRUNK_STAT_ENDPOINTS_USED] = { "endpoints:used", + "Number of endpoints in use", + "", 60, 0 }, +}; + +const struct osmo_stat_item_group_desc trunk_statg_desc = { + .group_name_prefix = "trunk", + .group_description = "mgw trunk", + .class_id = OSMO_STATS_CLASS_GLOBAL, + .num_items = ARRAY_SIZE(trunk_stat_desc), + .item_desc = trunk_stat_desc, +}; + +/*! allocate trunk specific stat items + * (called once on trunk initialization). + * \param[in] trunk for which the stat items are allocated. + * \returns 0 on success, -EINVAL on failure. */ +int mgcp_stat_trunk_alloc(struct mgcp_trunk *trunk) +{ + struct mgcp_stat_trunk *stats = &trunk->stats; + static unsigned int common_stat_index = 0; + char stat_name[256]; + + stats->common = osmo_stat_item_group_alloc(trunk, &trunk_statg_desc, common_stat_index); + if (!stats->common) + return -EINVAL; + snprintf(stat_name, sizeof(stat_name), "%s-%u:common", mgcp_trunk_type_strs_str(trunk->trunk_type), + trunk->trunk_nr); + osmo_stat_item_group_set_name(stats->common, stat_name); + common_stat_index++; + + return 0; +} diff --git a/src/libosmo-mgcp/mgcp_trunk.c b/src/libosmo-mgcp/mgcp_trunk.c index 27663b490..b2d196930 100644 --- a/src/libosmo-mgcp/mgcp_trunk.c +++ b/src/libosmo-mgcp/mgcp_trunk.c @@ -27,6 +27,7 @@ #include #include #include +#include const struct value_string mgcp_trunk_type_strs[] = { { MGCP_TRUNK_VIRTUAL, "virtual" }, @@ -64,6 +65,7 @@ struct mgcp_trunk *mgcp_trunk_alloc(struct mgcp_config *cfg, enum mgcp_trunk_typ llist_add_tail(&trunk->entry, &cfg->trunks); mgcp_ratectr_trunk_alloc(trunk); + mgcp_stat_trunk_alloc(trunk); return trunk; } @@ -127,7 +129,8 @@ int mgcp_trunk_alloc_endpts(struct mgcp_trunk *trunk) /* make the endpoints we just created available to the MGW code */ trunk->number_endpoints = number_endpoints; - + osmo_stat_item_set(osmo_stat_item_group_get_item(trunk->stats.common, TRUNK_STAT_ENDPOINTS_TOTAL), + trunk->number_endpoints); return 0; } diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c index bcbcc02e5..26fcc2a22 100644 --- a/tests/mgcp/mgcp_test.c +++ b/tests/mgcp/mgcp_test.c @@ -1065,20 +1065,20 @@ static void test_packet_loss_calc(void) int i; struct mgcp_endpoint endp; struct mgcp_endpoint *endpoints[1]; - struct mgcp_config cfg = {0}; - struct mgcp_trunk trunk; + struct mgcp_config *cfg; + struct mgcp_trunk *trunk; printf("Testing packet loss calculation.\n"); memset(&endp, 0, sizeof(endp)); - memset(&trunk, 0, sizeof(trunk)); - - endp.cfg = &cfg; + cfg = mgcp_config_alloc(); + trunk = mgcp_trunk_alloc(cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID); + endp.cfg = cfg; endp.type = &ep_typeset.rtp; - trunk.v.vty_number_endpoints = 1; - trunk.endpoints = endpoints; - trunk.endpoints[0] = &endp; - endp.trunk = &trunk; + trunk->v.vty_number_endpoints = 1; + trunk->endpoints = endpoints; + trunk->endpoints[0] = &endp; + endp.trunk = trunk; INIT_LLIST_HEAD(&endp.conns); for (i = 0; i < ARRAY_SIZE(pl_test_dat); ++i) { @@ -1116,6 +1116,8 @@ static void test_packet_loss_calc(void) mgcp_conn_free_all(&endp); } + talloc_free(trunk); + talloc_free(cfg); } int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os, @@ -1297,10 +1299,10 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) { int i; - struct mgcp_trunk trunk; + struct mgcp_trunk *trunk; struct mgcp_endpoint endp; struct mgcp_endpoint *endpoints[1]; - struct mgcp_config cfg = {0}; + struct mgcp_config *cfg; struct mgcp_rtp_state state; struct mgcp_rtp_end *rtp; struct osmo_sockaddr addr = { 0 }; @@ -1318,7 +1320,8 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) patch_ssrc ? ", patch SSRC" : "", patch_ts ? ", patch timestamps" : ""); - memset(&trunk, 0, sizeof(trunk)); + cfg = mgcp_config_alloc(); + trunk = mgcp_trunk_alloc(cfg, MGCP_TRUNK_VIRTUAL, MGCP_VIRT_TRUNK_ID); memset(&endp, 0, sizeof(endp)); memset(&state, 0, sizeof(state)); @@ -1327,16 +1330,16 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) state.in_stream.err_ts_ctr = &test_ctr_in; state.out_stream.err_ts_ctr = &test_ctr_out; - endp.cfg = &cfg; + endp.cfg = cfg; endp.type = &ep_typeset.rtp; - trunk.v.vty_number_endpoints = 1; - trunk.endpoints = endpoints; - trunk.endpoints[0] = &endp; - trunk.force_constant_ssrc = patch_ssrc; - trunk.force_aligned_timing = patch_ts; + trunk->v.vty_number_endpoints = 1; + trunk->endpoints = endpoints; + trunk->endpoints[0] = &endp; + trunk->force_constant_ssrc = patch_ssrc; + trunk->force_aligned_timing = patch_ts; - endp.trunk = &trunk; + endp.trunk = trunk; INIT_LLIST_HEAD(&endp.conns); _conn = mgcp_conn_alloc(NULL, &endp, MGCP_CONN_TYPE_RTP, @@ -1395,6 +1398,8 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) force_monotonic_time_us = -1; mgcp_conn_free_all(&endp); + talloc_free(trunk); + talloc_free(cfg); } static void test_multilple_codec(void)