aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-09-14 17:18:12 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-06-17 09:40:19 +0200
commit2fc26faebb5724bf503eb4a7fe0c8eff80fcd829 (patch)
tree192cbe7079fc88d9ed405ff5b1a3d9749bc62fad
parent0adefd304ec03ce689fba1531e4d7701f522909b (diff)
mgcp: Include statistics at the end of a connection
Follow the MGCP specification and send the collected statistics at the end of a call. Right now this does not include jitter, packet loss and delay. Conflicts: openbsc/src/libmgcp/mgcp_protocol.c openbsc/tests/mgcp/mgcp_test.c openbsc/tests/mgcp/mgcp_test.ok
-rw-r--r--openbsc/include/openbsc/mgcp.h1
-rw-r--r--openbsc/src/libmgcp/mgcp_protocol.c45
2 files changed, 37 insertions, 9 deletions
diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h
index 1af4d6545..1410f2b04 100644
--- a/openbsc/include/openbsc/mgcp.h
+++ b/openbsc/include/openbsc/mgcp.h
@@ -167,6 +167,7 @@ int mgcp_vty_init(void);
int mgcp_endpoints_allocate(struct mgcp_trunk_config *cfg);
void mgcp_free_endp(struct mgcp_endpoint *endp);
int mgcp_reset_transcoder(struct mgcp_config *cfg);
+void mgcp_format_stats(struct mgcp_endpoint *endp, char *stats, size_t size);
/*
* format helper functions
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index e2669a838..02fb72054 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -137,9 +137,9 @@ static struct msgb *mgcp_msgb_alloc(void)
return msg;
}
-struct msgb *mgcp_create_response_with_data(int code, const char *txt,
- const char *msg, const char *trans,
- const char *data)
+static struct msgb *create_resp(int code, const char *txt, const char *msg,
+ const char *trans, const char *param,
+ const char *sdp)
{
int len;
struct msgb *res;
@@ -148,10 +148,12 @@ struct msgb *mgcp_create_response_with_data(int code, const char *txt,
if (!res)
return NULL;
- if (data) {
- len = snprintf((char *) res->data, 2048, "%d %s%s\r\n%s", code, trans, txt, data);
- } else {
- len = snprintf((char *) res->data, 2048, "%d %s%s\r\n", code, trans, txt);
+ len = snprintf((char *) res->data, 2048, "%d %s%s%s\r\n%s",
+ code, trans, txt, param ? param : "", sdp ? sdp : "");
+ if (len < 0) {
+ LOGP(DMGCP, LOGL_ERROR, "Failed to sprintf MGCP response.\n");
+ msgb_free(res);
+ return NULL;
}
res->l2h = msgb_put(res, len);
@@ -159,9 +161,22 @@ struct msgb *mgcp_create_response_with_data(int code, const char *txt,
return res;
}
+struct msgb *mgcp_create_response_with_data(int code, const char *txt,
+ const char *msg, const char *trans,
+ const char *data)
+{
+ return create_resp(code, txt, msg, trans, NULL, data);
+}
+
+static struct msgb *create_ok_resp_with_param(int code, const char *msg,
+ const char *trans, const char *param)
+{
+ return create_resp(code, " OK", msg, trans, param, NULL);
+}
+
static struct msgb *create_ok_response(int code, const char *msg, const char *trans)
{
- return mgcp_create_response_with_data(code, " OK", msg, trans, NULL);
+ return create_ok_resp_with_param(code, msg, trans, NULL);
}
static struct msgb *create_err_response(int code, const char *msg, const char *trans)
@@ -776,6 +791,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
struct mgcp_endpoint *endp;
int error_code = 400;
int silent = 0;
+ char stats[1048];
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
@@ -834,6 +850,9 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
LOGP(DMGCP, LOGL_DEBUG, "Deleted endpoint on: 0x%x Server: %s:%u\n",
ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr), ntohs(endp->net_end.rtp_port));
+ /* save the statistics of the current call */
+ mgcp_format_stats(endp, stats, sizeof(stats));
+
delete_transcoder(endp);
mgcp_free_endp(endp);
if (cfg->change_cb)
@@ -841,7 +860,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
if (silent)
goto out_silent;
- return create_ok_response(250, "DLCX", trans_id);
+ return create_ok_resp_with_param(250, "DLCX", trans_id, stats);
error:
LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d\n",
@@ -1141,3 +1160,11 @@ int mgcp_reset_transcoder(struct mgcp_config *cfg)
return send_trans(cfg, mgcp_reset, sizeof mgcp_reset -1);
}
+
+void mgcp_format_stats(struct mgcp_endpoint *endp, char *msg, size_t size)
+{
+ snprintf(msg, size, "\r\nP: PS=%u, OS=%u, PR=%u, OR=%u",
+ endp->bts_end.packets, endp->bts_end.octets,
+ endp->net_end.packets, endp->net_end.octets);
+ msg[size - 1] = '\0';
+}