diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2012-09-14 17:18:12 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2012-11-12 10:42:05 +0100 |
commit | 0bf15a81878c9fce83d7cff8842c52b5839564b9 (patch) | |
tree | 7d64612dcbe5efa16bfc254da7f34d8c544b3dbb | |
parent | 2e8e659586e7f625b45921c28bf44aba69e99504 (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.
-rw-r--r-- | openbsc/include/openbsc/mgcp.h | 1 | ||||
-rw-r--r-- | openbsc/src/libmgcp/mgcp_protocol.c | 45 | ||||
-rw-r--r-- | openbsc/tests/mgcp/mgcp_test.c | 8 | ||||
-rw-r--r-- | openbsc/tests/mgcp/mgcp_test.ok | 1 |
4 files changed, 46 insertions, 9 deletions
diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index 751943ada..d618f3cdb 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -168,6 +168,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 719a4c743..d57ad0024 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -107,9 +107,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; @@ -118,10 +118,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); @@ -129,9 +131,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) @@ -707,6 +722,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg) int error_code = 400; int silent = 0; char *line, *save; + char stats[1048]; for_each_line((char *) msg->l3h, line, save) { /* skip first line */ @@ -769,6 +785,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) @@ -776,7 +795,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); error3: return create_err_response(error_code, "DLCX", trans_id); @@ -1099,3 +1118,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'; +} diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index d151ebb1f..41a51dea0 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -67,6 +67,13 @@ "m=audio 5904 RTP/AVP 97\r" \ "a=rtpmap:97 GSM-EFR/8000\r" +#define DLCX "DLCX 7 1@mgw MGCP 1.0\r\n" \ + "C: 2\r\n" + +#define DLCX_RET "250 7 OK\r\n" \ + "P: PS=0, OS=0, PR=0, OR=0\r\n" + + struct mgcp_test { const char *name; const char *req; @@ -83,6 +90,7 @@ const struct mgcp_test tests[] = { { "SHORT2", SHORT2, SHORT2_RET }, { "SHORT3", SHORT3, SHORT2_RET }, { "SHORT4", SHORT4, SHORT2_RET }, + { "DLCX", DLCX, DLCX_RET }, }; static struct msgb *create_msg(const char *str) diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 45882a57f..5e0e47cab 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -7,4 +7,5 @@ Testing SHORT1 Testing SHORT2 Testing SHORT3 Testing SHORT4 +Testing DLCX Done |