blob: 3c43f5359f0a54aad8373c45372138047ac426b3 [file] [log] [blame]
Alexandre Lision8af73cb2013-12-10 14:11:20 -05001/* $Id$ */
2/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
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"
22#include <pjsip.h>
23#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.
39 ** This also checks that transaction is destroyed immediately after
40 ** it sends final response when reliable transport is used.
41 **
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
51 ** transaction user upon receiving request retransmissions on TRYING
52 ** state
53 **
54 ** TEST5_BRANCH_ID
55 ** As above, in PROCEEDING state.
56 **
57 ** TEST6_BRANCH_ID
58 ** As above, in COMPLETED state, with first sending provisional response.
59 ** (Only applicable for non-reliable transports).
60 **
61 ** TEST7_BRANCH_ID
62 ** INVITE transaction MUST retransmit non-2xx final response.
63 **
64 ** TEST8_BRANCH_ID
65 ** 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.
72 ** (Only applicable for non-reliable transports).
73 **
74 ** TEST11_BRANCH_ID
75 ** 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
87 ** 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 **
96 **/
97
98#define TEST1_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test1")
99#define TEST2_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test2")
100#define TEST3_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test3")
101#define TEST4_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test4")
102#define TEST5_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test5")
103#define TEST6_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test6")
104#define TEST7_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test7")
105#define TEST8_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test8")
106#define TEST9_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test9")
107#define TEST10_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test10")
108#define TEST11_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test11")
109#define TEST12_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test12")
110//#define TEST13_BRANCH_ID (PJSIP_RFC3261_BRANCH_ID "-UAS-Test13")
111
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
116#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
128#define TEST9_STATUS_CODE 301
129
130
131#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
136static char TARGET_URI[128];
137static char FROM_URI[128];
138static struct tsx_test_param *test_param;
139static unsigned tp_flag;
140
141
142#define TEST_TIMEOUT_ERROR -30
143#define MAX_ALLOWED_DIFF 150
144
145static 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 */
155 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 */
173 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. */
198//static pj_timer_entry timer;
199
200/* Timer to send response via transaction. */
201struct response
202{
203 pj_str_t tsx_key;
204 pjsip_tx_data *tdata;
205};
206
207/* Timer callback to send response. */
208static void send_response_timer( pj_timer_heap_t *timer_heap,
209 struct pj_timer_entry *entry)
210{
211 pjsip_transaction *tsx;
212 struct response *r = (struct response*) entry->user_data;
213 pj_status_t status;
214
215 PJ_UNUSED_ARG(timer_heap);
216
217 tsx = pjsip_tsx_layer_find_tsx(&r->tsx_key, PJ_TRUE);
218 if (!tsx) {
219 PJ_LOG(3,(THIS_FILE," error: timer unable to find transaction"));
220 pjsip_tx_data_dec_ref(r->tdata);
221 return;
222 }
223
224 status = pjsip_tsx_send_msg(tsx, r->tdata);
225 if (status != PJ_SUCCESS) {
226 // Some tests do expect failure!
227 //PJ_LOG(3,(THIS_FILE," error: timer unable to send response"));
228 pj_grp_lock_release(tsx->grp_lock);
229 pjsip_tx_data_dec_ref(r->tdata);
230 return;
231 }
232
233 pj_grp_lock_release(tsx->grp_lock);
234}
235
236/* Utility to send response. */
237static void send_response( pjsip_rx_data *rdata,
238 pjsip_transaction *tsx,
239 int status_code )
240{
241 pj_status_t status;
242 pjsip_tx_data *tdata;
243
244 status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL,
245 &tdata);
246 if (status != PJ_SUCCESS) {
247 app_perror(" error: unable to create response", status);
248 test_complete = -196;
249 return;
250 }
251
252 status = pjsip_tsx_send_msg(tsx, tdata);
253 if (status != PJ_SUCCESS) {
254 pjsip_tx_data_dec_ref(tdata);
255 // Some tests do expect failure!
256 //app_perror(" error: unable to send response", status);
257 //test_complete = -197;
258 return;
259 }
260}
261
262/* Schedule timer to send response for the specified UAS transaction */
263static void schedule_send_response( pjsip_rx_data *rdata,
264 const pj_str_t *tsx_key,
265 int status_code,
266 int msec_delay )
267{
268 pj_status_t status;
269 pjsip_tx_data *tdata;
270 pj_timer_entry *t;
271 struct response *r;
272 pj_time_val delay;
273
274 status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL,
275 &tdata);
276 if (status != PJ_SUCCESS) {
277 app_perror(" error: unable to create response", status);
278 test_complete = -198;
279 return;
280 }
281
282 r = PJ_POOL_ALLOC_T(tdata->pool, struct response);
283 pj_strdup(tdata->pool, &r->tsx_key, tsx_key);
284 r->tdata = tdata;
285
286 delay.sec = 0;
287 delay.msec = msec_delay;
288 pj_time_val_normalize(&delay);
289
290 t = PJ_POOL_ZALLOC_T(tdata->pool, pj_timer_entry);
291 t->user_data = r;
292 t->cb = &send_response_timer;
293
294 status = pjsip_endpt_schedule_timer(endpt, t, &delay);
295 if (status != PJ_SUCCESS) {
296 pjsip_tx_data_dec_ref(tdata);
297 app_perror(" error: unable to schedule timer", status);
298 test_complete = -199;
299 return;
300 }
301}
302
303
304/* Find and terminate tsx with the specified key. */
305static void terminate_our_tsx(int status_code)
306{
307 pjsip_transaction *tsx;
308
309 tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
310 if (!tsx) {
311 PJ_LOG(3,(THIS_FILE," error: timer unable to find transaction"));
312 return;
313 }
314
315 pjsip_tsx_terminate(tsx, status_code);
316 pj_grp_lock_release(tsx->grp_lock);
317}
318
319#if 0 /* Unused for now */
320/* Timer callback to terminate transaction. */
321static void terminate_tsx_timer( pj_timer_heap_t *timer_heap,
322 struct pj_timer_entry *entry)
323{
324 terminate_our_tsx(entry->id);
325}
326
327
328/* Schedule timer to terminate transaction. */
329static void schedule_terminate_tsx( pjsip_transaction *tsx,
330 int status_code,
331 int msec_delay )
332{
333 pj_time_val delay;
334
335 delay.sec = 0;
336 delay.msec = msec_delay;
337 pj_time_val_normalize(&delay);
338
339 pj_assert(pj_strcmp(&tsx->transaction_key, &tsx_key)==0);
340 timer.user_data = NULL;
341 timer.id = status_code;
342 timer.cb = &terminate_tsx_timer;
343 pjsip_endpt_schedule_timer(endpt, &timer, &delay);
344}
345#endif
346
347
348/*
349 * This is the handler to receive state changed notification from the
350 * transaction. It is used to verify that the transaction behaves according
351 * to the test scenario.
352 */
353static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
354{
355 if (pj_stricmp2(&tsx->branch, TEST1_BRANCH_ID)==0 ||
356 pj_stricmp2(&tsx->branch, TEST2_BRANCH_ID)==0)
357 {
358 /*
359 * TEST1_BRANCH_ID tests that non-INVITE transaction transmits final
360 * response using correct transport and terminates transaction after
361 * T4 (PJSIP_T4_TIMEOUT, 5 seconds).
362 *
363 * TEST2_BRANCH_ID does similar test for non-2xx final response.
364 */
365 int status_code = (pj_stricmp2(&tsx->branch, TEST1_BRANCH_ID)==0) ?
366 TEST1_STATUS_CODE : TEST2_STATUS_CODE;
367
368 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
369
370 test_complete = 1;
371
372 /* Check that status code is status_code. */
373 if (tsx->status_code != status_code) {
374 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
375 test_complete = -100;
376 }
377
378 /* Previous state must be completed. */
379 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
380 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
381 test_complete = -101;
382 }
383
384 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
385
386 /* Previous state must be TRYING. */
387 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
388 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
389 test_complete = -102;
390 }
391 }
392
393 }
394 else
395 if (pj_stricmp2(&tsx->branch, TEST3_BRANCH_ID)==0) {
396 /*
397 * TEST3_BRANCH_ID tests sending provisional response.
398 */
399 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
400
401 test_complete = 1;
402
403 /* Check that status code is status_code. */
404 if (tsx->status_code != TEST3_STATUS_CODE) {
405 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
406 test_complete = -110;
407 }
408
409 /* Previous state must be completed. */
410 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
411 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
412 test_complete = -111;
413 }
414
415 } else if (tsx->state == PJSIP_TSX_STATE_PROCEEDING) {
416
417 /* Previous state must be TRYING. */
418 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
419 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
420 test_complete = -112;
421 }
422
423 /* Check that status code is status_code. */
424 if (tsx->status_code != TEST3_PROVISIONAL_CODE) {
425 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
426 test_complete = -113;
427 }
428
429 /* Check that event must be TX_MSG */
430 if (e->body.tsx_state.type != PJSIP_EVENT_TX_MSG) {
431 PJ_LOG(3,(THIS_FILE, " error: incorrect event"));
432 test_complete = -114;
433 }
434
435 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
436
437 /* Previous state must be PROCEEDING. */
438 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) {
439 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
440 test_complete = -115;
441 }
442
443 /* Check that status code is status_code. */
444 if (tsx->status_code != TEST3_STATUS_CODE) {
445 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
446 test_complete = -116;
447 }
448
449 /* Check that event must be TX_MSG */
450 if (e->body.tsx_state.type != PJSIP_EVENT_TX_MSG) {
451 PJ_LOG(3,(THIS_FILE, " error: incorrect event"));
452 test_complete = -117;
453 }
454
455 }
456
457 } else
458 if (pj_stricmp2(&tsx->branch, TEST4_BRANCH_ID)==0) {
459 /*
460 * TEST4_BRANCH_ID tests receiving retransmissions in TRYING state.
461 */
462 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
463 /* Request is received. */
464 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
465
466 /* Check that status code is status_code. */
467 if (tsx->status_code != TEST4_STATUS_CODE) {
468 PJ_LOG(3,(THIS_FILE,
469 " error: incorrect status code %d "
470 "(expecting %d)", tsx->status_code,
471 TEST4_STATUS_CODE));
472 test_complete = -120;
473 }
474
475 /* Previous state. */
476 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
477 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
478 test_complete = -121;
479 }
480
481 } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED)
482 {
483 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (122)",
484 pjsip_tsx_state_str(tsx->state)));
485 test_complete = -122;
486
487 }
488
489
490 } else
491 if (pj_stricmp2(&tsx->branch, TEST5_BRANCH_ID)==0) {
492 /*
493 * TEST5_BRANCH_ID tests receiving retransmissions in PROCEEDING state
494 */
495 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
496 /* Request is received. */
497
498 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
499
500 /* Check that status code is status_code. */
501 if (tsx->status_code != TEST5_STATUS_CODE) {
502 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
503 test_complete = -130;
504 }
505
506 /* Previous state. */
507 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) {
508 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
509 test_complete = -131;
510 }
511
512 } else if (tsx->state == PJSIP_TSX_STATE_PROCEEDING) {
513
514 /* Check status code. */
515 if (tsx->status_code != TEST5_PROVISIONAL_CODE) {
516 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
517 test_complete = -132;
518 }
519
520 } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED) {
521 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (133)",
522 pjsip_tsx_state_str(tsx->state)));
523 test_complete = -133;
524
525 }
526
527 } else
528 if (pj_stricmp2(&tsx->branch, TEST6_BRANCH_ID)==0) {
529 /*
530 * TEST6_BRANCH_ID tests receiving retransmissions in COMPLETED state
531 */
532 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
533 /* Request is received. */
534
535 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
536
537 /* Check that status code is status_code. */
538 if (tsx->status_code != TEST6_STATUS_CODE) {
539 PJ_LOG(3,(THIS_FILE, " error: incorrect status code %d "
540 "(expecting %d)", tsx->status_code,
541 TEST6_STATUS_CODE));
542 test_complete = -140;
543 }
544
545 /* Previous state. */
546 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
547 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
548 test_complete = -141;
549 }
550
551 } else if (tsx->state != PJSIP_TSX_STATE_PROCEEDING &&
552 tsx->state != PJSIP_TSX_STATE_COMPLETED &&
553 tsx->state != PJSIP_TSX_STATE_DESTROYED)
554 {
555 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (142)",
556 pjsip_tsx_state_str(tsx->state)));
557 test_complete = -142;
558
559 }
560
561
562 } else
563 if (pj_stricmp2(&tsx->branch, TEST7_BRANCH_ID)==0 ||
564 pj_stricmp2(&tsx->branch, TEST8_BRANCH_ID)==0)
565 {
566 /*
567 * TEST7_BRANCH_ID and TEST8_BRANCH_ID test retransmission of
568 * INVITE final response
569 */
570 int code;
571
572 if (pj_stricmp2(&tsx->branch, TEST7_BRANCH_ID) == 0)
573 code = TEST7_STATUS_CODE;
574 else
575 code = TEST8_STATUS_CODE;
576
577 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
578 /* Request is received. */
579
580 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
581
582 if (test_complete == 0)
583 test_complete = 1;
584
585 /* Check status code. */
586 if (tsx->status_code != PJSIP_SC_TSX_TIMEOUT) {
587 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
588 test_complete = -150;
589 }
590
591 /* Previous state. */
592 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
593 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
594 test_complete = -151;
595 }
596
597 /* Check the number of retransmissions */
598 if (tp_flag & PJSIP_TRANSPORT_RELIABLE) {
599
600 if (tsx->retransmit_count != 0) {
601 PJ_LOG(3,(THIS_FILE, " error: should not retransmit"));
602 test_complete = -1510;
603 }
604
605 } else {
606
607 if (tsx->retransmit_count != 10) {
608 PJ_LOG(3,(THIS_FILE,
609 " error: incorrect retransmit count %d "
610 "(expecting 10)",
611 tsx->retransmit_count));
612 test_complete = -1510;
613 }
614
615 }
616
617 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
618
619 /* Check that status code is status_code. */
620 if (tsx->status_code != code) {
621 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
622 test_complete = -152;
623 }
624
625 /* Previous state. */
626 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
627 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
628 test_complete = -153;
629 }
630
631 } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED) {
632
633 PJ_LOG(3,(THIS_FILE, " error: unexpected state (154)"));
634 test_complete = -154;
635
636 }
637
638
639 } else
640 if (pj_stricmp2(&tsx->branch, TEST9_BRANCH_ID)==0) {
641 /*
642 * TEST9_BRANCH_ID tests that retransmission of INVITE final response
643 * must cease when ACK is received.
644 */
645
646 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
647 /* Request is received. */
648
649 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
650
651 if (test_complete == 0)
652 test_complete = 1;
653
654 /* Check status code. */
655 if (tsx->status_code != TEST9_STATUS_CODE) {
656 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
657 test_complete = -160;
658 }
659
660 /* Previous state. */
661 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_CONFIRMED) {
662 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
663 test_complete = -161;
664 }
665
666 } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
667
668 /* Check that status code is status_code. */
669 if (tsx->status_code != TEST9_STATUS_CODE) {
670 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
671 test_complete = -162;
672 }
673
674 /* Previous state. */
675 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
676 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
677 test_complete = -163;
678 }
679
680
681 } else if (tsx->state == PJSIP_TSX_STATE_CONFIRMED) {
682
683 /* Check that status code is status_code. */
684 if (tsx->status_code != TEST9_STATUS_CODE) {
685 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
686 test_complete = -164;
687 }
688
689 /* Previous state. */
690 if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
691 PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
692 test_complete = -165;
693 }
694
695 } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED) {
696
697 PJ_LOG(3,(THIS_FILE, " error: unexpected state (166)"));
698 test_complete = -166;
699
700 }
701
702
703 } else
704 if (pj_stricmp2(&tsx->branch, TEST10_BRANCH_ID)==0 ||
705 pj_stricmp2(&tsx->branch, TEST11_BRANCH_ID)==0 ||
706 pj_stricmp2(&tsx->branch, TEST12_BRANCH_ID)==0)
707 {
708 if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
709
710 if (!test_complete)
711 test_complete = 1;
712
713 if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) {
714 PJ_LOG(3,(THIS_FILE," error: incorrect status code"));
715 test_complete = -170;
716 }
717 }
718 }
719
720}
721
722/* Save transaction key to global variables. */
723static void save_key(pjsip_transaction *tsx)
724{
725 pj_str_t key;
726
727 pj_strdup(tsx->pool, &key, &tsx->transaction_key);
728 pj_strcpy(&tsx_key, &key);
729}
730
731#define DIFF(a,b) ((a<b) ? (b-a) : (a-b))
732
733/*
734 * Message receiver handler.
735 */
736static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
737{
738 pjsip_msg *msg = rdata->msg_info.msg;
739 pj_str_t branch_param = rdata->msg_info.via->branch_param;
740 pj_status_t status;
741
742 if (pj_stricmp2(&branch_param, TEST1_BRANCH_ID) == 0 ||
743 pj_stricmp2(&branch_param, TEST2_BRANCH_ID) == 0)
744 {
745 /*
746 * TEST1_BRANCH_ID tests that non-INVITE transaction transmits 2xx
747 * final response using correct transport and terminates transaction
748 * after 32 seconds.
749 *
750 * TEST2_BRANCH_ID performs similar test for non-2xx final response.
751 */
752 int status_code = (pj_stricmp2(&branch_param, TEST1_BRANCH_ID) == 0) ?
753 TEST1_STATUS_CODE : TEST2_STATUS_CODE;
754
755 if (msg->type == PJSIP_REQUEST_MSG) {
756 /* On received request, create UAS and respond with final
757 * response.
758 */
759 pjsip_transaction *tsx;
760
761 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
762 if (status != PJ_SUCCESS) {
763 app_perror(" error: unable to create transaction", status);
764 test_complete = -110;
765 return PJ_TRUE;
766 }
767 pjsip_tsx_recv_msg(tsx, rdata);
768
769 save_key(tsx);
770 send_response(rdata, tsx, status_code);
771
772 } else {
773 /* Verify the response received. */
774
775 ++recv_count;
776
777 /* Verify status code. */
778 if (msg->line.status.code != status_code) {
779 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
780 test_complete = -113;
781 }
782
783 /* Verify that no retransmissions is received. */
784 if (recv_count > 1) {
785 PJ_LOG(3,(THIS_FILE, " error: retransmission received"));
786 test_complete = -114;
787 }
788
789 }
790 return PJ_TRUE;
791
792 } else if (pj_stricmp2(&branch_param, TEST3_BRANCH_ID) == 0) {
793
794 /* TEST3_BRANCH_ID tests provisional response. */
795
796 if (msg->type == PJSIP_REQUEST_MSG) {
797 /* On received request, create UAS and respond with provisional
798 * response, then schedule timer to send final response.
799 */
800 pjsip_transaction *tsx;
801
802 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
803 if (status != PJ_SUCCESS) {
804 app_perror(" error: unable to create transaction", status);
805 test_complete = -116;
806 return PJ_TRUE;
807 }
808 pjsip_tsx_recv_msg(tsx, rdata);
809
810 save_key(tsx);
811
812 send_response(rdata, tsx, TEST3_PROVISIONAL_CODE);
813 schedule_send_response(rdata, &tsx->transaction_key,
814 TEST3_STATUS_CODE, 2000);
815
816 } else {
817 /* Verify the response received. */
818
819 ++recv_count;
820
821 if (recv_count == 1) {
822 /* Verify status code. */
823 if (msg->line.status.code != TEST3_PROVISIONAL_CODE) {
824 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
825 test_complete = -123;
826 }
827 } else if (recv_count == 2) {
828 /* Verify status code. */
829 if (msg->line.status.code != TEST3_STATUS_CODE) {
830 PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
831 test_complete = -124;
832 }
833 } else {
834 PJ_LOG(3,(THIS_FILE, " error: retransmission received"));
835 test_complete = -125;
836 }
837
838 }
839 return PJ_TRUE;
840
841 } else if (pj_stricmp2(&branch_param, TEST4_BRANCH_ID) == 0 ||
842 pj_stricmp2(&branch_param, TEST5_BRANCH_ID) == 0 ||
843 pj_stricmp2(&branch_param, TEST6_BRANCH_ID) == 0)
844 {
845
846 /* TEST4_BRANCH_ID: absorbs retransmissions in TRYING state. */
847 /* TEST5_BRANCH_ID: retransmit last response in PROCEEDING state. */
848 /* TEST6_BRANCH_ID: retransmit last response in COMPLETED state. */
849
850 if (msg->type == PJSIP_REQUEST_MSG) {
851 /* On received request, create UAS. */
852 pjsip_transaction *tsx;
853
854 PJ_LOG(4,(THIS_FILE, " received request (probably retransmission)"));
855
856 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
857 if (status != PJ_SUCCESS) {
858 app_perror(" error: unable to create transaction", status);
859 test_complete = -130;
860 return PJ_TRUE;
861 }
862
863 pjsip_tsx_recv_msg(tsx, rdata);
864 save_key(tsx);
865
866 if (pj_stricmp2(&branch_param, TEST4_BRANCH_ID) == 0) {
867
868 } else if (pj_stricmp2(&branch_param, TEST5_BRANCH_ID) == 0) {
869 send_response(rdata, tsx, TEST5_PROVISIONAL_CODE);
870
871 } else if (pj_stricmp2(&branch_param, TEST6_BRANCH_ID) == 0) {
872 PJ_LOG(4,(THIS_FILE, " sending provisional response"));
873 send_response(rdata, tsx, TEST6_PROVISIONAL_CODE);
874 PJ_LOG(4,(THIS_FILE, " sending final response"));
875 send_response(rdata, tsx, TEST6_STATUS_CODE);
876 }
877
878 } else {
879 /* Verify the response received. */
880
881 PJ_LOG(4,(THIS_FILE, " received response number %d", recv_count));
882
883 ++recv_count;
884
885 if (pj_stricmp2(&branch_param, TEST4_BRANCH_ID) == 0) {
886 PJ_LOG(3,(THIS_FILE, " error: not expecting response!"));
887 test_complete = -132;
888
889 } else if (pj_stricmp2(&branch_param, TEST5_BRANCH_ID) == 0) {
890
891 if (rdata->msg_info.msg->line.status.code!=TEST5_PROVISIONAL_CODE) {
892 PJ_LOG(3,(THIS_FILE, " error: incorrect status code!"));
893 test_complete = -133;
894
895 }
896 if (recv_count > TEST5_RESPONSE_COUNT) {
897 PJ_LOG(3,(THIS_FILE, " error: not expecting response!"));
898 test_complete = -134;
899 }
900
901 } else if (pj_stricmp2(&branch_param, TEST6_BRANCH_ID) == 0) {
902
903 int code = rdata->msg_info.msg->line.status.code;
904
905 switch (recv_count) {
906 case 1:
907 if (code != TEST6_PROVISIONAL_CODE) {
908 PJ_LOG(3,(THIS_FILE, " error: invalid code!"));
909 test_complete = -135;
910 }
911 break;
912 case 2:
913 case 3:
914 if (code != TEST6_STATUS_CODE) {
915 PJ_LOG(3,(THIS_FILE, " error: invalid code %d "
916 "(expecting %d)", code, TEST6_STATUS_CODE));
917 test_complete = -136;
918 }
919 break;
920 default:
921 PJ_LOG(3,(THIS_FILE, " error: not expecting response"));
922 test_complete = -137;
923 break;
924 }
925 }
926 }
927 return PJ_TRUE;
928
929
930 } else if (pj_stricmp2(&branch_param, TEST7_BRANCH_ID) == 0 ||
931 pj_stricmp2(&branch_param, TEST8_BRANCH_ID) == 0)
932 {
933
934 /*
935 * TEST7_BRANCH_ID and TEST8_BRANCH_ID test the retransmission
936 * of INVITE final response
937 */
938 if (msg->type == PJSIP_REQUEST_MSG) {
939
940 /* On received request, create UAS. */
941 pjsip_transaction *tsx;
942
943 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
944 if (status != PJ_SUCCESS) {
945 app_perror(" error: unable to create transaction", status);
946 test_complete = -140;
947 return PJ_TRUE;
948 }
949
950 pjsip_tsx_recv_msg(tsx, rdata);
951 save_key(tsx);
952
953 if (pj_stricmp2(&branch_param, TEST7_BRANCH_ID) == 0) {
954
955 send_response(rdata, tsx, TEST7_STATUS_CODE);
956
957 } else {
958
959 send_response(rdata, tsx, TEST8_STATUS_CODE);
960
961 }
962
963 } else {
964 int code;
965
966 ++recv_count;
967
968 if (pj_stricmp2(&branch_param, TEST7_BRANCH_ID) == 0)
969 code = TEST7_STATUS_CODE;
970 else
971 code = TEST8_STATUS_CODE;
972
973 if (recv_count==1) {
974
975 if (rdata->msg_info.msg->line.status.code != code) {
976 PJ_LOG(3,(THIS_FILE," error: invalid status code"));
977 test_complete = -141;
978 }
979
980 recv_last = rdata->pkt_info.timestamp;
981
982 } else {
983
984 pj_time_val now;
985 unsigned msec, msec_expected;
986
987 now = rdata->pkt_info.timestamp;
988
989 PJ_TIME_VAL_SUB(now, recv_last);
990
991 msec = now.sec*1000 + now.msec;
992 msec_expected = (1 << (recv_count-2)) * pjsip_cfg()->tsx.t1;
993 if (msec_expected > pjsip_cfg()->tsx.t2)
994 msec_expected = pjsip_cfg()->tsx.t2;
995
996 if (DIFF(msec, msec_expected) > MAX_ALLOWED_DIFF) {
997 PJ_LOG(3,(THIS_FILE,
998 " error: incorrect retransmission "
999 "time (%d ms expected, %d ms received",
1000 msec_expected, msec));
1001 test_complete = -142;
1002 }
1003
1004 if (recv_count > 11) {
1005 PJ_LOG(3,(THIS_FILE," error: too many responses (%d)",
1006 recv_count));
1007 test_complete = -143;
1008 }
1009
1010 recv_last = rdata->pkt_info.timestamp;
1011 }
1012
1013 }
1014 return PJ_TRUE;
1015
1016 } else if (pj_stricmp2(&branch_param, TEST9_BRANCH_ID) == 0) {
1017
1018 /*
1019 * TEST9_BRANCH_ID tests that the retransmission of INVITE final
1020 * response should cease when ACK is received. Transaction also MUST
1021 * terminate in T4 seconds.
1022 */
1023 if (msg->type == PJSIP_REQUEST_MSG) {
1024
1025 /* On received request, create UAS. */
1026 pjsip_transaction *tsx;
1027
1028 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
1029 if (status != PJ_SUCCESS) {
1030 app_perror(" error: unable to create transaction", status);
1031 test_complete = -150;
1032 return PJ_TRUE;
1033 }
1034
1035 pjsip_tsx_recv_msg(tsx, rdata);
1036 save_key(tsx);
1037 send_response(rdata, tsx, TEST9_STATUS_CODE);
1038
1039
1040 } else {
1041
1042 ++recv_count;
1043
1044 if (rdata->msg_info.msg->line.status.code != TEST9_STATUS_CODE) {
1045 PJ_LOG(3,(THIS_FILE," error: invalid status code"));
1046 test_complete = -151;
1047 }
1048
1049 if (recv_count==1) {
1050
1051 recv_last = rdata->pkt_info.timestamp;
1052
1053 } else if (recv_count < 5) {
1054
1055 /* Let UAS retransmit some messages before we send ACK. */
1056 pj_time_val now;
1057 unsigned msec, msec_expected;
1058
1059 now = rdata->pkt_info.timestamp;
1060
1061 PJ_TIME_VAL_SUB(now, recv_last);
1062
1063 msec = now.sec*1000 + now.msec;
1064 msec_expected = (1 << (recv_count-2)) * pjsip_cfg()->tsx.t1;
1065 if (msec_expected > pjsip_cfg()->tsx.t2)
1066 msec_expected = pjsip_cfg()->tsx.t2;
1067
1068 if (DIFF(msec, msec_expected) > MAX_ALLOWED_DIFF) {
1069 PJ_LOG(3,(THIS_FILE,
1070 " error: incorrect retransmission "
1071 "time (%d ms expected, %d ms received",
1072 msec_expected, msec));
1073 test_complete = -152;
1074 }
1075
1076 recv_last = rdata->pkt_info.timestamp;
1077
1078 } else if (recv_count == 5) {
1079 pjsip_tx_data *tdata;
1080 pjsip_sip_uri *uri;
1081 pjsip_via_hdr *via;
1082
1083 status = pjsip_endpt_create_request_from_hdr(
1084 endpt, &pjsip_ack_method,
1085 rdata->msg_info.to->uri,
1086 rdata->msg_info.from,
1087 rdata->msg_info.to,
1088 NULL,
1089 rdata->msg_info.cid,
1090 rdata->msg_info.cseq->cseq,
1091 NULL,
1092 &tdata);
1093 if (status != PJ_SUCCESS) {
1094 app_perror(" error: unable to create ACK", status);
1095 test_complete = -153;
1096 return PJ_TRUE;
1097 }
1098
1099 uri=(pjsip_sip_uri*)pjsip_uri_get_uri(tdata->msg->line.req.uri);
1100 uri->transport_param = pj_str("loop-dgram");
1101
1102 via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
1103 via->branch_param = pj_str(TEST9_BRANCH_ID);
1104
1105 status = pjsip_endpt_send_request_stateless(endpt, tdata,
1106 NULL, NULL);
1107 if (status != PJ_SUCCESS) {
1108 app_perror(" error: unable to send ACK", status);
1109 test_complete = -154;
1110 }
1111
1112 } else {
1113 PJ_LOG(3,(THIS_FILE," error: too many responses (%d)",
1114 recv_count));
1115 test_complete = -155;
1116 }
1117
1118 }
1119 return PJ_TRUE;
1120
1121 } else if (pj_stricmp2(&branch_param, TEST10_BRANCH_ID) == 0 ||
1122 pj_stricmp2(&branch_param, TEST11_BRANCH_ID) == 0 ||
1123 pj_stricmp2(&branch_param, TEST12_BRANCH_ID) == 0)
1124 {
1125 int test_num, code1, code2;
1126
1127 if (pj_stricmp2(&branch_param, TEST10_BRANCH_ID) == 0)
1128 test_num=10, code1 = 100, code2 = 0;
1129 else if (pj_stricmp2(&branch_param, TEST11_BRANCH_ID) == 0)
1130 test_num=11, code1 = 100, code2 = 200;
1131 else
1132 test_num=12, code1 = 200, code2 = 0;
1133
1134 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
1135
1136 /* On received response, create UAS. */
1137 pjsip_transaction *tsx;
1138
1139 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
1140 if (status != PJ_SUCCESS) {
1141 app_perror(" error: unable to create transaction", status);
1142 test_complete = -150;
1143 return PJ_TRUE;
1144 }
1145
1146 pjsip_tsx_recv_msg(tsx, rdata);
1147 save_key(tsx);
1148
1149 schedule_send_response(rdata, &tsx_key, code1, 1000);
1150
1151 if (code2)
1152 schedule_send_response(rdata, &tsx_key, code2, 2000);
1153
1154 } else {
1155
1156 }
1157
1158 return PJ_TRUE;
1159 }
1160
1161 return PJ_FALSE;
1162}
1163
1164/*
1165 * The generic test framework, used by most of the tests.
1166 */
1167static int perform_test( char *target_uri, char *from_uri,
1168 char *branch_param, int test_time,
1169 const pjsip_method *method,
1170 int request_cnt, int request_interval_msec,
1171 int expecting_timeout)
1172{
1173 pjsip_tx_data *tdata;
1174 pj_str_t target, from;
1175 pjsip_via_hdr *via;
1176 pj_time_val timeout, next_send;
1177 int sent_cnt;
1178 pj_status_t status;
1179
1180 PJ_LOG(3,(THIS_FILE,
1181 " please standby, this will take at most %d seconds..",
1182 test_time));
1183
1184 /* Reset test. */
1185 recv_count = 0;
1186 test_complete = 0;
1187 tsx_key.slen = 0;
1188
1189 /* Init headers. */
1190 target = pj_str(target_uri);
1191 from = pj_str(from_uri);
1192
1193 /* Create request. */
1194 status = pjsip_endpt_create_request( endpt, method, &target,
1195 &from, &target, NULL, NULL, -1,
1196 NULL, &tdata);
1197 if (status != PJ_SUCCESS) {
1198 app_perror(" Error: unable to create request", status);
1199 return -10;
1200 }
1201
1202 /* Set the branch param for test 1. */
1203 via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
1204 via->branch_param = pj_str(branch_param);
1205
1206 /* Schedule first send. */
1207 sent_cnt = 0;
1208 pj_gettimeofday(&next_send);
1209 pj_time_val_normalize(&next_send);
1210
1211 /* Set test completion time. */
1212 pj_gettimeofday(&timeout);
1213 timeout.sec += test_time;
1214
1215 /* Wait until test complete. */
1216 while (!test_complete) {
1217 pj_time_val now, poll_delay = {0, 10};
1218
1219 pjsip_endpt_handle_events(endpt, &poll_delay);
1220
1221 pj_gettimeofday(&now);
1222
1223 if (sent_cnt < request_cnt && PJ_TIME_VAL_GTE(now, next_send)) {
1224 /* Add additional reference to tdata to prevent transaction from
1225 * deleting it.
1226 */
1227 pjsip_tx_data_add_ref(tdata);
1228
1229 /* (Re)Send the request. */
1230 PJ_LOG(4,(THIS_FILE, " (re)sending request %d", sent_cnt));
1231
1232 status = pjsip_endpt_send_request_stateless(endpt, tdata, 0, 0);
1233 if (status != PJ_SUCCESS) {
1234 app_perror(" Error: unable to send request", status);
1235 pjsip_tx_data_dec_ref(tdata);
1236 return -20;
1237 }
1238
1239 /* Schedule next send, if any. */
1240 sent_cnt++;
1241 if (sent_cnt < request_cnt) {
1242 pj_gettimeofday(&next_send);
1243 next_send.msec += request_interval_msec;
1244 pj_time_val_normalize(&next_send);
1245 }
1246 }
1247
1248 if (now.sec > timeout.sec) {
1249 if (!expecting_timeout)
1250 PJ_LOG(3,(THIS_FILE, " Error: test has timed out"));
1251 pjsip_tx_data_dec_ref(tdata);
1252 return TEST_TIMEOUT_ERROR;
1253 }
1254 }
1255
1256 if (test_complete < 0) {
1257 pjsip_transaction *tsx;
1258
1259 tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
1260 if (tsx) {
1261 pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);
1262 pj_grp_lock_release(tsx->grp_lock);
1263 flush_events(1000);
1264 }
1265 pjsip_tx_data_dec_ref(tdata);
1266 return test_complete;
1267 }
1268
1269 /* Allow transaction to destroy itself */
1270 flush_events(500);
1271
1272 /* Make sure transaction has been destroyed. */
1273 if (pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE) != NULL) {
1274 PJ_LOG(3,(THIS_FILE, " Error: transaction has not been destroyed"));
1275 pjsip_tx_data_dec_ref(tdata);
1276 return -40;
1277 }
1278
1279 /* Check tdata reference counter. */
1280 if (pj_atomic_get(tdata->ref_cnt) != 1) {
1281 PJ_LOG(3,(THIS_FILE, " Error: tdata reference counter is %d",
1282 pj_atomic_get(tdata->ref_cnt)));
1283 pjsip_tx_data_dec_ref(tdata);
1284 return -50;
1285 }
1286
1287 /* Destroy txdata */
1288 pjsip_tx_data_dec_ref(tdata);
1289
1290 return PJ_SUCCESS;
1291
1292}
1293
1294
1295/*****************************************************************************
1296 **
1297 ** TEST1_BRANCH_ID: Basic 2xx final response
1298 ** TEST2_BRANCH_ID: Basic non-2xx final response
1299 **
1300 *****************************************************************************
1301 */
1302static int tsx_basic_final_response_test(void)
1303{
1304 unsigned duration;
1305 int status;
1306
1307 PJ_LOG(3,(THIS_FILE," test1: basic sending 2xx final response"));
1308
1309 /* Test duration must be greater than 32 secs if unreliable transport
1310 * is used.
1311 */
1312 duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
1313
1314 status = perform_test(TARGET_URI, FROM_URI, TEST1_BRANCH_ID,
1315 duration, &pjsip_options_method, 1, 0, 0);
1316 if (status != 0)
1317 return status;
1318
1319 PJ_LOG(3,(THIS_FILE," test2: basic sending non-2xx final response"));
1320
1321 status = perform_test(TARGET_URI, FROM_URI, TEST2_BRANCH_ID,
1322 duration, &pjsip_options_method, 1, 0, 0);
1323 if (status != 0)
1324 return status;
1325
1326 return 0;
1327}
1328
1329
1330/*****************************************************************************
1331 **
1332 ** TEST3_BRANCH_ID: Sending provisional response
1333 **
1334 *****************************************************************************
1335 */
1336static int tsx_basic_provisional_response_test(void)
1337{
1338 unsigned duration;
1339 int status;
1340
1341 PJ_LOG(3,(THIS_FILE," test3: basic sending 2xx final response"));
1342
1343 duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
1344 duration += 2;
1345
1346 status = perform_test(TARGET_URI, FROM_URI, TEST3_BRANCH_ID, duration,
1347 &pjsip_options_method, 1, 0, 0);
1348
1349 return status;
1350}
1351
1352
1353/*****************************************************************************
1354 **
1355 ** TEST4_BRANCH_ID: Absorbs retransmissions in TRYING state
1356 ** TEST5_BRANCH_ID: Absorbs retransmissions in PROCEEDING state
1357 ** TEST6_BRANCH_ID: Absorbs retransmissions in COMPLETED state
1358 **
1359 *****************************************************************************
1360 */
1361static int tsx_retransmit_last_response_test(const char *title,
1362 char *branch_id,
1363 int request_cnt,
1364 int status_code)
1365{
1366 int status;
1367
1368 PJ_LOG(3,(THIS_FILE," %s", title));
1369
1370 status = perform_test(TARGET_URI, FROM_URI, branch_id, 5,
1371 &pjsip_options_method,
1372 request_cnt, 1000, 1);
1373 if (status && status != TEST_TIMEOUT_ERROR)
1374 return status;
1375 if (!status) {
1376 PJ_LOG(3,(THIS_FILE, " error: expecting timeout"));
1377 return -31;
1378 }
1379
1380 terminate_our_tsx(status_code);
1381 flush_events(100);
1382
1383 if (test_complete != 1)
1384 return test_complete;
1385
1386 flush_events(100);
1387 return 0;
1388}
1389
1390/*****************************************************************************
1391 **
1392 ** TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
1393 ** TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
1394 **
1395 *****************************************************************************
1396 */
1397static int tsx_final_response_retransmission_test(void)
1398{
1399 int status;
1400
1401 PJ_LOG(3,(THIS_FILE,
1402 " test7: INVITE non-2xx final response retransmission"));
1403
1404 status = perform_test(TARGET_URI, FROM_URI, TEST7_BRANCH_ID,
1405 33, /* Test duration must be greater than 32 secs */
1406 &pjsip_invite_method, 1, 0, 0);
1407 if (status != 0)
1408 return status;
1409
1410 PJ_LOG(3,(THIS_FILE,
1411 " test8: INVITE 2xx final response retransmission"));
1412
1413 status = perform_test(TARGET_URI, FROM_URI, TEST8_BRANCH_ID,
1414 33, /* Test duration must be greater than 32 secs */
1415 &pjsip_invite_method, 1, 0, 0);
1416 if (status != 0)
1417 return status;
1418
1419 return 0;
1420}
1421
1422
1423/*****************************************************************************
1424 **
1425 ** TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
1426 ** cease when ACK is received
1427 **
1428 *****************************************************************************
1429 */
1430static int tsx_ack_test(void)
1431{
1432 int status;
1433
1434 PJ_LOG(3,(THIS_FILE,
1435 " test9: receiving ACK for non-2xx final response"));
1436
1437 status = perform_test(TARGET_URI, FROM_URI, TEST9_BRANCH_ID,
1438 20, /* allow 5 retransmissions */
1439 &pjsip_invite_method, 1, 0, 0);
1440 if (status != 0)
1441 return status;
1442
1443
1444 return 0;
1445}
1446
1447
1448
1449/*****************************************************************************
1450 **
1451 ** TEST10_BRANCH_ID: test transport failure in TRYING state.
1452 ** TEST11_BRANCH_ID: test transport failure in PROCEEDING state.
1453 ** TEST12_BRANCH_ID: test transport failure in CONNECTED state.
1454 ** TEST13_BRANCH_ID: test transport failure in CONFIRMED state.
1455 **
1456 *****************************************************************************
1457 */
1458static int tsx_transport_failure_test(void)
1459{
1460 struct test_desc
1461 {
1462 int transport_delay;
1463 int fail_delay;
1464 char *branch_id;
1465 char *title;
1466 } tests[] =
1467 {
1468 { 0, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (no delay)" },
1469 { 50, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (50 ms delay)" },
1470 { 0, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (no delay)" },
1471 { 50, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (50 ms delay)" },
1472 { 0, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (no delay)" },
1473 { 50, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (50 ms delay)" },
1474 };
1475 int i, status;
1476
1477 for (i=0; i<(int)PJ_ARRAY_SIZE(tests); ++i) {
1478 pj_time_val fail_time, end_test, now;
1479
1480 PJ_LOG(3,(THIS_FILE, " %s", tests[i].title));
1481 pjsip_loop_set_failure(loop, 0, NULL);
1482 pjsip_loop_set_delay(loop, tests[i].transport_delay);
1483
1484 status = perform_test(TARGET_URI, FROM_URI, tests[i].branch_id,
1485 0, &pjsip_invite_method, 1, 0, 1);
1486 if (status && status != TEST_TIMEOUT_ERROR)
1487 return status;
1488 if (!status) {
1489 PJ_LOG(3,(THIS_FILE, " error: expecting timeout"));
1490 return -40;
1491 }
1492
1493 pj_gettimeofday(&fail_time);
1494 fail_time.msec += tests[i].fail_delay;
1495 pj_time_val_normalize(&fail_time);
1496
1497 do {
1498 pj_time_val interval = { 0, 1 };
1499 pj_gettimeofday(&now);
1500 pjsip_endpt_handle_events(endpt, &interval);
1501 } while (PJ_TIME_VAL_LT(now, fail_time));
1502
1503 pjsip_loop_set_failure(loop, 1, NULL);
1504
1505 end_test = now;
1506 end_test.sec += 5;
1507
1508 do {
1509 pj_time_val interval = { 0, 1 };
1510 pj_gettimeofday(&now);
1511 pjsip_endpt_handle_events(endpt, &interval);
1512 } while (!test_complete && PJ_TIME_VAL_LT(now, end_test));
1513
1514 if (test_complete == 0) {
1515 PJ_LOG(3,(THIS_FILE, " error: test has timed out"));
1516 return -41;
1517 }
1518
1519 if (test_complete != 1)
1520 return test_complete;
1521 }
1522
1523 return 0;
1524}
1525
1526/*****************************************************************************
1527 **
1528 ** UAS Transaction Test.
1529 **
1530 *****************************************************************************
1531 */
1532int tsx_uas_test(struct tsx_test_param *param)
1533{
1534 pj_sockaddr_in addr;
1535 pj_status_t status;
1536
1537 test_param = param;
1538 tp_flag = pjsip_transport_get_flag_from_type((pjsip_transport_type_e)param->type);
1539
1540 pj_ansi_sprintf(TARGET_URI, "sip:bob@127.0.0.1:%d;transport=%s",
1541 param->port, param->tp_type);
1542 pj_ansi_sprintf(FROM_URI, "sip:alice@127.0.0.1:%d;transport=%s",
1543 param->port, param->tp_type);
1544
1545 /* Check if loop transport is configured. */
1546 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
1547 &addr, sizeof(addr), NULL, &loop);
1548 if (status != PJ_SUCCESS) {
1549 PJ_LOG(3,(THIS_FILE, " Error: loop transport is not configured!"));
1550 return -10;
1551 }
1552 /* Register modules. */
1553 status = pjsip_endpt_register_module(endpt, &tsx_user);
1554 if (status != PJ_SUCCESS) {
1555 app_perror(" Error: unable to register module", status);
1556 return -3;
1557 }
1558 status = pjsip_endpt_register_module(endpt, &msg_sender);
1559 if (status != PJ_SUCCESS) {
1560 app_perror(" Error: unable to register module", status);
1561 return -4;
1562 }
1563
1564 /* TEST1_BRANCH_ID: Basic 2xx final response.
1565 * TEST2_BRANCH_ID: Basic non-2xx final response.
1566 */
1567 status = tsx_basic_final_response_test();
1568 if (status != 0)
1569 return status;
1570
1571 /* TEST3_BRANCH_ID: with provisional response
1572 */
1573 status = tsx_basic_provisional_response_test();
1574 if (status != 0)
1575 return status;
1576
1577 /* TEST4_BRANCH_ID: absorbs retransmissions in TRYING state
1578 */
1579 status = tsx_retransmit_last_response_test(TEST4_TITLE,
1580 TEST4_BRANCH_ID,
1581 TEST4_REQUEST_COUNT,
1582 TEST4_STATUS_CODE);
1583 if (status != 0)
1584 return status;
1585
1586 /* TEST5_BRANCH_ID: retransmit last response in PROCEEDING state
1587 */
1588 status = tsx_retransmit_last_response_test(TEST5_TITLE,
1589 TEST5_BRANCH_ID,
1590 TEST5_REQUEST_COUNT,
1591 TEST5_STATUS_CODE);
1592 if (status != 0)
1593 return status;
1594
1595 /* TEST6_BRANCH_ID: retransmit last response in COMPLETED state
1596 * This only applies to non-reliable transports,
1597 * since UAS transaction is destroyed as soon
1598 * as final response is sent for reliable transports.
1599 */
1600 if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
1601 status = tsx_retransmit_last_response_test(TEST6_TITLE,
1602 TEST6_BRANCH_ID,
1603 TEST6_REQUEST_COUNT,
1604 TEST6_STATUS_CODE);
1605 if (status != 0)
1606 return status;
1607 }
1608
1609 /* TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
1610 * TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
1611 */
1612 status = tsx_final_response_retransmission_test();
1613 if (status != 0)
1614 return status;
1615
1616 /* TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
1617 * cease when ACK is received
1618 * Only applicable for non-reliable transports.
1619 */
1620 if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
1621 status = tsx_ack_test();
1622 if (status != 0)
1623 return status;
1624 }
1625
1626
1627 /* TEST10_BRANCH_ID: test transport failure in TRYING state.
1628 * TEST11_BRANCH_ID: test transport failure in PROCEEDING state.
1629 * TEST12_BRANCH_ID: test transport failure in CONNECTED state.
1630 * TEST13_BRANCH_ID: test transport failure in CONFIRMED state.
1631 */
1632 /* Only valid for loop-dgram */
1633 if (param->type == PJSIP_TRANSPORT_LOOP_DGRAM) {
1634 status = tsx_transport_failure_test();
1635 if (status != 0)
1636 return status;
1637 }
1638
1639
1640 /* Register modules. */
1641 status = pjsip_endpt_unregister_module(endpt, &tsx_user);
1642 if (status != PJ_SUCCESS) {
1643 app_perror(" Error: unable to unregister module", status);
1644 return -8;
1645 }
1646 status = pjsip_endpt_unregister_module(endpt, &msg_sender);
1647 if (status != PJ_SUCCESS) {
1648 app_perror(" Error: unable to unregister module", status);
1649 return -9;
1650 }
1651
1652
1653 if (loop)
1654 pjsip_transport_dec_ref(loop);
1655
1656 return 0;
1657}
1658