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.
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index 719a4c7..d57ad00 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -107,9 +107,9 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 
 	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 @@
 
 	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';
+}