blob: 70f1bc9259f5de705bc959b6b5c3f79c8b7bcc8d [file] [log] [blame]
Benny Prijonoe93e2872006-06-28 16:46:49 +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#include "test.h"
21#include <pjsip.h>
22#include <pjlib.h>
23
24#define THIS_FILE "transport_tcp_test.c"
25
26
27/*
28 * TCP transport test.
29 */
30int transport_tcp_test(void)
31{
32 enum { SEND_RECV_LOOP = 8 };
33 pjsip_tpfactory *tpfactory;
34 pjsip_transport *tcp;
35 pj_sockaddr_in rem_addr;
36 pj_status_t status;
37 char url[64];
38 unsigned rtt[SEND_RECV_LOOP], min_rtt;
39 int i, pkt_lost;
40
41 /* Start TCP listener on arbitrary port. */
42 status = pjsip_tcp_transport_start(endpt, NULL, 1, &tpfactory);
43 if (status != PJ_SUCCESS) {
44 app_perror(" Error: unable to start TCP transport", status);
45 return -10;
46 }
47
48
49 /* Get the listener address */
50 status = pj_sockaddr_in_init(&rem_addr, &tpfactory->addr_name.host,
51 (pj_uint16_t)tpfactory->addr_name.port);
52 if (status != PJ_SUCCESS) {
53 app_perror(" Error: possibly invalid TCP address name", status);
54 return -14;
55 }
56
57 pj_ansi_sprintf(url, "sip:alice@%s:%d;transport=tcp",
58 pj_inet_ntoa(rem_addr.sin_addr),
59 pj_ntohs(rem_addr.sin_port));
60
61
62 /* Acquire one TCP transport. */
63 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP,
64 &rem_addr, sizeof(rem_addr),
65 &tcp);
66 if (status != PJ_SUCCESS || tcp == NULL) {
67 app_perror(" Error: unable to acquire TCP transport", status);
68 return -17;
69 }
70
71 /* After pjsip_endpt_acquire_transport, TCP transport must have
72 * reference counter 1.
73 */
74 if (pj_atomic_get(tcp->ref_cnt) != 1)
75 return -20;
76
77 /* Test basic transport attributes */
78 status = generic_transport_test(tcp);
79 if (status != PJ_SUCCESS)
80 return status;
81
82
83 /* Check again that reference counter is 1. */
84 if (pj_atomic_get(tcp->ref_cnt) != 1)
85 return -70;
86
87 /* Basic transport's send/receive loopback test. */
88 for (i=0; i<SEND_RECV_LOOP; ++i) {
89 status = transport_send_recv_test(PJSIP_TRANSPORT_TCP, tcp, url, &rtt[i]);
90
91 if (status != 0) {
92 pjsip_transport_dec_ref(tcp);
93 flush_events(500);
94 return -72;
95 }
96 }
97
98 min_rtt = 0xFFFFFFF;
99 for (i=0; i<SEND_RECV_LOOP; ++i)
100 if (rtt[i] < min_rtt) min_rtt = rtt[i];
101
102 report_ival("tcp-rtt-usec", min_rtt, "usec",
103 "Best TCP transport round trip time, in microseconds "
104 "(time from sending request until response is received. "
105 "Tests were performed on local machine only, and after "
106 "TCP socket has been established by previous test)");
107
108
109 /* Multi-threaded round-trip test. */
110 status = transport_rt_test(PJSIP_TRANSPORT_TCP, tcp, url, &pkt_lost);
111 if (status != 0) {
112 pjsip_transport_dec_ref(tcp);
113 return status;
114 }
115
116 if (pkt_lost != 0)
117 PJ_LOG(3,(THIS_FILE, " note: %d packet(s) was lost", pkt_lost));
118
119 /* Check again that reference counter is still 1. */
120 if (pj_atomic_get(tcp->ref_cnt) != 1)
121 return -80;
122
123 /* Destroy this transport. */
124 pjsip_transport_dec_ref(tcp);
125
126 /* Force destroy this transport. */
127 status = pjsip_transport_destroy(tcp);
128 if (status != PJ_SUCCESS)
129 return -90;
130
131 /* Unregister factory */
132 status = pjsip_tpmgr_unregister_tpfactory(pjsip_endpt_get_tpmgr(endpt),
133 tpfactory);
134 if (status != PJ_SUCCESS)
135 return -95;
136
137 /* Flush events. */
138 PJ_LOG(3,(THIS_FILE, " Flushing events, 1 second..."));
139 flush_events(1000);
140
141 /* Done */
142 return 0;
143}