blob: 192f223b8d565ffc1980b9f9f7365b63ca1a06ec [file] [log] [blame]
Benny Prijono16a6b0e2006-05-12 10:20:03 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20
21/*
22 * DO NOT COMPILE THIS FILE ON ITS OWN!
23 *
24 * This file is included by siprtp.c to implement the reporting capability
25 * to a separate file, so that user can implement different reporting
26 * functionality (such as writing to XML file).
27 */
28
29static const char *good_number(char *buf, pj_int32_t val)
30{
31 if (val < 1000) {
32 pj_ansi_sprintf(buf, "%d", val);
33 } else if (val < 1000000) {
34 pj_ansi_sprintf(buf, "%d.%dK",
35 val / 1000,
36 (val % 1000) / 100);
37 } else {
38 pj_ansi_sprintf(buf, "%d.%02dM",
39 val / 1000000,
40 (val % 1000000) / 10000);
41 }
42
43 return buf;
44}
45
46
47static void print_call(int call_index)
48{
49 struct call *call = &app.call[call_index];
50 int len;
51 pjsip_inv_session *inv = call->inv;
52 pjsip_dialog *dlg = inv->dlg;
53 struct media_stream *audio = &call->media[0];
54 char userinfo[128];
55 char duration[80], last_update[80];
56 char bps[16], ipbps[16], packets[16], bytes[16], ipbytes[16];
57 pj_time_val now;
58
59 pj_gettimeofday(&now);
60
61 /* Print duration */
Benny Prijono65382db2006-05-14 18:50:09 +000062 if (inv->state >= PJSIP_INV_STATE_CONFIRMED && call->connect_time.sec) {
Benny Prijono16a6b0e2006-05-12 10:20:03 +000063
64 PJ_TIME_VAL_SUB(now, call->connect_time);
65
66 sprintf(duration, " [duration: %02ld:%02ld:%02ld.%03ld]",
67 now.sec / 3600,
68 (now.sec % 3600) / 60,
69 (now.sec % 60),
70 now.msec);
71
72 } else {
73 duration[0] = '\0';
74 }
75
76
77
78 /* Call number and state */
79 printf("Call #%d: %s%s\n", call_index, pjsip_inv_state_name(inv->state),
80 duration);
81
82
83
84 /* Call identification */
85 len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
86 if (len < 1)
87 pj_ansi_strcpy(userinfo, "<--uri too long-->");
88 else
89 userinfo[len] = '\0';
90
91 printf(" %s\n", userinfo);
92
93
94 if (call->inv == NULL || call->inv->state < PJSIP_INV_STATE_CONFIRMED ||
95 call->connect_time.sec == 0)
96 {
97 return;
98 }
99
100
101 /* Signaling quality */
102 {
103 char pdd[64], connectdelay[64];
104 pj_time_val t;
105
106 if (call->response_time.sec) {
107 t = call->response_time;
108 PJ_TIME_VAL_SUB(t, call->start_time);
109 sprintf(pdd, "got 1st response in %ld ms", PJ_TIME_VAL_MSEC(t));
110 } else {
111 pdd[0] = '\0';
112 }
113
114 if (call->connect_time.sec) {
115 t = call->connect_time;
116 PJ_TIME_VAL_SUB(t, call->start_time);
117 sprintf(connectdelay, ", connected after: %ld ms",
118 PJ_TIME_VAL_MSEC(t));
119 } else {
120 connectdelay[0] = '\0';
121 }
122
123 printf(" Signaling quality: %s%s\n", pdd, connectdelay);
124 }
125
126
127 printf(" Stream #0: audio %.*s@%dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n",
128 (int)audio->si.fmt.encoding_name.slen,
129 audio->si.fmt.encoding_name.ptr,
130 audio->clock_rate,
131 audio->samples_per_frame * 1000 / audio->clock_rate,
132 good_number(bps, audio->bytes_per_frame * audio->clock_rate / audio->samples_per_frame),
133 good_number(ipbps, (audio->bytes_per_frame+32) * audio->clock_rate / audio->samples_per_frame));
134
135 if (audio->rtcp.stat.rx.update_cnt == 0)
136 strcpy(last_update, "never");
137 else {
138 pj_gettimeofday(&now);
139 PJ_TIME_VAL_SUB(now, audio->rtcp.stat.rx.update);
140 sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
141 now.sec / 3600,
142 (now.sec % 3600) / 60,
143 now.sec % 60,
144 now.msec);
145 }
146
147 printf(" RX stat last update: %s\n"
148 " total %s packets %sB received (%sB +IP hdr)%s\n"
149 " pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
150 " (msec) min avg max last\n"
151 " loss period: %7.3f %7.3f %7.3f %7.3f%s\n"
152 " jitter : %7.3f %7.3f %7.3f %7.3f%s\n",
153 last_update,
154 good_number(packets, audio->rtcp.stat.rx.pkt),
155 good_number(bytes, audio->rtcp.stat.rx.bytes),
156 good_number(ipbytes, audio->rtcp.stat.rx.bytes + audio->rtcp.stat.rx.pkt * 32),
157 "",
158 audio->rtcp.stat.rx.loss,
159 audio->rtcp.stat.rx.loss * 100.0 / audio->rtcp.stat.rx.pkt,
160 audio->rtcp.stat.rx.dup,
161 audio->rtcp.stat.rx.dup * 100.0 / audio->rtcp.stat.rx.pkt,
162 audio->rtcp.stat.rx.reorder,
163 audio->rtcp.stat.rx.reorder * 100.0 / audio->rtcp.stat.rx.pkt,
164 "",
165 audio->rtcp.stat.rx.loss_period.min / 1000.0,
166 audio->rtcp.stat.rx.loss_period.avg / 1000.0,
167 audio->rtcp.stat.rx.loss_period.max / 1000.0,
168 audio->rtcp.stat.rx.loss_period.last / 1000.0,
169 "",
170 audio->rtcp.stat.rx.jitter.min / 1000.0,
171 audio->rtcp.stat.rx.jitter.avg / 1000.0,
172 audio->rtcp.stat.rx.jitter.max / 1000.0,
173 audio->rtcp.stat.rx.jitter.last / 1000.0,
174 ""
175 );
176
177
178 if (audio->rtcp.stat.tx.update_cnt == 0)
179 strcpy(last_update, "never");
180 else {
181 pj_gettimeofday(&now);
182 PJ_TIME_VAL_SUB(now, audio->rtcp.stat.tx.update);
183 sprintf(last_update, "%02ldh:%02ldm:%02ld.%03lds ago",
184 now.sec / 3600,
185 (now.sec % 3600) / 60,
186 now.sec % 60,
187 now.msec);
188 }
189
190 printf(" TX stat last update: %s\n"
191 " total %s packets %sB sent (%sB +IP hdr)%s\n"
192 " pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
193 " (msec) min avg max last\n"
194 " loss period: %7.3f %7.3f %7.3f %7.3f%s\n"
195 " jitter : %7.3f %7.3f %7.3f %7.3f%s\n",
196 last_update,
197 good_number(packets, audio->rtcp.stat.tx.pkt),
198 good_number(bytes, audio->rtcp.stat.tx.bytes),
199 good_number(ipbytes, audio->rtcp.stat.tx.bytes + audio->rtcp.stat.tx.pkt * 32),
200 "",
201 audio->rtcp.stat.tx.loss,
202 audio->rtcp.stat.tx.loss * 100.0 / audio->rtcp.stat.tx.pkt,
203 audio->rtcp.stat.tx.dup,
204 audio->rtcp.stat.tx.dup * 100.0 / audio->rtcp.stat.tx.pkt,
205 audio->rtcp.stat.tx.reorder,
206 audio->rtcp.stat.tx.reorder * 100.0 / audio->rtcp.stat.tx.pkt,
207 "",
208 audio->rtcp.stat.tx.loss_period.min / 1000.0,
209 audio->rtcp.stat.tx.loss_period.avg / 1000.0,
210 audio->rtcp.stat.tx.loss_period.max / 1000.0,
211 audio->rtcp.stat.tx.loss_period.last / 1000.0,
212 "",
213 audio->rtcp.stat.tx.jitter.min / 1000.0,
214 audio->rtcp.stat.tx.jitter.avg / 1000.0,
215 audio->rtcp.stat.tx.jitter.max / 1000.0,
216 audio->rtcp.stat.tx.jitter.last / 1000.0,
217 ""
218 );
219
220
221 printf(" RTT delay : %7.3f %7.3f %7.3f %7.3f%s\n",
222 audio->rtcp.stat.rtt.min / 1000.0,
223 audio->rtcp.stat.rtt.avg / 1000.0,
224 audio->rtcp.stat.rtt.max / 1000.0,
225 audio->rtcp.stat.rtt.last / 1000.0,
226 ""
227 );
228
229}
230