blob: 813e4e50e96eafa2747ea759a58d5847b5d6db16 [file] [log] [blame]
Benny Prijonodbe337a2006-01-08 23:57:52 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
Benny Prijono32177c02008-06-20 22:44:47 +00004 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijonodbe337a2006-01-08 23:57:52 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "test.h"
Benny Prijono40f2f642006-01-30 18:40:05 +000022#include <pjsip.h>
Benny Prijonodbe337a2006-01-08 23:57:52 +000023#include <pjlib.h>
24
25#define THIS_FILE "tsx_uas_test.c"
26
27
28/*****************************************************************************
29 **
30 ** UAS tests.
31 **
32 ** This file performs various tests for UAC transactions. Each test will have
33 ** a different Via branch param so that message receiver module and
34 ** transaction user module can identify which test is being carried out.
35 **
36 ** TEST1_BRANCH_ID
37 ** Test that non-INVITE transaction returns 2xx response to the correct
38 ** transport and correctly terminates the transaction.
Benny Prijonoe93e2872006-06-28 16:46:49 +000039 ** This also checks that transaction is destroyed immediately after
40 ** it sends final response when reliable transport is used.
Benny Prijonodbe337a2006-01-08 23:57:52 +000041 **
42 ** TEST2_BRANCH_ID
43 ** As above, for non-2xx final response.
44 **
45 ** TEST3_BRANCH_ID
46 ** Transaction correctly progressing to PROCEEDING state when provisional
47 ** response is sent.
48 **
49 ** TEST4_BRANCH_ID
50 ** Transaction retransmits last response (if any) without notifying
Benny Prijono0c2bc612006-01-10 13:31:40 +000051 ** transaction user upon receiving request retransmissions on TRYING
52 ** state
Benny Prijonodbe337a2006-01-08 23:57:52 +000053 **
54 ** TEST5_BRANCH_ID
Benny Prijono0c2bc612006-01-10 13:31:40 +000055 ** As above, in PROCEEDING state.
Benny Prijonodbe337a2006-01-08 23:57:52 +000056 **
57 ** TEST6_BRANCH_ID
Benny Prijono0c2bc612006-01-10 13:31:40 +000058 ** As above, in COMPLETED state, with first sending provisional response.
Benny Prijonoe93e2872006-06-28 16:46:49 +000059 ** (Only applicable for non-reliable transports).
Benny Prijonodbe337a2006-01-08 23:57:52 +000060 **
61 ** TEST7_BRANCH_ID
Benny Prijono0c2bc612006-01-10 13:31:40 +000062 ** INVITE transaction MUST retransmit non-2xx final response.
Benny Prijonodbe337a2006-01-08 23:57:52 +000063 **
64 ** TEST8_BRANCH_ID
Benny Prijono0c2bc612006-01-10 13:31:40 +000065 ** As above, for INVITE's 2xx final response (this is PJSIP specific).
66 **
67 ** TEST9_BRANCH_ID
68 ** INVITE transaction MUST cease retransmission of final response when
69 ** ACK is received. (Note: PJSIP also retransmit 2xx final response
70 ** until it's terminated by user).
71 ** Transaction also MUST terminate in T4 seconds.
Benny Prijonoe93e2872006-06-28 16:46:49 +000072 ** (Only applicable for non-reliable transports).
Benny Prijono0c2bc612006-01-10 13:31:40 +000073 **
Benny Prijono0c2bc612006-01-10 13:31:40 +000074 ** TEST11_BRANCH_ID
Benny Prijono728a9052006-01-18 23:34:15 +000075 ** Test scenario where transport fails before response is sent (i.e.
76 ** in TRYING state).
77 **
78 ** TEST12_BRANCH_ID
79 ** As above, after provisional response is sent but before final
80 ** response is sent (i.e. in PROCEEDING state).
81 **
82 ** TEST13_BRANCH_ID
83 ** As above, for INVITE, after final response has been sent but before
84 ** ACK is received (i.e. in CONNECTED state).
85 **
86 ** TEST14_BRANCH_ID
Benny Prijonodbe337a2006-01-08 23:57:52 +000087 ** When UAS failed to deliver the response with the selected transport,
88 ** it should try contacting the client with other transport or begin
89 ** RFC 3263 server resolution procedure.
90 ** This should be tested on:
91 ** a. TRYING state (when delivering first response).
92 ** b. PROCEEDING state (when failed to retransmit last response
93 ** upon receiving request retransmission).
94 ** c. COMPLETED state.
95 **
Benny Prijonodbe337a2006-01-08 23:57:52 +000096 **/
97
98static char *TEST1_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test1";
99static char *TEST2_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test2";
100static char *TEST3_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test3";
101static char *TEST4_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test4";
102static char *TEST5_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test5";
103static char *TEST6_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test6";
104static char *TEST7_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test7";
Benny Prijono0c2bc612006-01-10 13:31:40 +0000105static char *TEST8_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test8";
106static char *TEST9_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test9";
107static char *TEST10_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test10";
108static char *TEST11_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test11";
109static char *TEST12_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test12";
Benny Prijonobc331ca2006-09-19 13:32:05 +0000110//static char *TEST13_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test13";
Benny Prijonodbe337a2006-01-08 23:57:52 +0000111
112#define TEST1_STATUS_CODE 200
113#define TEST2_STATUS_CODE 301
114#define TEST3_PROVISIONAL_CODE PJSIP_SC_QUEUED
115#define TEST3_STATUS_CODE 202
Benny Prijono0c2bc612006-01-10 13:31:40 +0000116#define TEST4_STATUS_CODE 200
117#define TEST4_REQUEST_COUNT 2
118#define TEST5_PROVISIONAL_CODE 100
119#define TEST5_STATUS_CODE 200
120#define TEST5_REQUEST_COUNT 2
121#define TEST5_RESPONSE_COUNT 2
122#define TEST6_PROVISIONAL_CODE 100
123#define TEST6_STATUS_CODE 200 /* Must be final */
124#define TEST6_REQUEST_COUNT 2
125#define TEST6_RESPONSE_COUNT 3
126#define TEST7_STATUS_CODE 301
127#define TEST8_STATUS_CODE 302
Benny Prijono728a9052006-01-18 23:34:15 +0000128#define TEST9_STATUS_CODE 301
Benny Prijonodbe337a2006-01-08 23:57:52 +0000129
130
Benny Prijono0c2bc612006-01-10 13:31:40 +0000131#define TEST4_TITLE "test4: absorbing request retransmission"
132#define TEST5_TITLE "test5: retransmit last response in PROCEEDING state"
133#define TEST6_TITLE "test6: retransmit last response in COMPLETED state"
134
135
Benny Prijonoe93e2872006-06-28 16:46:49 +0000136static char TARGET_URI[128];
137static char FROM_URI[128];
138static struct tsx_test_param *test_param;
139static unsigned tp_flag;
140
141
Benny Prijono0c2bc612006-01-10 13:31:40 +0000142#define TEST_TIMEOUT_ERROR -30
143#define MAX_ALLOWED_DIFF 150
144
Benny Prijonodbe337a2006-01-08 23:57:52 +0000145static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e);
146static pj_bool_t on_rx_message(pjsip_rx_data *rdata);
147
148/* UAC transaction user module. */
149static pjsip_module tsx_user =
150{
151 NULL, NULL, /* prev and next */
152 { "Tsx-UAS-User", 12}, /* Name. */
153 -1, /* Id */
154 PJSIP_MOD_PRIORITY_APPLICATION-1, /* Priority */
Benny Prijonodbe337a2006-01-08 23:57:52 +0000155 NULL, /* load() */
156 NULL, /* start() */
157 NULL, /* stop() */
158 NULL, /* unload() */
159 NULL, /* on_rx_request() */
160 NULL, /* on_rx_response() */
161 NULL, /* on_tx_request() */
162 NULL, /* on_tx_response() */
163 &tsx_user_on_tsx_state, /* on_tsx_state() */
164};
165
166/* Module to send request. */
167static pjsip_module msg_sender =
168{
169 NULL, NULL, /* prev and next */
170 { "Msg-Sender", 10}, /* Name. */
171 -1, /* Id */
172 PJSIP_MOD_PRIORITY_APPLICATION-1, /* Priority */
Benny Prijonodbe337a2006-01-08 23:57:52 +0000173 NULL, /* load() */
174 NULL, /* start() */
175 NULL, /* stop() */
176 NULL, /* unload() */
177 &on_rx_message, /* on_rx_request() */
178 &on_rx_message, /* on_rx_response() */
179 NULL, /* on_tx_request() */
180 NULL, /* on_tx_response() */
181 NULL, /* on_tsx_state() */
182};
183
184/* Static vars, which will be reset on each test. */
185static int recv_count;
186static pj_time_val recv_last;
187static pj_bool_t test_complete;
188
189/* Loop transport instance. */
190static pjsip_transport *loop;
191
192/* UAS transaction key. */
193static char key_buf[64];
194static pj_str_t tsx_key = { key_buf, 0 };
195
196
197/* General timer entry to be used by tests. */
Benny Prijonobc331ca2006-09-19 13:32:05 +0000198//static pj_timer_entry timer;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000199
200/* Timer to send response via transaction. */
201struct response
202{
203 pj_str_t tsx_key;
204 pjsip_tx_data *tdata;
205};
206
Benny Prijono0c2bc612006-01-10 13:31:40 +0000207/* Timer callback to send response. */
Benny Prijonodbe337a2006-01-08 23:57:52 +0000208static void send_response_timer( pj_timer_heap_t *timer_heap,
209 struct pj_timer_entry *entry)
210{
211 pjsip_transaction *tsx;
Benny Prijonoa1e69682007-05-11 15:14:34 +0000212 struct response *r = (struct response*) entry->user_data;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000213 pj_status_t status;
214
215 tsx = pjsip_tsx_layer_find_tsx(&r->tsx_key, PJ_TRUE);
216 if (!tsx) {
217 PJ_LOG(3,(THIS_FILE," error: timer unable to find transaction"));
218 pjsip_tx_data_dec_ref(r->tdata);
219 return;
220 }
221
222 status = pjsip_tsx_send_msg(tsx, r->tdata);
223 if (status != PJ_SUCCESS) {
Benny Prijono728a9052006-01-18 23:34:15 +0000224 // Some tests do expect failure!
225 //PJ_LOG(3,(THIS_FILE," error: timer unable to send response"));
226 pj_mutex_unlock(tsx->mutex);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000227 pjsip_tx_data_dec_ref(r->tdata);
228 return;
229 }
Benny Prijono728a9052006-01-18 23:34:15 +0000230
231 pj_mutex_unlock(tsx->mutex);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000232}
233
Benny Prijono0c2bc612006-01-10 13:31:40 +0000234/* Utility to send response. */
235static void send_response( pjsip_rx_data *rdata,
236 pjsip_transaction *tsx,
237 int status_code )
238{
239 pj_status_t status;
240 pjsip_tx_data *tdata;
241
242 status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL,
243 &tdata);
244 if (status != PJ_SUCCESS) {
245 app_perror(" error: unable to create response", status);
246 test_complete = -196;
247 return;
248 }
249
250 status = pjsip_tsx_send_msg(tsx, tdata);
251 if (status != PJ_SUCCESS) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000252 pjsip_tx_data_dec_ref(tdata);
Benny Prijono728a9052006-01-18 23:34:15 +0000253 // Some tests do expect failure!
254 //app_perror(" error: unable to send response", status);
255 //test_complete = -197;
Benny Prijono0c2bc612006-01-10 13:31:40 +0000256 return;
257 }
258}
259
Benny Prijonodbe337a2006-01-08 23:57:52 +0000260/* Schedule timer to send response for the specified UAS transaction */
261static void schedule_send_response( pjsip_rx_data *rdata,
262 const pj_str_t *tsx_key,
263 int status_code,
264 int msec_delay )
265{
266 pj_status_t status;
267 pjsip_tx_data *tdata;
Benny Prijono728a9052006-01-18 23:34:15 +0000268 pj_timer_entry *t;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000269 struct response *r;
270 pj_time_val delay;
271
272 status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL,
273 &tdata);
274 if (status != PJ_SUCCESS) {
275 app_perror(" error: unable to create response", status);
276 test_complete = -198;
277 return;
278 }
279
Benny Prijonoa1e69682007-05-11 15:14:34 +0000280 r = PJ_POOL_ALLOC_T(tdata->pool, struct response);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000281 pj_strdup(tdata->pool, &r->tsx_key, tsx_key);
282 r->tdata = tdata;
283
284 delay.sec = 0;
285 delay.msec = msec_delay;
286 pj_time_val_normalize(&delay);
287
Benny Prijonoa1e69682007-05-11 15:14:34 +0000288 t = PJ_POOL_ZALLOC_T(tdata->pool, pj_timer_entry);
Benny Prijono728a9052006-01-18 23:34:15 +0000289 t->user_data = r;
290 t->cb = &send_response_timer;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000291
Benny Prijono728a9052006-01-18 23:34:15 +0000292 status = pjsip_endpt_schedule_timer(endpt, t, &delay);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000293 if (status != PJ_SUCCESS) {
Benny Prijono728a9052006-01-18 23:34:15 +0000294 pjsip_tx_data_dec_ref(tdata);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000295 app_perror(" error: unable to schedule timer", status);
296 test_complete = -199;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000297 return;
298 }
299}
300
Benny Prijono0c2bc612006-01-10 13:31:40 +0000301
302/* Find and terminate tsx with the specified key. */
303static void terminate_our_tsx(int status_code)
304{
305 pjsip_transaction *tsx;
306
307 tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
308 if (!tsx) {
309 PJ_LOG(3,(THIS_FILE," error: timer unable to find transaction"));
310 return;
311 }
312
313 pjsip_tsx_terminate(tsx, status_code);
314 pj_mutex_unlock(tsx->mutex);
315}
316
Benny Prijonobc331ca2006-09-19 13:32:05 +0000317#if 0 /* Unused for now */
Benny Prijono0c2bc612006-01-10 13:31:40 +0000318/* Timer callback to terminate transaction. */
319static void terminate_tsx_timer( pj_timer_heap_t *timer_heap,
320 struct pj_timer_entry *entry)
321{
322 terminate_our_tsx(entry->id);
323}
324
325
326/* Schedule timer to terminate transaction. */
327static void schedule_terminate_tsx( pjsip_transaction *tsx,
328 int status_code,
329 int msec_delay )
330{
331 pj_time_val delay;
332
333 delay.sec = 0;
334 delay.msec = msec_delay;
335 pj_time_val_normalize(&delay);
336
337 pj_assert(pj_strcmp(&tsx->transaction_key, &tsx_key)==0);
338 timer.user_data = NULL;
339 timer.id = status_code;
340 timer.cb = &terminate_tsx_timer;
341 pjsip_endpt_schedule_timer(endpt, &timer, &delay);
342}
Benny Prijonobc331ca2006-09-19 13:32:05 +0000343#endif
Benny Prijono0c2bc612006-01-10 13:31:40 +0000344
345
Benny Prijonodbe337a2006-01-08 23:57:52 +0000346/*
347 * This is the handler to receive state changed notification from the
348 * transaction. It is used to verify that the transaction behaves according
349 * to the test scenario.
350 */
351static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
352{
353 if (pj_strcmp2(&tsx->branch, TEST1_BRANCH_ID)==0 ||
354 pj_strcmp2(&tsx->branch, TEST2_BRANCH_ID)==0)
355 {
356 /*
357 * TEST1_BRANCH_ID tests that non-INVITE transaction transmits final
358 * response using correct transport and terminates transaction after
359 * T4 (PJSIP_T4_TIMEOUT, 5 seconds).
360 *
361 * TEST2_BRANCH_ID does similar test for non-2xx final response.
362 */
363 int status_code = (pj_strcmp2(&tsx->branch, TEST1_BRANCH_ID)==0) ?
364 TEST1_STATUS_CODE : TEST2_STATUS_CODE;
365
366 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
367
368 test_complete = 1;
369
370 /* Check that status code is status_code. */
371 if (tsx->status_code != status_code) {
372 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
373 test_complete = -100;
374 }
375
376 /* Previous state must be completed. */
377 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
378 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
379 test_complete = -101;
380 }
381
382 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
383
384 /* Previous state must be TRYING. */
385 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
386 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
387 test_complete = -102;
388 }
389 }
390
391 }
392 else
393 if (pj_strcmp2(&tsx->branch, TEST3_BRANCH_ID)==0) {
394 /*
395 * TEST3_BRANCH_ID tests sending provisional response.
396 */
397 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
398
399 test_complete = 1;
400
401 /* Check that status code is status_code. */
402 if (tsx->status_code != TEST3_STATUS_CODE) {
403 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
404 test_complete = -110;
405 }
406
407 /* Previous state must be completed. */
408 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
409 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
410 test_complete = -111;
411 }
412
413 } else if (tsx->state == PJSIP_TSX_STATE_PROCEEDING) {
414
415 /* Previous state must be TRYING. */
416 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
417 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
418 test_complete = -112;
419 }
420
421 /* Check that status code is status_code. */
422 if (tsx->status_code != TEST3_PROVISIONAL_CODE) {
423 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
424 test_complete = -113;
425 }
426
427 /* Check that event must be TX_MSG */
428 if (e->body.tsx_state.type != PJSIP_EVENT_TX_MSG) {
429 PJ_LOG(3,(THIS_FILE, " error: incorrect event"));
430 test_complete = -114;
431 }
432
433 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
434
435 /* Previous state must be PROCEEDING. */
436 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) {
437 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
438 test_complete = -115;
439 }
440
441 /* Check that status code is status_code. */
442 if (tsx->status_code != TEST3_STATUS_CODE) {
443 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
444 test_complete = -116;
445 }
446
447 /* Check that event must be TX_MSG */
448 if (e->body.tsx_state.type != PJSIP_EVENT_TX_MSG) {
449 PJ_LOG(3,(THIS_FILE, " error: incorrect event"));
450 test_complete = -117;
451 }
452
453 }
454
Benny Prijono0c2bc612006-01-10 13:31:40 +0000455 } else
456 if (pj_strcmp2(&tsx->branch, TEST4_BRANCH_ID)==0) {
457 /*
458 * TEST4_BRANCH_ID tests receiving retransmissions in TRYING state.
459 */
Benny Prijono02b8fd82006-06-26 15:12:55 +0000460 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
461 /* Request is received. */
462 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000463
464 /* Check that status code is status_code. */
465 if (tsx->status_code != TEST4_STATUS_CODE) {
Benny Prijono02b8fd82006-06-26 15:12:55 +0000466 PJ_LOG(3,(THIS_FILE,
467 " error: incorrect status code %d "
468 "(expecting %d)", tsx->status_code,
469 TEST4_STATUS_CODE));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000470 test_complete = -120;
471 }
472
473 /* Previous state. */
474 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
475 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
476 test_complete = -121;
477 }
478
479 } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED)
480 {
Benny Prijono02b8fd82006-06-26 15:12:55 +0000481 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (122)",
482 pjsip_tsx_state_str(tsx->state)));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000483 test_complete = -122;
484
485 }
486
487
488 } else
489 if (pj_strcmp2(&tsx->branch, TEST5_BRANCH_ID)==0) {
490 /*
491 * TEST5_BRANCH_ID tests receiving retransmissions in PROCEEDING state
492 */
Benny Prijono02b8fd82006-06-26 15:12:55 +0000493 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
494 /* Request is received. */
495
496 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000497
498 /* Check that status code is status_code. */
499 if (tsx->status_code != TEST5_STATUS_CODE) {
500 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
501 test_complete = -130;
502 }
503
504 /* Previous state. */
505 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) {
506 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
507 test_complete = -131;
508 }
509
510 } else if (tsx->state == PJSIP_TSX_STATE_PROCEEDING) {
511
512 /* Check status code. */
513 if (tsx->status_code != TEST5_PROVISIONAL_CODE) {
514 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
515 test_complete = -132;
516 }
517
518 } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED) {
Benny Prijono02b8fd82006-06-26 15:12:55 +0000519 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (133)",
520 pjsip_tsx_state_str(tsx->state)));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000521 test_complete = -133;
522
523 }
524
525 } else
526 if (pj_strcmp2(&tsx->branch, TEST6_BRANCH_ID)==0) {
527 /*
528 * TEST6_BRANCH_ID tests receiving retransmissions in COMPLETED state
529 */
Benny Prijono02b8fd82006-06-26 15:12:55 +0000530 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
531 /* Request is received. */
532
533 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000534
535 /* Check that status code is status_code. */
536 if (tsx->status_code != TEST6_STATUS_CODE) {
Benny Prijonoe93e2872006-06-28 16:46:49 +0000537 PJ_LOG(3,(THIS_FILE, " error: incorrect status code %d "
538 "(expecting %d)", tsx->status_code,
539 TEST6_STATUS_CODE));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000540 test_complete = -140;
541 }
542
543 /* Previous state. */
544 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
545 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
546 test_complete = -141;
547 }
548
549 } else if (tsx->state != PJSIP_TSX_STATE_PROCEEDING &&
550 tsx->state != PJSIP_TSX_STATE_COMPLETED &&
551 tsx->state != PJSIP_TSX_STATE_DESTROYED)
552 {
Benny Prijono02b8fd82006-06-26 15:12:55 +0000553 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (142)",
554 pjsip_tsx_state_str(tsx->state)));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000555 test_complete = -142;
556
557 }
558
559
560 } else
561 if (pj_strcmp2(&tsx->branch, TEST7_BRANCH_ID)==0 ||
562 pj_strcmp2(&tsx->branch, TEST8_BRANCH_ID)==0)
563 {
564 /*
565 * TEST7_BRANCH_ID and TEST8_BRANCH_ID test retransmission of
566 * INVITE final response
567 */
568 int code;
569
570 if (pj_strcmp2(&tsx->branch, TEST7_BRANCH_ID) == 0)
571 code = TEST7_STATUS_CODE;
572 else
573 code = TEST8_STATUS_CODE;
574
Benny Prijono02b8fd82006-06-26 15:12:55 +0000575 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
576 /* Request is received. */
577
578 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000579
580 if (test_complete == 0)
581 test_complete = 1;
582
583 /* Check status code. */
584 if (tsx->status_code != PJSIP_SC_TSX_TIMEOUT) {
585 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
586 test_complete = -150;
587 }
588
589 /* Previous state. */
590 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
591 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
592 test_complete = -151;
593 }
594
Benny Prijonoe93e2872006-06-28 16:46:49 +0000595 /* Check the number of retransmissions */
596 if (tp_flag & PJSIP_TRANSPORT_RELIABLE) {
597
598 if (tsx->retransmit_count != 0) {
599 PJ_LOG(3,(THIS_FILE, " error: should not retransmit"));
600 test_complete = -1510;
601 }
602
603 } else {
604
605 if (tsx->retransmit_count != 10) {
606 PJ_LOG(3,(THIS_FILE,
607 " error: incorrect retransmit count %d "
608 "(expecting 10)",
609 tsx->retransmit_count));
610 test_complete = -1510;
611 }
612
613 }
614
Benny Prijono0c2bc612006-01-10 13:31:40 +0000615 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
616
617 /* Check that status code is status_code. */
618 if (tsx->status_code != code) {
619 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
620 test_complete = -152;
621 }
622
623 /* Previous state. */
624 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
625 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
626 test_complete = -153;
627 }
628
629 } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED) {
630
Benny Prijono02b8fd82006-06-26 15:12:55 +0000631 PJ_LOG(3,(THIS_FILE, " error: unexpected state (154)"));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000632 test_complete = -154;
633
634 }
635
Benny Prijono728a9052006-01-18 23:34:15 +0000636
637 } else
638 if (pj_strcmp2(&tsx->branch, TEST9_BRANCH_ID)==0) {
639 /*
640 * TEST9_BRANCH_ID tests that retransmission of INVITE final response
641 * must cease when ACK is received.
642 */
643
Benny Prijono02b8fd82006-06-26 15:12:55 +0000644 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
645 /* Request is received. */
646
647 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono728a9052006-01-18 23:34:15 +0000648
649 if (test_complete == 0)
650 test_complete = 1;
651
652 /* Check status code. */
653 if (tsx->status_code != TEST9_STATUS_CODE) {
654 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
655 test_complete = -160;
656 }
657
658 /* Previous state. */
659 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_CONFIRMED) {
660 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
661 test_complete = -161;
662 }
663
664 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
665
666 /* Check that status code is status_code. */
667 if (tsx->status_code != TEST9_STATUS_CODE) {
668 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
669 test_complete = -162;
670 }
671
672 /* Previous state. */
673 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
674 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
675 test_complete = -163;
676 }
677
678
679 } else if (tsx->state == PJSIP_TSX_STATE_CONFIRMED) {
680
681 /* Check that status code is status_code. */
682 if (tsx->status_code != TEST9_STATUS_CODE) {
683 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
684 test_complete = -164;
685 }
686
687 /* Previous state. */
688 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
689 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
690 test_complete = -165;
691 }
692
693 } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED) {
694
Benny Prijono02b8fd82006-06-26 15:12:55 +0000695 PJ_LOG(3,(THIS_FILE, " error: unexpected state (166)"));
Benny Prijono728a9052006-01-18 23:34:15 +0000696 test_complete = -166;
697
698 }
699
700
701 } else
702 if (pj_strcmp2(&tsx->branch, TEST10_BRANCH_ID)==0 ||
703 pj_strcmp2(&tsx->branch, TEST11_BRANCH_ID)==0 ||
704 pj_strcmp2(&tsx->branch, TEST12_BRANCH_ID)==0)
705 {
706 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
707
708 if (!test_complete)
709 test_complete = 1;
710
711 if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) {
712 PJ_LOG(3,(THIS_FILE," error: incorrect status code"));
713 test_complete = -170;
714 }
715 }
Benny Prijonodbe337a2006-01-08 23:57:52 +0000716 }
717
718}
719
720/* Save transaction key to global variables. */
721static void save_key(pjsip_transaction *tsx)
722{
723 pj_str_t key;
724
725 pj_strdup(tsx->pool, &key, &tsx->transaction_key);
726 pj_strcpy(&tsx_key, &key);
727}
728
Benny Prijono0c2bc612006-01-10 13:31:40 +0000729#define DIFF(a,b) ((a<b) ? (b-a) : (a-b))
730
Benny Prijonodbe337a2006-01-08 23:57:52 +0000731/*
732 * Message receiver handler.
733 */
734static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
735{
736 pjsip_msg *msg = rdata->msg_info.msg;
737 pj_str_t branch_param = rdata->msg_info.via->branch_param;
738 pj_status_t status;
739
740 if (pj_strcmp2(&branch_param, TEST1_BRANCH_ID) == 0 ||
741 pj_strcmp2(&branch_param, TEST2_BRANCH_ID) == 0)
742 {
743 /*
744 * TEST1_BRANCH_ID tests that non-INVITE transaction transmits 2xx
745 * final response using correct transport and terminates transaction
746 * after 32 seconds.
747 *
748 * TEST2_BRANCH_ID performs similar test for non-2xx final response.
749 */
750 int status_code = (pj_strcmp2(&branch_param, TEST1_BRANCH_ID) == 0) ?
751 TEST1_STATUS_CODE : TEST2_STATUS_CODE;
752
753 if (msg->type == PJSIP_REQUEST_MSG) {
Benny Prijono728a9052006-01-18 23:34:15 +0000754 /* On received request, create UAS and respond with final
Benny Prijonodbe337a2006-01-08 23:57:52 +0000755 * response.
756 */
757 pjsip_transaction *tsx;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000758
759 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
760 if (status != PJ_SUCCESS) {
761 app_perror(" error: unable to create transaction", status);
762 test_complete = -110;
763 return PJ_TRUE;
764 }
Benny Prijono38998232006-02-08 22:44:25 +0000765 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000766
767 save_key(tsx);
Benny Prijono0c2bc612006-01-10 13:31:40 +0000768 send_response(rdata, tsx, status_code);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000769
770 } else {
771 /* Verify the response received. */
772
773 ++recv_count;
774
775 /* Verify status code. */
776 if (msg->line.status.code != status_code) {
777 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
778 test_complete = -113;
779 }
780
781 /* Verify that no retransmissions is received. */
782 if (recv_count > 1) {
783 PJ_LOG(3,(THIS_FILE, " error: retransmission received"));
784 test_complete = -114;
785 }
786
787 }
788 return PJ_TRUE;
789
790 } else if (pj_strcmp2(&branch_param, TEST3_BRANCH_ID) == 0) {
791
792 /* TEST3_BRANCH_ID tests provisional response. */
793
794 if (msg->type == PJSIP_REQUEST_MSG) {
Benny Prijono728a9052006-01-18 23:34:15 +0000795 /* On received request, create UAS and respond with provisional
Benny Prijonodbe337a2006-01-08 23:57:52 +0000796 * response, then schedule timer to send final response.
797 */
798 pjsip_transaction *tsx;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000799
800 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
801 if (status != PJ_SUCCESS) {
802 app_perror(" error: unable to create transaction", status);
Benny Prijono02b8fd82006-06-26 15:12:55 +0000803 test_complete = -116;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000804 return PJ_TRUE;
805 }
Benny Prijono38998232006-02-08 22:44:25 +0000806 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000807
808 save_key(tsx);
809
Benny Prijono0c2bc612006-01-10 13:31:40 +0000810 send_response(rdata, tsx, TEST3_PROVISIONAL_CODE);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000811 schedule_send_response(rdata, &tsx->transaction_key,
812 TEST3_STATUS_CODE, 2000);
813
814 } else {
815 /* Verify the response received. */
816
817 ++recv_count;
818
819 if (recv_count == 1) {
820 /* Verify status code. */
821 if (msg->line.status.code != TEST3_PROVISIONAL_CODE) {
822 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
823 test_complete = -123;
824 }
825 } else if (recv_count == 2) {
826 /* Verify status code. */
827 if (msg->line.status.code != TEST3_STATUS_CODE) {
828 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
829 test_complete = -124;
830 }
831 } else {
832 PJ_LOG(3,(THIS_FILE, " error: retransmission received"));
833 test_complete = -125;
834 }
835
836 }
837 return PJ_TRUE;
838
Benny Prijono0c2bc612006-01-10 13:31:40 +0000839 } else if (pj_strcmp2(&branch_param, TEST4_BRANCH_ID) == 0 ||
840 pj_strcmp2(&branch_param, TEST5_BRANCH_ID) == 0 ||
841 pj_strcmp2(&branch_param, TEST6_BRANCH_ID) == 0)
842 {
843
844 /* TEST4_BRANCH_ID: absorbs retransmissions in TRYING state. */
845 /* TEST5_BRANCH_ID: retransmit last response in PROCEEDING state. */
846 /* TEST6_BRANCH_ID: retransmit last response in COMPLETED state. */
847
848 if (msg->type == PJSIP_REQUEST_MSG) {
Benny Prijono728a9052006-01-18 23:34:15 +0000849 /* On received request, create UAS. */
Benny Prijono0c2bc612006-01-10 13:31:40 +0000850 pjsip_transaction *tsx;
851
Benny Prijonoe93e2872006-06-28 16:46:49 +0000852 PJ_LOG(4,(THIS_FILE, " received request (probably retransmission)"));
853
Benny Prijono0c2bc612006-01-10 13:31:40 +0000854 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
855 if (status != PJ_SUCCESS) {
856 app_perror(" error: unable to create transaction", status);
857 test_complete = -130;
858 return PJ_TRUE;
859 }
860
Benny Prijono38998232006-02-08 22:44:25 +0000861 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijono0c2bc612006-01-10 13:31:40 +0000862 save_key(tsx);
863
864 if (pj_strcmp2(&branch_param, TEST4_BRANCH_ID) == 0) {
865
866 } else if (pj_strcmp2(&branch_param, TEST5_BRANCH_ID) == 0) {
867 send_response(rdata, tsx, TEST5_PROVISIONAL_CODE);
868
869 } else if (pj_strcmp2(&branch_param, TEST6_BRANCH_ID) == 0) {
Benny Prijonoe93e2872006-06-28 16:46:49 +0000870 PJ_LOG(4,(THIS_FILE, " sending provisional response"));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000871 send_response(rdata, tsx, TEST6_PROVISIONAL_CODE);
Benny Prijonoe93e2872006-06-28 16:46:49 +0000872 PJ_LOG(4,(THIS_FILE, " sending final response"));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000873 send_response(rdata, tsx, TEST6_STATUS_CODE);
874 }
875
876 } else {
877 /* Verify the response received. */
878
Benny Prijonoe93e2872006-06-28 16:46:49 +0000879 PJ_LOG(4,(THIS_FILE, " received response number %d", recv_count));
880
Benny Prijono0c2bc612006-01-10 13:31:40 +0000881 ++recv_count;
882
883 if (pj_strcmp2(&branch_param, TEST4_BRANCH_ID) == 0) {
884 PJ_LOG(3,(THIS_FILE, " error: not expecting response!"));
885 test_complete = -132;
886
887 } else if (pj_strcmp2(&branch_param, TEST5_BRANCH_ID) == 0) {
888
889 if (rdata->msg_info.msg->line.status.code!=TEST5_PROVISIONAL_CODE) {
890 PJ_LOG(3,(THIS_FILE, " error: incorrect status code!"));
891 test_complete = -133;
892
893 }
894 if (recv_count > TEST5_RESPONSE_COUNT) {
895 PJ_LOG(3,(THIS_FILE, " error: not expecting response!"));
896 test_complete = -134;
897 }
898
899 } else if (pj_strcmp2(&branch_param, TEST6_BRANCH_ID) == 0) {
900
901 int code = rdata->msg_info.msg->line.status.code;
902
903 switch (recv_count) {
904 case 1:
905 if (code != TEST6_PROVISIONAL_CODE) {
906 PJ_LOG(3,(THIS_FILE, " error: invalid code!"));
907 test_complete = -135;
908 }
909 break;
910 case 2:
911 case 3:
912 if (code != TEST6_STATUS_CODE) {
Benny Prijonoe93e2872006-06-28 16:46:49 +0000913 PJ_LOG(3,(THIS_FILE, " error: invalid code %d "
914 "(expecting %d)", code, TEST6_STATUS_CODE));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000915 test_complete = -136;
916 }
917 break;
918 default:
919 PJ_LOG(3,(THIS_FILE, " error: not expecting response"));
920 test_complete = -137;
921 break;
922 }
923 }
924 }
925 return PJ_TRUE;
926
927
928 } else if (pj_strcmp2(&branch_param, TEST7_BRANCH_ID) == 0 ||
929 pj_strcmp2(&branch_param, TEST8_BRANCH_ID) == 0)
930 {
931
932 /*
933 * TEST7_BRANCH_ID and TEST8_BRANCH_ID test the retransmission
934 * of INVITE final response
935 */
936 if (msg->type == PJSIP_REQUEST_MSG) {
937
Benny Prijono728a9052006-01-18 23:34:15 +0000938 /* On received request, create UAS. */
Benny Prijono0c2bc612006-01-10 13:31:40 +0000939 pjsip_transaction *tsx;
940
941 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
942 if (status != PJ_SUCCESS) {
943 app_perror(" error: unable to create transaction", status);
944 test_complete = -140;
945 return PJ_TRUE;
946 }
947
Benny Prijono38998232006-02-08 22:44:25 +0000948 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijono0c2bc612006-01-10 13:31:40 +0000949 save_key(tsx);
950
951 if (pj_strcmp2(&branch_param, TEST7_BRANCH_ID) == 0) {
952
953 send_response(rdata, tsx, TEST7_STATUS_CODE);
954
955 } else {
956
957 send_response(rdata, tsx, TEST8_STATUS_CODE);
958
959 }
960
961 } else {
962 int code;
963
964 ++recv_count;
965
966 if (pj_strcmp2(&branch_param, TEST7_BRANCH_ID) == 0)
967 code = TEST7_STATUS_CODE;
968 else
969 code = TEST8_STATUS_CODE;
970
971 if (recv_count==1) {
972
973 if (rdata->msg_info.msg->line.status.code != code) {
974 PJ_LOG(3,(THIS_FILE," error: invalid status code"));
975 test_complete = -141;
976 }
977
978 recv_last = rdata->pkt_info.timestamp;
979
980 } else {
981
982 pj_time_val now;
983 unsigned msec, msec_expected;
984
985 now = rdata->pkt_info.timestamp;
986
987 PJ_TIME_VAL_SUB(now, recv_last);
988
989 msec = now.sec*1000 + now.msec;
Benny Prijono4768c3c2008-02-22 11:10:17 +0000990 msec_expected = (1 << (recv_count-2)) * pjsip_cfg()->tsx.t1;
991 if (msec_expected > pjsip_cfg()->tsx.t2)
992 msec_expected = pjsip_cfg()->tsx.t2;
Benny Prijono0c2bc612006-01-10 13:31:40 +0000993
994 if (DIFF(msec, msec_expected) > MAX_ALLOWED_DIFF) {
995 PJ_LOG(3,(THIS_FILE,
996 " error: incorrect retransmission "
997 "time (%d ms expected, %d ms received",
998 msec_expected, msec));
999 test_complete = -142;
1000 }
1001
1002 if (recv_count > 11) {
1003 PJ_LOG(3,(THIS_FILE," error: too many responses (%d)",
1004 recv_count));
1005 test_complete = -143;
1006 }
1007
1008 recv_last = rdata->pkt_info.timestamp;
1009 }
1010
1011 }
1012 return PJ_TRUE;
1013
Benny Prijono728a9052006-01-18 23:34:15 +00001014 } else if (pj_strcmp2(&branch_param, TEST9_BRANCH_ID) == 0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001015
1016 /*
1017 * TEST9_BRANCH_ID tests that the retransmission of INVITE final
1018 * response should cease when ACK is received. Transaction also MUST
1019 * terminate in T4 seconds.
1020 */
1021 if (msg->type == PJSIP_REQUEST_MSG) {
1022
Benny Prijono728a9052006-01-18 23:34:15 +00001023 /* On received request, create UAS. */
Benny Prijono0c2bc612006-01-10 13:31:40 +00001024 pjsip_transaction *tsx;
1025
1026 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
1027 if (status != PJ_SUCCESS) {
1028 app_perror(" error: unable to create transaction", status);
Benny Prijono728a9052006-01-18 23:34:15 +00001029 test_complete = -150;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001030 return PJ_TRUE;
1031 }
1032
Benny Prijono38998232006-02-08 22:44:25 +00001033 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijono0c2bc612006-01-10 13:31:40 +00001034 save_key(tsx);
Benny Prijono728a9052006-01-18 23:34:15 +00001035 send_response(rdata, tsx, TEST9_STATUS_CODE);
Benny Prijono0c2bc612006-01-10 13:31:40 +00001036
Benny Prijono0c2bc612006-01-10 13:31:40 +00001037
1038 } else {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001039
1040 ++recv_count;
1041
Benny Prijono728a9052006-01-18 23:34:15 +00001042 if (rdata->msg_info.msg->line.status.code != TEST9_STATUS_CODE) {
1043 PJ_LOG(3,(THIS_FILE," error: invalid status code"));
1044 test_complete = -151;
1045 }
Benny Prijono0c2bc612006-01-10 13:31:40 +00001046
1047 if (recv_count==1) {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001048
1049 recv_last = rdata->pkt_info.timestamp;
1050
Benny Prijono728a9052006-01-18 23:34:15 +00001051 } else if (recv_count < 5) {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001052
Benny Prijono728a9052006-01-18 23:34:15 +00001053 /* Let UAS retransmit some messages before we send ACK. */
Benny Prijono0c2bc612006-01-10 13:31:40 +00001054 pj_time_val now;
1055 unsigned msec, msec_expected;
1056
1057 now = rdata->pkt_info.timestamp;
1058
1059 PJ_TIME_VAL_SUB(now, recv_last);
1060
1061 msec = now.sec*1000 + now.msec;
Benny Prijono4768c3c2008-02-22 11:10:17 +00001062 msec_expected = (1 << (recv_count-2)) * pjsip_cfg()->tsx.t1;
1063 if (msec_expected > pjsip_cfg()->tsx.t2)
1064 msec_expected = pjsip_cfg()->tsx.t2;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001065
1066 if (DIFF(msec, msec_expected) > MAX_ALLOWED_DIFF) {
1067 PJ_LOG(3,(THIS_FILE,
1068 " error: incorrect retransmission "
1069 "time (%d ms expected, %d ms received",
1070 msec_expected, msec));
Benny Prijono728a9052006-01-18 23:34:15 +00001071 test_complete = -152;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001072 }
1073
1074 recv_last = rdata->pkt_info.timestamp;
Benny Prijono728a9052006-01-18 23:34:15 +00001075
1076 } else if (recv_count == 5) {
1077 pjsip_tx_data *tdata;
1078 pjsip_sip_uri *uri;
1079 pjsip_via_hdr *via;
1080
1081 status = pjsip_endpt_create_request_from_hdr(
1082 endpt, &pjsip_ack_method,
1083 rdata->msg_info.to->uri,
1084 rdata->msg_info.from,
1085 rdata->msg_info.to,
1086 NULL,
1087 rdata->msg_info.cid,
1088 rdata->msg_info.cseq->cseq,
1089 NULL,
1090 &tdata);
1091 if (status != PJ_SUCCESS) {
1092 app_perror(" error: unable to create ACK", status);
1093 test_complete = -153;
1094 return PJ_TRUE;
1095 }
1096
1097 uri=(pjsip_sip_uri*)pjsip_uri_get_uri(tdata->msg->line.req.uri);
1098 uri->transport_param = pj_str("loop-dgram");
1099
Benny Prijonoa1e69682007-05-11 15:14:34 +00001100 via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
Benny Prijono728a9052006-01-18 23:34:15 +00001101 via->branch_param = pj_str(TEST9_BRANCH_ID);
1102
1103 status = pjsip_endpt_send_request_stateless(endpt, tdata,
1104 NULL, NULL);
1105 if (status != PJ_SUCCESS) {
1106 app_perror(" error: unable to send ACK", status);
1107 test_complete = -154;
1108 }
1109
1110 } else {
1111 PJ_LOG(3,(THIS_FILE," error: too many responses (%d)",
1112 recv_count));
1113 test_complete = -155;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001114 }
1115
1116 }
1117 return PJ_TRUE;
Benny Prijono728a9052006-01-18 23:34:15 +00001118
1119 } else if (pj_strcmp2(&branch_param, TEST10_BRANCH_ID) == 0 ||
1120 pj_strcmp2(&branch_param, TEST11_BRANCH_ID) == 0 ||
1121 pj_strcmp2(&branch_param, TEST12_BRANCH_ID) == 0)
1122 {
1123 int test_num, code1, code2;
1124
1125 if (pj_strcmp2(&branch_param, TEST10_BRANCH_ID) == 0)
1126 test_num=10, code1 = 100, code2 = 0;
1127 else if (pj_strcmp2(&branch_param, TEST11_BRANCH_ID) == 0)
1128 test_num=11, code1 = 100, code2 = 200;
1129 else
1130 test_num=12, code1 = 200, code2 = 0;
1131
1132 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
1133
1134 /* On received response, create UAS. */
1135 pjsip_transaction *tsx;
1136
1137 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
1138 if (status != PJ_SUCCESS) {
1139 app_perror(" error: unable to create transaction", status);
1140 test_complete = -150;
1141 return PJ_TRUE;
1142 }
1143
Benny Prijono38998232006-02-08 22:44:25 +00001144 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijono728a9052006-01-18 23:34:15 +00001145 save_key(tsx);
1146
1147 schedule_send_response(rdata, &tsx_key, code1, 1000);
1148
1149 if (code2)
1150 schedule_send_response(rdata, &tsx_key, code2, 2000);
1151
1152 } else {
1153
1154 }
1155
1156 return PJ_TRUE;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001157 }
1158
1159 return PJ_FALSE;
1160}
1161
1162/*
1163 * The generic test framework, used by most of the tests.
1164 */
1165static int perform_test( char *target_uri, char *from_uri,
1166 char *branch_param, int test_time,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001167 const pjsip_method *method,
1168 int request_cnt, int request_interval_msec,
1169 int expecting_timeout)
Benny Prijonodbe337a2006-01-08 23:57:52 +00001170{
1171 pjsip_tx_data *tdata;
1172 pj_str_t target, from;
1173 pjsip_via_hdr *via;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001174 pj_time_val timeout, next_send;
1175 int sent_cnt;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001176 pj_status_t status;
1177
1178 PJ_LOG(3,(THIS_FILE,
1179 " please standby, this will take at most %d seconds..",
1180 test_time));
1181
1182 /* Reset test. */
1183 recv_count = 0;
1184 test_complete = 0;
1185 tsx_key.slen = 0;
1186
1187 /* Init headers. */
1188 target = pj_str(target_uri);
1189 from = pj_str(from_uri);
1190
1191 /* Create request. */
1192 status = pjsip_endpt_create_request( endpt, method, &target,
1193 &from, &target, NULL, NULL, -1,
1194 NULL, &tdata);
1195 if (status != PJ_SUCCESS) {
1196 app_perror(" Error: unable to create request", status);
1197 return -10;
1198 }
1199
1200 /* Set the branch param for test 1. */
Benny Prijonoa1e69682007-05-11 15:14:34 +00001201 via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001202 via->branch_param = pj_str(branch_param);
1203
Benny Prijono0c2bc612006-01-10 13:31:40 +00001204 /* Schedule first send. */
1205 sent_cnt = 0;
1206 pj_gettimeofday(&next_send);
1207 pj_time_val_normalize(&next_send);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001208
1209 /* Set test completion time. */
1210 pj_gettimeofday(&timeout);
1211 timeout.sec += test_time;
1212
1213 /* Wait until test complete. */
1214 while (!test_complete) {
1215 pj_time_val now, poll_delay = {0, 10};
1216
1217 pjsip_endpt_handle_events(endpt, &poll_delay);
1218
1219 pj_gettimeofday(&now);
Benny Prijono0c2bc612006-01-10 13:31:40 +00001220
1221 if (sent_cnt < request_cnt && PJ_TIME_VAL_GTE(now, next_send)) {
1222 /* Add additional reference to tdata to prevent transaction from
1223 * deleting it.
1224 */
1225 pjsip_tx_data_add_ref(tdata);
1226
1227 /* (Re)Send the request. */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001228 PJ_LOG(4,(THIS_FILE, " (re)sending request %d", sent_cnt));
1229
Benny Prijono0c2bc612006-01-10 13:31:40 +00001230 status = pjsip_endpt_send_request_stateless(endpt, tdata, 0, 0);
1231 if (status != PJ_SUCCESS) {
1232 app_perror(" Error: unable to send request", status);
1233 pjsip_tx_data_dec_ref(tdata);
1234 return -20;
1235 }
1236
1237 /* Schedule next send, if any. */
1238 sent_cnt++;
1239 if (sent_cnt < request_cnt) {
1240 pj_gettimeofday(&next_send);
1241 next_send.msec += request_interval_msec;
1242 pj_time_val_normalize(&next_send);
1243 }
1244 }
1245
Benny Prijonodbe337a2006-01-08 23:57:52 +00001246 if (now.sec > timeout.sec) {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001247 if (!expecting_timeout)
1248 PJ_LOG(3,(THIS_FILE, " Error: test has timed out"));
Benny Prijonodbe337a2006-01-08 23:57:52 +00001249 pjsip_tx_data_dec_ref(tdata);
Benny Prijono0c2bc612006-01-10 13:31:40 +00001250 return TEST_TIMEOUT_ERROR;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001251 }
1252 }
1253
1254 if (test_complete < 0) {
1255 pjsip_transaction *tsx;
1256
1257 tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
1258 if (tsx) {
1259 pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);
1260 pj_mutex_unlock(tsx->mutex);
1261 flush_events(1000);
1262 }
1263 pjsip_tx_data_dec_ref(tdata);
1264 return test_complete;
1265 }
1266
1267 /* Allow transaction to destroy itself */
1268 flush_events(500);
1269
1270 /* Make sure transaction has been destroyed. */
1271 if (pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE) != NULL) {
1272 PJ_LOG(3,(THIS_FILE, " Error: transaction has not been destroyed"));
1273 pjsip_tx_data_dec_ref(tdata);
1274 return -40;
1275 }
1276
1277 /* Check tdata reference counter. */
1278 if (pj_atomic_get(tdata->ref_cnt) != 1) {
1279 PJ_LOG(3,(THIS_FILE, " Error: tdata reference counter is %d",
1280 pj_atomic_get(tdata->ref_cnt)));
1281 pjsip_tx_data_dec_ref(tdata);
1282 return -50;
1283 }
1284
1285 /* Destroy txdata */
1286 pjsip_tx_data_dec_ref(tdata);
1287
1288 return PJ_SUCCESS;
1289
1290}
1291
1292
1293/*****************************************************************************
1294 **
1295 ** TEST1_BRANCH_ID: Basic 2xx final response
1296 ** TEST2_BRANCH_ID: Basic non-2xx final response
1297 **
1298 *****************************************************************************
1299 */
1300static int tsx_basic_final_response_test(void)
1301{
Benny Prijonoe93e2872006-06-28 16:46:49 +00001302 unsigned duration;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001303 int status;
1304
1305 PJ_LOG(3,(THIS_FILE," test1: basic sending 2xx final response"));
1306
Benny Prijonoe93e2872006-06-28 16:46:49 +00001307 /* Test duration must be greater than 32 secs if unreliable transport
1308 * is used.
1309 */
1310 duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
1311
1312 status = perform_test(TARGET_URI, FROM_URI, TEST1_BRANCH_ID,
1313 duration, &pjsip_options_method, 1, 0, 0);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001314 if (status != 0)
1315 return status;
1316
1317 PJ_LOG(3,(THIS_FILE," test2: basic sending non-2xx final response"));
1318
Benny Prijonoe93e2872006-06-28 16:46:49 +00001319 status = perform_test(TARGET_URI, FROM_URI, TEST2_BRANCH_ID,
1320 duration, &pjsip_options_method, 1, 0, 0);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001321 if (status != 0)
1322 return status;
1323
1324 return 0;
1325}
1326
1327
1328/*****************************************************************************
1329 **
1330 ** TEST3_BRANCH_ID: Sending provisional response
1331 **
1332 *****************************************************************************
1333 */
1334static int tsx_basic_provisional_response_test(void)
1335{
Benny Prijonoe93e2872006-06-28 16:46:49 +00001336 unsigned duration;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001337 int status;
1338
Benny Prijono02b8fd82006-06-26 15:12:55 +00001339 PJ_LOG(3,(THIS_FILE," test3: basic sending 2xx final response"));
Benny Prijonodbe337a2006-01-08 23:57:52 +00001340
Benny Prijonoe93e2872006-06-28 16:46:49 +00001341 duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
1342 duration += 2;
1343
1344 status = perform_test(TARGET_URI, FROM_URI, TEST3_BRANCH_ID, duration,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001345 &pjsip_options_method, 1, 0, 0);
1346
Benny Prijonodbe337a2006-01-08 23:57:52 +00001347 return status;
1348}
1349
1350
1351/*****************************************************************************
1352 **
Benny Prijono0c2bc612006-01-10 13:31:40 +00001353 ** TEST4_BRANCH_ID: Absorbs retransmissions in TRYING state
1354 ** TEST5_BRANCH_ID: Absorbs retransmissions in PROCEEDING state
1355 ** TEST6_BRANCH_ID: Absorbs retransmissions in COMPLETED state
1356 **
1357 *****************************************************************************
1358 */
1359static int tsx_retransmit_last_response_test(const char *title,
1360 char *branch_id,
1361 int request_cnt,
1362 int status_code)
1363{
1364 int status;
1365
1366 PJ_LOG(3,(THIS_FILE," %s", title));
1367
Benny Prijonoe93e2872006-06-28 16:46:49 +00001368 status = perform_test(TARGET_URI, FROM_URI, branch_id, 5,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001369 &pjsip_options_method,
1370 request_cnt, 1000, 1);
1371 if (status && status != TEST_TIMEOUT_ERROR)
1372 return status;
1373 if (!status) {
1374 PJ_LOG(3,(THIS_FILE, " error: expecting timeout"));
1375 return -31;
1376 }
1377
1378 terminate_our_tsx(status_code);
1379 flush_events(100);
1380
1381 if (test_complete != 1)
1382 return test_complete;
1383
1384 flush_events(100);
1385 return 0;
1386}
1387
1388/*****************************************************************************
1389 **
1390 ** TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
1391 ** TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
1392 **
1393 *****************************************************************************
1394 */
1395static int tsx_final_response_retransmission_test(void)
1396{
1397 int status;
1398
1399 PJ_LOG(3,(THIS_FILE,
1400 " test7: INVITE non-2xx final response retransmission"));
1401
Benny Prijonoe93e2872006-06-28 16:46:49 +00001402 status = perform_test(TARGET_URI, FROM_URI, TEST7_BRANCH_ID,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001403 33, /* Test duration must be greater than 32 secs */
1404 &pjsip_invite_method, 1, 0, 0);
1405 if (status != 0)
1406 return status;
1407
1408 PJ_LOG(3,(THIS_FILE,
1409 " test8: INVITE 2xx final response retransmission"));
1410
Benny Prijonoe93e2872006-06-28 16:46:49 +00001411 status = perform_test(TARGET_URI, FROM_URI, TEST8_BRANCH_ID,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001412 33, /* Test duration must be greater than 32 secs */
1413 &pjsip_invite_method, 1, 0, 0);
1414 if (status != 0)
1415 return status;
1416
1417 return 0;
1418}
1419
1420
Benny Prijono728a9052006-01-18 23:34:15 +00001421/*****************************************************************************
1422 **
1423 ** TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
1424 ** cease when ACK is received
1425 **
1426 *****************************************************************************
1427 */
1428static int tsx_ack_test(void)
1429{
1430 int status;
1431
1432 PJ_LOG(3,(THIS_FILE,
1433 " test9: receiving ACK for non-2xx final response"));
1434
Benny Prijonoe93e2872006-06-28 16:46:49 +00001435 status = perform_test(TARGET_URI, FROM_URI, TEST9_BRANCH_ID,
Benny Prijono728a9052006-01-18 23:34:15 +00001436 20, /* allow 5 retransmissions */
1437 &pjsip_invite_method, 1, 0, 0);
1438 if (status != 0)
1439 return status;
1440
1441
1442 return 0;
1443}
1444
1445
1446
1447/*****************************************************************************
1448 **
1449 ** TEST10_BRANCH_ID: test transport failure in TRYING state.
1450 ** TEST11_BRANCH_ID: test transport failure in PROCEEDING state.
1451 ** TEST12_BRANCH_ID: test transport failure in CONNECTED state.
1452 ** TEST13_BRANCH_ID: test transport failure in CONFIRMED state.
1453 **
1454 *****************************************************************************
1455 */
1456static int tsx_transport_failure_test(void)
1457{
1458 struct test_desc
1459 {
1460 int transport_delay;
1461 int fail_delay;
1462 char *branch_id;
1463 char *title;
1464 } tests[] =
1465 {
1466 { 0, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (no delay)" },
1467 { 50, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (50 ms delay)" },
1468 { 0, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (no delay)" },
1469 { 50, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (50 ms delay)" },
1470 { 0, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (no delay)" },
1471 { 50, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (50 ms delay)" },
1472 };
1473 int i, status;
1474
Benny Prijonoa1e69682007-05-11 15:14:34 +00001475 for (i=0; i<(int)PJ_ARRAY_SIZE(tests); ++i) {
Benny Prijono728a9052006-01-18 23:34:15 +00001476 pj_time_val fail_time, end_test, now;
1477
1478 PJ_LOG(3,(THIS_FILE, " %s", tests[i].title));
1479 pjsip_loop_set_failure(loop, 0, NULL);
1480 pjsip_loop_set_delay(loop, tests[i].transport_delay);
1481
Benny Prijonoe93e2872006-06-28 16:46:49 +00001482 status = perform_test(TARGET_URI, FROM_URI, tests[i].branch_id,
1483 0, &pjsip_invite_method, 1, 0, 1);
Benny Prijono728a9052006-01-18 23:34:15 +00001484 if (status && status != TEST_TIMEOUT_ERROR)
1485 return status;
1486 if (!status) {
1487 PJ_LOG(3,(THIS_FILE, " error: expecting timeout"));
1488 return -40;
1489 }
1490
1491 pj_gettimeofday(&fail_time);
1492 fail_time.msec += tests[i].fail_delay;
1493 pj_time_val_normalize(&fail_time);
1494
1495 do {
1496 pj_time_val interval = { 0, 1 };
1497 pj_gettimeofday(&now);
1498 pjsip_endpt_handle_events(endpt, &interval);
1499 } while (PJ_TIME_VAL_LT(now, fail_time));
1500
1501 pjsip_loop_set_failure(loop, 1, NULL);
1502
1503 end_test = now;
1504 end_test.sec += 5;
1505
1506 do {
1507 pj_time_val interval = { 0, 1 };
1508 pj_gettimeofday(&now);
1509 pjsip_endpt_handle_events(endpt, &interval);
1510 } while (!test_complete && PJ_TIME_VAL_LT(now, end_test));
1511
1512 if (test_complete == 0) {
1513 PJ_LOG(3,(THIS_FILE, " error: test has timed out"));
1514 return -41;
1515 }
1516
1517 if (test_complete != 1)
1518 return test_complete;
1519 }
1520
1521 return 0;
1522}
Benny Prijono0c2bc612006-01-10 13:31:40 +00001523
1524/*****************************************************************************
1525 **
Benny Prijonodbe337a2006-01-08 23:57:52 +00001526 ** UAS Transaction Test.
1527 **
1528 *****************************************************************************
1529 */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001530int tsx_uas_test(struct tsx_test_param *param)
Benny Prijonodbe337a2006-01-08 23:57:52 +00001531{
1532 pj_sockaddr_in addr;
1533 pj_status_t status;
1534
Benny Prijonoe93e2872006-06-28 16:46:49 +00001535 test_param = param;
Benny Prijonoa1e69682007-05-11 15:14:34 +00001536 tp_flag = pjsip_transport_get_flag_from_type((pjsip_transport_type_e)param->type);
Benny Prijonoe93e2872006-06-28 16:46:49 +00001537
1538 pj_ansi_sprintf(TARGET_URI, "sip:bob@127.0.0.1:%d;transport=%s",
1539 param->port, param->tp_type);
1540 pj_ansi_sprintf(FROM_URI, "sip:alice@127.0.0.1:%d;transport=%s",
1541 param->port, param->tp_type);
1542
Benny Prijonodbe337a2006-01-08 23:57:52 +00001543 /* Check if loop transport is configured. */
1544 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
Benny Prijonodf2b71e2007-01-20 19:17:47 +00001545 &addr, sizeof(addr), NULL, &loop);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001546 if (status != PJ_SUCCESS) {
1547 PJ_LOG(3,(THIS_FILE, " Error: loop transport is not configured!"));
Benny Prijonoe93e2872006-06-28 16:46:49 +00001548 return -10;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001549 }
Benny Prijonodbe337a2006-01-08 23:57:52 +00001550 /* Register modules. */
1551 status = pjsip_endpt_register_module(endpt, &tsx_user);
1552 if (status != PJ_SUCCESS) {
1553 app_perror(" Error: unable to register module", status);
1554 return -3;
1555 }
1556 status = pjsip_endpt_register_module(endpt, &msg_sender);
1557 if (status != PJ_SUCCESS) {
1558 app_perror(" Error: unable to register module", status);
1559 return -4;
1560 }
1561
Benny Prijonodbe337a2006-01-08 23:57:52 +00001562 /* TEST1_BRANCH_ID: Basic 2xx final response.
1563 * TEST2_BRANCH_ID: Basic non-2xx final response.
1564 */
1565 status = tsx_basic_final_response_test();
1566 if (status != 0)
1567 return status;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001568
1569 /* TEST3_BRANCH_ID: with provisional response
1570 */
1571 status = tsx_basic_provisional_response_test();
1572 if (status != 0)
1573 return status;
1574
Benny Prijono0c2bc612006-01-10 13:31:40 +00001575 /* TEST4_BRANCH_ID: absorbs retransmissions in TRYING state
1576 */
1577 status = tsx_retransmit_last_response_test(TEST4_TITLE,
1578 TEST4_BRANCH_ID,
1579 TEST4_REQUEST_COUNT,
1580 TEST4_STATUS_CODE);
1581 if (status != 0)
1582 return status;
1583
1584 /* TEST5_BRANCH_ID: retransmit last response in PROCEEDING state
1585 */
1586 status = tsx_retransmit_last_response_test(TEST5_TITLE,
1587 TEST5_BRANCH_ID,
1588 TEST5_REQUEST_COUNT,
1589 TEST5_STATUS_CODE);
1590 if (status != 0)
1591 return status;
1592
Benny Prijonoe93e2872006-06-28 16:46:49 +00001593 /* TEST6_BRANCH_ID: retransmit last response in COMPLETED state
1594 * This only applies to non-reliable transports,
1595 * since UAS transaction is destroyed as soon
1596 * as final response is sent for reliable transports.
Benny Prijono0c2bc612006-01-10 13:31:40 +00001597 */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001598 if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
1599 status = tsx_retransmit_last_response_test(TEST6_TITLE,
1600 TEST6_BRANCH_ID,
1601 TEST6_REQUEST_COUNT,
1602 TEST6_STATUS_CODE);
1603 if (status != 0)
1604 return status;
1605 }
Benny Prijono0c2bc612006-01-10 13:31:40 +00001606
1607 /* TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
1608 * TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
1609 */
Benny Prijono0c2bc612006-01-10 13:31:40 +00001610 status = tsx_final_response_retransmission_test();
1611 if (status != 0)
1612 return status;
1613
Benny Prijono728a9052006-01-18 23:34:15 +00001614 /* TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
1615 * cease when ACK is received
Benny Prijonoe93e2872006-06-28 16:46:49 +00001616 * Only applicable for non-reliable transports.
Benny Prijono728a9052006-01-18 23:34:15 +00001617 */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001618 if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
1619 status = tsx_ack_test();
1620 if (status != 0)
1621 return status;
1622 }
1623
Benny Prijono728a9052006-01-18 23:34:15 +00001624
1625 /* TEST10_BRANCH_ID: test transport failure in TRYING state.
1626 * TEST11_BRANCH_ID: test transport failure in PROCEEDING state.
1627 * TEST12_BRANCH_ID: test transport failure in CONNECTED state.
1628 * TEST13_BRANCH_ID: test transport failure in CONFIRMED state.
1629 */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001630 /* Only valid for loop-dgram */
1631 if (param->type == PJSIP_TRANSPORT_LOOP_DGRAM) {
1632 status = tsx_transport_failure_test();
1633 if (status != 0)
1634 return status;
1635 }
Benny Prijono728a9052006-01-18 23:34:15 +00001636
Benny Prijonodbe337a2006-01-08 23:57:52 +00001637
Benny Prijonoe93e2872006-06-28 16:46:49 +00001638 /* Register modules. */
1639 status = pjsip_endpt_unregister_module(endpt, &tsx_user);
1640 if (status != PJ_SUCCESS) {
1641 app_perror(" Error: unable to unregister module", status);
1642 return -8;
1643 }
1644 status = pjsip_endpt_unregister_module(endpt, &msg_sender);
1645 if (status != PJ_SUCCESS) {
1646 app_perror(" Error: unable to unregister module", status);
1647 return -9;
1648 }
1649
1650
1651 if (loop)
1652 pjsip_transport_dec_ref(loop);
1653
Benny Prijonodbe337a2006-01-08 23:57:52 +00001654 return 0;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001655}
1656