blob: 973f3315af9e78a454eebee146c1228d9037f7ac [file] [log] [blame]
Benny Prijonodbe337a2006-01-08 23:57:52 +00001/* $Id$ */
2/*
Nanang Izzuddina62ffc92011-05-05 06:14:19 +00003 * Copyright (C) 2008-2011 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
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +000098#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")
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
Nanang Izzuddin2e4f03f2009-04-27 19:18:38 +0000215 PJ_UNUSED_ARG(timer_heap);
216
Benny Prijonodbe337a2006-01-08 23:57:52 +0000217 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) {
Benny Prijono728a9052006-01-18 23:34:15 +0000226 // Some tests do expect failure!
227 //PJ_LOG(3,(THIS_FILE," error: timer unable to send response"));
228 pj_mutex_unlock(tsx->mutex);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000229 pjsip_tx_data_dec_ref(r->tdata);
230 return;
231 }
Benny Prijono728a9052006-01-18 23:34:15 +0000232
233 pj_mutex_unlock(tsx->mutex);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000234}
235
Benny Prijono0c2bc612006-01-10 13:31:40 +0000236/* 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) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000254 pjsip_tx_data_dec_ref(tdata);
Benny Prijono728a9052006-01-18 23:34:15 +0000255 // Some tests do expect failure!
256 //app_perror(" error: unable to send response", status);
257 //test_complete = -197;
Benny Prijono0c2bc612006-01-10 13:31:40 +0000258 return;
259 }
260}
261
Benny Prijonodbe337a2006-01-08 23:57:52 +0000262/* 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;
Benny Prijono728a9052006-01-18 23:34:15 +0000270 pj_timer_entry *t;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000271 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
Benny Prijonoa1e69682007-05-11 15:14:34 +0000282 r = PJ_POOL_ALLOC_T(tdata->pool, struct response);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000283 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
Benny Prijonoa1e69682007-05-11 15:14:34 +0000290 t = PJ_POOL_ZALLOC_T(tdata->pool, pj_timer_entry);
Benny Prijono728a9052006-01-18 23:34:15 +0000291 t->user_data = r;
292 t->cb = &send_response_timer;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000293
Benny Prijono728a9052006-01-18 23:34:15 +0000294 status = pjsip_endpt_schedule_timer(endpt, t, &delay);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000295 if (status != PJ_SUCCESS) {
Benny Prijono728a9052006-01-18 23:34:15 +0000296 pjsip_tx_data_dec_ref(tdata);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000297 app_perror(" error: unable to schedule timer", status);
298 test_complete = -199;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000299 return;
300 }
301}
302
Benny Prijono0c2bc612006-01-10 13:31:40 +0000303
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_mutex_unlock(tsx->mutex);
317}
318
Benny Prijonobc331ca2006-09-19 13:32:05 +0000319#if 0 /* Unused for now */
Benny Prijono0c2bc612006-01-10 13:31:40 +0000320/* 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}
Benny Prijonobc331ca2006-09-19 13:32:05 +0000345#endif
Benny Prijono0c2bc612006-01-10 13:31:40 +0000346
347
Benny Prijonodbe337a2006-01-08 23:57:52 +0000348/*
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{
Sauw Ming969227c2012-07-18 07:52:33 +0000355 if (pj_stricmp2(&tsx->branch, TEST1_BRANCH_ID)==0 ||
356 pj_stricmp2(&tsx->branch, TEST2_BRANCH_ID)==0)
Benny Prijonodbe337a2006-01-08 23:57:52 +0000357 {
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 */
Sauw Ming969227c2012-07-18 07:52:33 +0000365 int status_code = (pj_stricmp2(&tsx->branch, TEST1_BRANCH_ID)==0) ?
Benny Prijonodbe337a2006-01-08 23:57:52 +0000366 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
Sauw Ming969227c2012-07-18 07:52:33 +0000395 if (pj_stricmp2(&tsx->branch, TEST3_BRANCH_ID)==0) {
Benny Prijonodbe337a2006-01-08 23:57:52 +0000396 /*
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
Benny Prijono0c2bc612006-01-10 13:31:40 +0000457 } else
Sauw Ming969227c2012-07-18 07:52:33 +0000458 if (pj_stricmp2(&tsx->branch, TEST4_BRANCH_ID)==0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000459 /*
460 * TEST4_BRANCH_ID tests receiving retransmissions in TRYING state.
461 */
Benny Prijono02b8fd82006-06-26 15:12:55 +0000462 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
463 /* Request is received. */
464 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000465
466 /* Check that status code is status_code. */
467 if (tsx->status_code != TEST4_STATUS_CODE) {
Benny Prijono02b8fd82006-06-26 15:12:55 +0000468 PJ_LOG(3,(THIS_FILE,
469 " error: incorrect status code %d "
470 "(expecting %d)", tsx->status_code,
471 TEST4_STATUS_CODE));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000472 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 {
Benny Prijono02b8fd82006-06-26 15:12:55 +0000483 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (122)",
484 pjsip_tsx_state_str(tsx->state)));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000485 test_complete = -122;
486
487 }
488
489
490 } else
Sauw Ming969227c2012-07-18 07:52:33 +0000491 if (pj_stricmp2(&tsx->branch, TEST5_BRANCH_ID)==0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000492 /*
493 * TEST5_BRANCH_ID tests receiving retransmissions in PROCEEDING state
494 */
Benny Prijono02b8fd82006-06-26 15:12:55 +0000495 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
496 /* Request is received. */
497
498 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000499
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) {
Benny Prijono02b8fd82006-06-26 15:12:55 +0000521 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (133)",
522 pjsip_tsx_state_str(tsx->state)));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000523 test_complete = -133;
524
525 }
526
527 } else
Sauw Ming969227c2012-07-18 07:52:33 +0000528 if (pj_stricmp2(&tsx->branch, TEST6_BRANCH_ID)==0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000529 /*
530 * TEST6_BRANCH_ID tests receiving retransmissions in COMPLETED state
531 */
Benny Prijono02b8fd82006-06-26 15:12:55 +0000532 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
533 /* Request is received. */
534
535 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000536
537 /* Check that status code is status_code. */
538 if (tsx->status_code != TEST6_STATUS_CODE) {
Benny Prijonoe93e2872006-06-28 16:46:49 +0000539 PJ_LOG(3,(THIS_FILE, " error: incorrect status code %d "
540 "(expecting %d)", tsx->status_code,
541 TEST6_STATUS_CODE));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000542 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 {
Benny Prijono02b8fd82006-06-26 15:12:55 +0000555 PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (142)",
556 pjsip_tsx_state_str(tsx->state)));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000557 test_complete = -142;
558
559 }
560
561
562 } else
Sauw Ming969227c2012-07-18 07:52:33 +0000563 if (pj_stricmp2(&tsx->branch, TEST7_BRANCH_ID)==0 ||
564 pj_stricmp2(&tsx->branch, TEST8_BRANCH_ID)==0)
Benny Prijono0c2bc612006-01-10 13:31:40 +0000565 {
566 /*
567 * TEST7_BRANCH_ID and TEST8_BRANCH_ID test retransmission of
568 * INVITE final response
569 */
570 int code;
571
Sauw Ming969227c2012-07-18 07:52:33 +0000572 if (pj_stricmp2(&tsx->branch, TEST7_BRANCH_ID) == 0)
Benny Prijono0c2bc612006-01-10 13:31:40 +0000573 code = TEST7_STATUS_CODE;
574 else
575 code = TEST8_STATUS_CODE;
576
Benny Prijono02b8fd82006-06-26 15:12:55 +0000577 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
578 /* Request is received. */
579
580 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000581
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
Benny Prijonoe93e2872006-06-28 16:46:49 +0000597 /* 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
Benny Prijono0c2bc612006-01-10 13:31:40 +0000617 } 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
Benny Prijono02b8fd82006-06-26 15:12:55 +0000633 PJ_LOG(3,(THIS_FILE, " error: unexpected state (154)"));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000634 test_complete = -154;
635
636 }
637
Benny Prijono728a9052006-01-18 23:34:15 +0000638
639 } else
Sauw Ming969227c2012-07-18 07:52:33 +0000640 if (pj_stricmp2(&tsx->branch, TEST9_BRANCH_ID)==0) {
Benny Prijono728a9052006-01-18 23:34:15 +0000641 /*
642 * TEST9_BRANCH_ID tests that retransmission of INVITE final response
643 * must cease when ACK is received.
644 */
645
Benny Prijono02b8fd82006-06-26 15:12:55 +0000646 if (tsx->state == PJSIP_TSX_STATE_TRYING) {
647 /* Request is received. */
648
649 } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
Benny Prijono728a9052006-01-18 23:34:15 +0000650
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
Benny Prijono02b8fd82006-06-26 15:12:55 +0000697 PJ_LOG(3,(THIS_FILE, " error: unexpected state (166)"));
Benny Prijono728a9052006-01-18 23:34:15 +0000698 test_complete = -166;
699
700 }
701
702
703 } else
Sauw Ming969227c2012-07-18 07:52:33 +0000704 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)
Benny Prijono728a9052006-01-18 23:34:15 +0000707 {
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 }
Benny Prijonodbe337a2006-01-08 23:57:52 +0000718 }
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
Benny Prijono0c2bc612006-01-10 13:31:40 +0000731#define DIFF(a,b) ((a<b) ? (b-a) : (a-b))
732
Benny Prijonodbe337a2006-01-08 23:57:52 +0000733/*
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
Sauw Ming969227c2012-07-18 07:52:33 +0000742 if (pj_stricmp2(&branch_param, TEST1_BRANCH_ID) == 0 ||
743 pj_stricmp2(&branch_param, TEST2_BRANCH_ID) == 0)
Benny Prijonodbe337a2006-01-08 23:57:52 +0000744 {
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 */
Sauw Ming969227c2012-07-18 07:52:33 +0000752 int status_code = (pj_stricmp2(&branch_param, TEST1_BRANCH_ID) == 0) ?
Benny Prijonodbe337a2006-01-08 23:57:52 +0000753 TEST1_STATUS_CODE : TEST2_STATUS_CODE;
754
755 if (msg->type == PJSIP_REQUEST_MSG) {
Benny Prijono728a9052006-01-18 23:34:15 +0000756 /* On received request, create UAS and respond with final
Benny Prijonodbe337a2006-01-08 23:57:52 +0000757 * response.
758 */
759 pjsip_transaction *tsx;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000760
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 }
Benny Prijono38998232006-02-08 22:44:25 +0000767 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000768
769 save_key(tsx);
Benny Prijono0c2bc612006-01-10 13:31:40 +0000770 send_response(rdata, tsx, status_code);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000771
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
Sauw Ming969227c2012-07-18 07:52:33 +0000792 } else if (pj_stricmp2(&branch_param, TEST3_BRANCH_ID) == 0) {
Benny Prijonodbe337a2006-01-08 23:57:52 +0000793
794 /* TEST3_BRANCH_ID tests provisional response. */
795
796 if (msg->type == PJSIP_REQUEST_MSG) {
Benny Prijono728a9052006-01-18 23:34:15 +0000797 /* On received request, create UAS and respond with provisional
Benny Prijonodbe337a2006-01-08 23:57:52 +0000798 * response, then schedule timer to send final response.
799 */
800 pjsip_transaction *tsx;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000801
802 status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
803 if (status != PJ_SUCCESS) {
804 app_perror(" error: unable to create transaction", status);
Benny Prijono02b8fd82006-06-26 15:12:55 +0000805 test_complete = -116;
Benny Prijonodbe337a2006-01-08 23:57:52 +0000806 return PJ_TRUE;
807 }
Benny Prijono38998232006-02-08 22:44:25 +0000808 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000809
810 save_key(tsx);
811
Benny Prijono0c2bc612006-01-10 13:31:40 +0000812 send_response(rdata, tsx, TEST3_PROVISIONAL_CODE);
Benny Prijonodbe337a2006-01-08 23:57:52 +0000813 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
Sauw Ming969227c2012-07-18 07:52:33 +0000841 } 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)
Benny Prijono0c2bc612006-01-10 13:31:40 +0000844 {
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) {
Benny Prijono728a9052006-01-18 23:34:15 +0000851 /* On received request, create UAS. */
Benny Prijono0c2bc612006-01-10 13:31:40 +0000852 pjsip_transaction *tsx;
853
Benny Prijonoe93e2872006-06-28 16:46:49 +0000854 PJ_LOG(4,(THIS_FILE, " received request (probably retransmission)"));
855
Benny Prijono0c2bc612006-01-10 13:31:40 +0000856 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
Benny Prijono38998232006-02-08 22:44:25 +0000863 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijono0c2bc612006-01-10 13:31:40 +0000864 save_key(tsx);
865
Sauw Ming969227c2012-07-18 07:52:33 +0000866 if (pj_stricmp2(&branch_param, TEST4_BRANCH_ID) == 0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000867
Sauw Ming969227c2012-07-18 07:52:33 +0000868 } else if (pj_stricmp2(&branch_param, TEST5_BRANCH_ID) == 0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000869 send_response(rdata, tsx, TEST5_PROVISIONAL_CODE);
870
Sauw Ming969227c2012-07-18 07:52:33 +0000871 } else if (pj_stricmp2(&branch_param, TEST6_BRANCH_ID) == 0) {
Benny Prijonoe93e2872006-06-28 16:46:49 +0000872 PJ_LOG(4,(THIS_FILE, " sending provisional response"));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000873 send_response(rdata, tsx, TEST6_PROVISIONAL_CODE);
Benny Prijonoe93e2872006-06-28 16:46:49 +0000874 PJ_LOG(4,(THIS_FILE, " sending final response"));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000875 send_response(rdata, tsx, TEST6_STATUS_CODE);
876 }
877
878 } else {
879 /* Verify the response received. */
880
Benny Prijonoe93e2872006-06-28 16:46:49 +0000881 PJ_LOG(4,(THIS_FILE, " received response number %d", recv_count));
882
Benny Prijono0c2bc612006-01-10 13:31:40 +0000883 ++recv_count;
884
Sauw Ming969227c2012-07-18 07:52:33 +0000885 if (pj_stricmp2(&branch_param, TEST4_BRANCH_ID) == 0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000886 PJ_LOG(3,(THIS_FILE, " error: not expecting response!"));
887 test_complete = -132;
888
Sauw Ming969227c2012-07-18 07:52:33 +0000889 } else if (pj_stricmp2(&branch_param, TEST5_BRANCH_ID) == 0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000890
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
Sauw Ming969227c2012-07-18 07:52:33 +0000901 } else if (pj_stricmp2(&branch_param, TEST6_BRANCH_ID) == 0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000902
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) {
Benny Prijonoe93e2872006-06-28 16:46:49 +0000915 PJ_LOG(3,(THIS_FILE, " error: invalid code %d "
916 "(expecting %d)", code, TEST6_STATUS_CODE));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000917 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
Sauw Ming969227c2012-07-18 07:52:33 +0000930 } else if (pj_stricmp2(&branch_param, TEST7_BRANCH_ID) == 0 ||
931 pj_stricmp2(&branch_param, TEST8_BRANCH_ID) == 0)
Benny Prijono0c2bc612006-01-10 13:31:40 +0000932 {
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
Benny Prijono728a9052006-01-18 23:34:15 +0000940 /* On received request, create UAS. */
Benny Prijono0c2bc612006-01-10 13:31:40 +0000941 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
Benny Prijono38998232006-02-08 22:44:25 +0000950 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijono0c2bc612006-01-10 13:31:40 +0000951 save_key(tsx);
952
Sauw Ming969227c2012-07-18 07:52:33 +0000953 if (pj_stricmp2(&branch_param, TEST7_BRANCH_ID) == 0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +0000954
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
Sauw Ming969227c2012-07-18 07:52:33 +0000968 if (pj_stricmp2(&branch_param, TEST7_BRANCH_ID) == 0)
Benny Prijono0c2bc612006-01-10 13:31:40 +0000969 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;
Benny Prijono4768c3c2008-02-22 11:10:17 +0000992 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;
Benny Prijono0c2bc612006-01-10 13:31:40 +0000995
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
Sauw Ming969227c2012-07-18 07:52:33 +00001016 } else if (pj_stricmp2(&branch_param, TEST9_BRANCH_ID) == 0) {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001017
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
Benny Prijono728a9052006-01-18 23:34:15 +00001025 /* On received request, create UAS. */
Benny Prijono0c2bc612006-01-10 13:31:40 +00001026 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);
Benny Prijono728a9052006-01-18 23:34:15 +00001031 test_complete = -150;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001032 return PJ_TRUE;
1033 }
1034
Benny Prijono38998232006-02-08 22:44:25 +00001035 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijono0c2bc612006-01-10 13:31:40 +00001036 save_key(tsx);
Benny Prijono728a9052006-01-18 23:34:15 +00001037 send_response(rdata, tsx, TEST9_STATUS_CODE);
Benny Prijono0c2bc612006-01-10 13:31:40 +00001038
Benny Prijono0c2bc612006-01-10 13:31:40 +00001039
1040 } else {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001041
1042 ++recv_count;
1043
Benny Prijono728a9052006-01-18 23:34:15 +00001044 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 }
Benny Prijono0c2bc612006-01-10 13:31:40 +00001048
1049 if (recv_count==1) {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001050
1051 recv_last = rdata->pkt_info.timestamp;
1052
Benny Prijono728a9052006-01-18 23:34:15 +00001053 } else if (recv_count < 5) {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001054
Benny Prijono728a9052006-01-18 23:34:15 +00001055 /* Let UAS retransmit some messages before we send ACK. */
Benny Prijono0c2bc612006-01-10 13:31:40 +00001056 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;
Benny Prijono4768c3c2008-02-22 11:10:17 +00001064 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;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001067
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));
Benny Prijono728a9052006-01-18 23:34:15 +00001073 test_complete = -152;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001074 }
1075
1076 recv_last = rdata->pkt_info.timestamp;
Benny Prijono728a9052006-01-18 23:34:15 +00001077
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
Benny Prijonoa1e69682007-05-11 15:14:34 +00001102 via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
Benny Prijono728a9052006-01-18 23:34:15 +00001103 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;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001116 }
1117
1118 }
1119 return PJ_TRUE;
Benny Prijono728a9052006-01-18 23:34:15 +00001120
Sauw Ming969227c2012-07-18 07:52:33 +00001121 } 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)
Benny Prijono728a9052006-01-18 23:34:15 +00001124 {
1125 int test_num, code1, code2;
1126
Sauw Ming969227c2012-07-18 07:52:33 +00001127 if (pj_stricmp2(&branch_param, TEST10_BRANCH_ID) == 0)
Benny Prijono728a9052006-01-18 23:34:15 +00001128 test_num=10, code1 = 100, code2 = 0;
Sauw Ming969227c2012-07-18 07:52:33 +00001129 else if (pj_stricmp2(&branch_param, TEST11_BRANCH_ID) == 0)
Benny Prijono728a9052006-01-18 23:34:15 +00001130 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
Benny Prijono38998232006-02-08 22:44:25 +00001146 pjsip_tsx_recv_msg(tsx, rdata);
Benny Prijono728a9052006-01-18 23:34:15 +00001147 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;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001159 }
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,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001169 const pjsip_method *method,
1170 int request_cnt, int request_interval_msec,
1171 int expecting_timeout)
Benny Prijonodbe337a2006-01-08 23:57:52 +00001172{
1173 pjsip_tx_data *tdata;
1174 pj_str_t target, from;
1175 pjsip_via_hdr *via;
Benny Prijono0c2bc612006-01-10 13:31:40 +00001176 pj_time_val timeout, next_send;
1177 int sent_cnt;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001178 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. */
Benny Prijonoa1e69682007-05-11 15:14:34 +00001203 via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001204 via->branch_param = pj_str(branch_param);
1205
Benny Prijono0c2bc612006-01-10 13:31:40 +00001206 /* Schedule first send. */
1207 sent_cnt = 0;
1208 pj_gettimeofday(&next_send);
1209 pj_time_val_normalize(&next_send);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001210
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);
Benny Prijono0c2bc612006-01-10 13:31:40 +00001222
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. */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001230 PJ_LOG(4,(THIS_FILE, " (re)sending request %d", sent_cnt));
1231
Benny Prijono0c2bc612006-01-10 13:31:40 +00001232 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
Benny Prijonodbe337a2006-01-08 23:57:52 +00001248 if (now.sec > timeout.sec) {
Benny Prijono0c2bc612006-01-10 13:31:40 +00001249 if (!expecting_timeout)
1250 PJ_LOG(3,(THIS_FILE, " Error: test has timed out"));
Benny Prijonodbe337a2006-01-08 23:57:52 +00001251 pjsip_tx_data_dec_ref(tdata);
Benny Prijono0c2bc612006-01-10 13:31:40 +00001252 return TEST_TIMEOUT_ERROR;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001253 }
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_mutex_unlock(tsx->mutex);
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{
Benny Prijonoe93e2872006-06-28 16:46:49 +00001304 unsigned duration;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001305 int status;
1306
1307 PJ_LOG(3,(THIS_FILE," test1: basic sending 2xx final response"));
1308
Benny Prijonoe93e2872006-06-28 16:46:49 +00001309 /* 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);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001316 if (status != 0)
1317 return status;
1318
1319 PJ_LOG(3,(THIS_FILE," test2: basic sending non-2xx final response"));
1320
Benny Prijonoe93e2872006-06-28 16:46:49 +00001321 status = perform_test(TARGET_URI, FROM_URI, TEST2_BRANCH_ID,
1322 duration, &pjsip_options_method, 1, 0, 0);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001323 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{
Benny Prijonoe93e2872006-06-28 16:46:49 +00001338 unsigned duration;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001339 int status;
1340
Benny Prijono02b8fd82006-06-26 15:12:55 +00001341 PJ_LOG(3,(THIS_FILE," test3: basic sending 2xx final response"));
Benny Prijonodbe337a2006-01-08 23:57:52 +00001342
Benny Prijonoe93e2872006-06-28 16:46:49 +00001343 duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
1344 duration += 2;
1345
1346 status = perform_test(TARGET_URI, FROM_URI, TEST3_BRANCH_ID, duration,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001347 &pjsip_options_method, 1, 0, 0);
1348
Benny Prijonodbe337a2006-01-08 23:57:52 +00001349 return status;
1350}
1351
1352
1353/*****************************************************************************
1354 **
Benny Prijono0c2bc612006-01-10 13:31:40 +00001355 ** 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
Benny Prijonoe93e2872006-06-28 16:46:49 +00001370 status = perform_test(TARGET_URI, FROM_URI, branch_id, 5,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001371 &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
Benny Prijonoe93e2872006-06-28 16:46:49 +00001404 status = perform_test(TARGET_URI, FROM_URI, TEST7_BRANCH_ID,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001405 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
Benny Prijonoe93e2872006-06-28 16:46:49 +00001413 status = perform_test(TARGET_URI, FROM_URI, TEST8_BRANCH_ID,
Benny Prijono0c2bc612006-01-10 13:31:40 +00001414 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
Benny Prijono728a9052006-01-18 23:34:15 +00001423/*****************************************************************************
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
Benny Prijonoe93e2872006-06-28 16:46:49 +00001437 status = perform_test(TARGET_URI, FROM_URI, TEST9_BRANCH_ID,
Benny Prijono728a9052006-01-18 23:34:15 +00001438 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
Benny Prijonoa1e69682007-05-11 15:14:34 +00001477 for (i=0; i<(int)PJ_ARRAY_SIZE(tests); ++i) {
Benny Prijono728a9052006-01-18 23:34:15 +00001478 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
Benny Prijonoe93e2872006-06-28 16:46:49 +00001484 status = perform_test(TARGET_URI, FROM_URI, tests[i].branch_id,
1485 0, &pjsip_invite_method, 1, 0, 1);
Benny Prijono728a9052006-01-18 23:34:15 +00001486 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}
Benny Prijono0c2bc612006-01-10 13:31:40 +00001525
1526/*****************************************************************************
1527 **
Benny Prijonodbe337a2006-01-08 23:57:52 +00001528 ** UAS Transaction Test.
1529 **
1530 *****************************************************************************
1531 */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001532int tsx_uas_test(struct tsx_test_param *param)
Benny Prijonodbe337a2006-01-08 23:57:52 +00001533{
1534 pj_sockaddr_in addr;
1535 pj_status_t status;
1536
Benny Prijonoe93e2872006-06-28 16:46:49 +00001537 test_param = param;
Benny Prijonoa1e69682007-05-11 15:14:34 +00001538 tp_flag = pjsip_transport_get_flag_from_type((pjsip_transport_type_e)param->type);
Benny Prijonoe93e2872006-06-28 16:46:49 +00001539
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
Benny Prijonodbe337a2006-01-08 23:57:52 +00001545 /* Check if loop transport is configured. */
1546 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
Benny Prijonodf2b71e2007-01-20 19:17:47 +00001547 &addr, sizeof(addr), NULL, &loop);
Benny Prijonodbe337a2006-01-08 23:57:52 +00001548 if (status != PJ_SUCCESS) {
1549 PJ_LOG(3,(THIS_FILE, " Error: loop transport is not configured!"));
Benny Prijonoe93e2872006-06-28 16:46:49 +00001550 return -10;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001551 }
Benny Prijonodbe337a2006-01-08 23:57:52 +00001552 /* 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
Benny Prijonodbe337a2006-01-08 23:57:52 +00001564 /* 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;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001570
1571 /* TEST3_BRANCH_ID: with provisional response
1572 */
1573 status = tsx_basic_provisional_response_test();
1574 if (status != 0)
1575 return status;
1576
Benny Prijono0c2bc612006-01-10 13:31:40 +00001577 /* 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
Benny Prijonoe93e2872006-06-28 16:46:49 +00001595 /* 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.
Benny Prijono0c2bc612006-01-10 13:31:40 +00001599 */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001600 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 }
Benny Prijono0c2bc612006-01-10 13:31:40 +00001608
1609 /* TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
1610 * TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
1611 */
Benny Prijono0c2bc612006-01-10 13:31:40 +00001612 status = tsx_final_response_retransmission_test();
1613 if (status != 0)
1614 return status;
1615
Benny Prijono728a9052006-01-18 23:34:15 +00001616 /* TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
1617 * cease when ACK is received
Benny Prijonoe93e2872006-06-28 16:46:49 +00001618 * Only applicable for non-reliable transports.
Benny Prijono728a9052006-01-18 23:34:15 +00001619 */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001620 if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
1621 status = tsx_ack_test();
1622 if (status != 0)
1623 return status;
1624 }
1625
Benny Prijono728a9052006-01-18 23:34:15 +00001626
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 */
Benny Prijonoe93e2872006-06-28 16:46:49 +00001632 /* 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 }
Benny Prijono728a9052006-01-18 23:34:15 +00001638
Benny Prijonodbe337a2006-01-08 23:57:52 +00001639
Benny Prijonoe93e2872006-06-28 16:46:49 +00001640 /* 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
Benny Prijonodbe337a2006-01-08 23:57:52 +00001656 return 0;
Benny Prijonodbe337a2006-01-08 23:57:52 +00001657}
1658