~ubuntu-branches/debian/stretch/sflphone/stretch

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.2.1/pjsip/src/test/tsx_uas_test.c

  • Committer: Package Import Robot
  • Author(s): Francois Marier, Francois Marier, Mark Purcell
  • Date: 2014-10-18 15:08:50 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20141018150850-2exfk34ckb15pcwi
Tags: 1.4.1-0.1
[ Francois Marier ]
* Non-maintainer upload
* New upstream release (closes: #759576, #741130)
  - debian/rules +PJPROJECT_VERSION := 2.2.1
  - add upstream patch to fix broken TLS support
  - add patch to fix pjproject regression

[ Mark Purcell ]
* Build-Depends:
  - sflphone-daemon + libavformat-dev, libavcodec-dev, libswscale-dev,
  libavdevice-dev, libavutil-dev
  - sflphone-gnome + libclutter-gtk-1.0-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tsx_uas_test.c 4728 2014-02-04 10:13:56Z bennylp $ */
 
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
 
 
136
static char TARGET_URI[128];
 
137
static char FROM_URI[128];
 
138
static struct tsx_test_param *test_param;
 
139
static unsigned tp_flag;
 
140
 
 
141
 
 
142
#define TEST_TIMEOUT_ERROR      -30
 
143
#define MAX_ALLOWED_DIFF        150
 
144
 
 
145
static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e);
 
146
static pj_bool_t on_rx_message(pjsip_rx_data *rdata);
 
147
 
 
148
/* UAC transaction user module. */
 
149
static 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. */
 
167
static 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. */
 
185
static int recv_count;
 
186
static pj_time_val recv_last;
 
187
static pj_bool_t test_complete;
 
188
 
 
189
/* Loop transport instance. */
 
190
static pjsip_transport *loop;
 
191
 
 
192
/* UAS transaction key. */
 
193
static char key_buf[64];
 
194
static 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. */
 
201
struct response
 
202
{
 
203
    pj_str_t         tsx_key;
 
204
    pjsip_tx_data   *tdata;
 
205
};
 
206
 
 
207
/* Timer callback to send response. */
 
208
static 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. */
 
237
static 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 */
 
263
static 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. */
 
305
static 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. */
 
321
static 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. */
 
329
static 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
 */
 
353
static 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. */
 
723
static 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
 */
 
736
static 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
        PJ_UNUSED_ARG(test_num);
 
1135
 
 
1136
        if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
 
1137
 
 
1138
            /* On received response, create UAS. */
 
1139
            pjsip_transaction *tsx;
 
1140
 
 
1141
            status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx);
 
1142
            if (status != PJ_SUCCESS) {
 
1143
                app_perror("    error: unable to create transaction", status);
 
1144
                test_complete = -150;
 
1145
                return PJ_TRUE;
 
1146
            }
 
1147
 
 
1148
            pjsip_tsx_recv_msg(tsx, rdata);
 
1149
            save_key(tsx);
 
1150
 
 
1151
            schedule_send_response(rdata, &tsx_key, code1, 1000);
 
1152
 
 
1153
            if (code2)
 
1154
                schedule_send_response(rdata, &tsx_key, code2, 2000);
 
1155
 
 
1156
        } else {
 
1157
 
 
1158
        }
 
1159
 
 
1160
        return PJ_TRUE;
 
1161
    }
 
1162
 
 
1163
    return PJ_FALSE;
 
1164
}
 
1165
 
 
1166
/*
 
1167
 * The generic test framework, used by most of the tests.
 
1168
 */
 
1169
static int perform_test( char *target_uri, char *from_uri,
 
1170
                         char *branch_param, int test_time,
 
1171
                         const pjsip_method *method,
 
1172
                         int request_cnt, int request_interval_msec,
 
1173
                         int expecting_timeout)
 
1174
{
 
1175
    pjsip_tx_data *tdata;
 
1176
    pj_str_t target, from;
 
1177
    pjsip_via_hdr *via;
 
1178
    pj_time_val timeout, next_send;
 
1179
    int sent_cnt;
 
1180
    pj_status_t status;
 
1181
 
 
1182
    PJ_LOG(3,(THIS_FILE,
 
1183
              "   please standby, this will take at most %d seconds..",
 
1184
              test_time));
 
1185
 
 
1186
    /* Reset test. */
 
1187
    recv_count = 0;
 
1188
    test_complete = 0;
 
1189
    tsx_key.slen = 0;
 
1190
 
 
1191
    /* Init headers. */
 
1192
    target = pj_str(target_uri);
 
1193
    from = pj_str(from_uri);
 
1194
 
 
1195
    /* Create request. */
 
1196
    status = pjsip_endpt_create_request( endpt, method, &target,
 
1197
                                         &from, &target, NULL, NULL, -1,
 
1198
                                         NULL, &tdata);
 
1199
    if (status != PJ_SUCCESS) {
 
1200
        app_perror("   Error: unable to create request", status);
 
1201
        return -10;
 
1202
    }
 
1203
 
 
1204
    /* Set the branch param for test 1. */
 
1205
    via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
 
1206
    via->branch_param = pj_str(branch_param);
 
1207
 
 
1208
    /* Schedule first send. */
 
1209
    sent_cnt = 0;
 
1210
    pj_gettimeofday(&next_send);
 
1211
    pj_time_val_normalize(&next_send);
 
1212
 
 
1213
    /* Set test completion time. */
 
1214
    pj_gettimeofday(&timeout);
 
1215
    timeout.sec += test_time;
 
1216
 
 
1217
    /* Wait until test complete. */
 
1218
    while (!test_complete) {
 
1219
        pj_time_val now, poll_delay = {0, 10};
 
1220
 
 
1221
        pjsip_endpt_handle_events(endpt, &poll_delay);
 
1222
 
 
1223
        pj_gettimeofday(&now);
 
1224
 
 
1225
        if (sent_cnt < request_cnt && PJ_TIME_VAL_GTE(now, next_send)) {
 
1226
            /* Add additional reference to tdata to prevent transaction from
 
1227
             * deleting it.
 
1228
             */
 
1229
            pjsip_tx_data_add_ref(tdata);
 
1230
 
 
1231
            /* (Re)Send the request. */
 
1232
            PJ_LOG(4,(THIS_FILE, "    (re)sending request %d", sent_cnt));
 
1233
 
 
1234
            status = pjsip_endpt_send_request_stateless(endpt, tdata, 0, 0);
 
1235
            if (status != PJ_SUCCESS) {
 
1236
                app_perror("   Error: unable to send request", status);
 
1237
                pjsip_tx_data_dec_ref(tdata);
 
1238
                return -20;
 
1239
            }
 
1240
 
 
1241
            /* Schedule next send, if any. */
 
1242
            sent_cnt++;
 
1243
            if (sent_cnt < request_cnt) {
 
1244
                pj_gettimeofday(&next_send);
 
1245
                next_send.msec += request_interval_msec;
 
1246
                pj_time_val_normalize(&next_send);
 
1247
            }
 
1248
        }
 
1249
 
 
1250
        if (now.sec > timeout.sec) {
 
1251
            if (!expecting_timeout)
 
1252
                PJ_LOG(3,(THIS_FILE, "   Error: test has timed out"));
 
1253
            pjsip_tx_data_dec_ref(tdata);
 
1254
            return TEST_TIMEOUT_ERROR;
 
1255
        }
 
1256
    }
 
1257
 
 
1258
    if (test_complete < 0) {
 
1259
        pjsip_transaction *tsx;
 
1260
 
 
1261
        tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
 
1262
        if (tsx) {
 
1263
            pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);
 
1264
            pj_grp_lock_release(tsx->grp_lock);
 
1265
            flush_events(1000);
 
1266
        }
 
1267
        pjsip_tx_data_dec_ref(tdata);
 
1268
        return test_complete;
 
1269
    }
 
1270
 
 
1271
    /* Allow transaction to destroy itself */
 
1272
    flush_events(500);
 
1273
 
 
1274
    /* Make sure transaction has been destroyed. */
 
1275
    if (pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE) != NULL) {
 
1276
        PJ_LOG(3,(THIS_FILE, "   Error: transaction has not been destroyed"));
 
1277
        pjsip_tx_data_dec_ref(tdata);
 
1278
        return -40;
 
1279
    }
 
1280
 
 
1281
    /* Check tdata reference counter. */
 
1282
    if (pj_atomic_get(tdata->ref_cnt) != 1) {
 
1283
        PJ_LOG(3,(THIS_FILE, "   Error: tdata reference counter is %d",
 
1284
                      pj_atomic_get(tdata->ref_cnt)));
 
1285
        pjsip_tx_data_dec_ref(tdata);
 
1286
        return -50;
 
1287
    }
 
1288
 
 
1289
    /* Destroy txdata */
 
1290
    pjsip_tx_data_dec_ref(tdata);
 
1291
 
 
1292
    return PJ_SUCCESS;
 
1293
 
 
1294
}
 
1295
 
 
1296
 
 
1297
/*****************************************************************************
 
1298
 **
 
1299
 ** TEST1_BRANCH_ID: Basic 2xx final response
 
1300
 ** TEST2_BRANCH_ID: Basic non-2xx final response
 
1301
 **
 
1302
 *****************************************************************************
 
1303
 */
 
1304
static int tsx_basic_final_response_test(void)
 
1305
{
 
1306
    unsigned duration;
 
1307
    int status;
 
1308
 
 
1309
    PJ_LOG(3,(THIS_FILE,"  test1: basic sending 2xx final response"));
 
1310
 
 
1311
    /* Test duration must be greater than 32 secs if unreliable transport
 
1312
     * is used.
 
1313
     */
 
1314
    duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
 
1315
 
 
1316
    status = perform_test(TARGET_URI, FROM_URI, TEST1_BRANCH_ID,
 
1317
                          duration,  &pjsip_options_method, 1, 0, 0);
 
1318
    if (status != 0)
 
1319
        return status;
 
1320
 
 
1321
    PJ_LOG(3,(THIS_FILE,"  test2: basic sending non-2xx final response"));
 
1322
 
 
1323
    status = perform_test(TARGET_URI, FROM_URI, TEST2_BRANCH_ID,
 
1324
                          duration, &pjsip_options_method, 1, 0, 0);
 
1325
    if (status != 0)
 
1326
        return status;
 
1327
 
 
1328
    return 0;
 
1329
}
 
1330
 
 
1331
 
 
1332
/*****************************************************************************
 
1333
 **
 
1334
 ** TEST3_BRANCH_ID: Sending provisional response
 
1335
 **
 
1336
 *****************************************************************************
 
1337
 */
 
1338
static int tsx_basic_provisional_response_test(void)
 
1339
{
 
1340
    unsigned duration;
 
1341
    int status;
 
1342
 
 
1343
    PJ_LOG(3,(THIS_FILE,"  test3: basic sending 2xx final response"));
 
1344
 
 
1345
    duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
 
1346
    duration += 2;
 
1347
 
 
1348
    status = perform_test(TARGET_URI, FROM_URI, TEST3_BRANCH_ID, duration,
 
1349
                          &pjsip_options_method, 1, 0, 0);
 
1350
 
 
1351
    return status;
 
1352
}
 
1353
 
 
1354
 
 
1355
/*****************************************************************************
 
1356
 **
 
1357
 ** TEST4_BRANCH_ID: Absorbs retransmissions in TRYING state
 
1358
 ** TEST5_BRANCH_ID: Absorbs retransmissions in PROCEEDING state
 
1359
 ** TEST6_BRANCH_ID: Absorbs retransmissions in COMPLETED state
 
1360
 **
 
1361
 *****************************************************************************
 
1362
 */
 
1363
static int tsx_retransmit_last_response_test(const char *title,
 
1364
                                             char *branch_id,
 
1365
                                             int request_cnt,
 
1366
                                             int status_code)
 
1367
{
 
1368
    int status;
 
1369
 
 
1370
    PJ_LOG(3,(THIS_FILE,"  %s", title));
 
1371
 
 
1372
    status = perform_test(TARGET_URI, FROM_URI, branch_id, 5,
 
1373
                          &pjsip_options_method,
 
1374
                          request_cnt, 1000, 1);
 
1375
    if (status && status != TEST_TIMEOUT_ERROR)
 
1376
        return status;
 
1377
    if (!status) {
 
1378
        PJ_LOG(3,(THIS_FILE, "   error: expecting timeout"));
 
1379
        return -31;
 
1380
    }
 
1381
 
 
1382
    terminate_our_tsx(status_code);
 
1383
    flush_events(100);
 
1384
 
 
1385
    if (test_complete != 1)
 
1386
        return test_complete;
 
1387
 
 
1388
    flush_events(100);
 
1389
    return 0;
 
1390
}
 
1391
 
 
1392
/*****************************************************************************
 
1393
 **
 
1394
 ** TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
 
1395
 ** TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
 
1396
 **
 
1397
 *****************************************************************************
 
1398
 */
 
1399
static int tsx_final_response_retransmission_test(void)
 
1400
{
 
1401
    int status;
 
1402
 
 
1403
    PJ_LOG(3,(THIS_FILE,
 
1404
              "  test7: INVITE non-2xx final response retransmission"));
 
1405
 
 
1406
    status = perform_test(TARGET_URI, FROM_URI, TEST7_BRANCH_ID,
 
1407
                          33, /* Test duration must be greater than 32 secs */
 
1408
                          &pjsip_invite_method, 1, 0, 0);
 
1409
    if (status != 0)
 
1410
        return status;
 
1411
 
 
1412
    PJ_LOG(3,(THIS_FILE,
 
1413
              "  test8: INVITE 2xx final response retransmission"));
 
1414
 
 
1415
    status = perform_test(TARGET_URI, FROM_URI, TEST8_BRANCH_ID,
 
1416
                          33, /* Test duration must be greater than 32 secs */
 
1417
                          &pjsip_invite_method, 1, 0, 0);
 
1418
    if (status != 0)
 
1419
        return status;
 
1420
 
 
1421
    return 0;
 
1422
}
 
1423
 
 
1424
 
 
1425
/*****************************************************************************
 
1426
 **
 
1427
 ** TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
 
1428
 ** cease when ACK is received
 
1429
 **
 
1430
 *****************************************************************************
 
1431
 */
 
1432
static int tsx_ack_test(void)
 
1433
{
 
1434
    int status;
 
1435
 
 
1436
    PJ_LOG(3,(THIS_FILE,
 
1437
              "  test9: receiving ACK for non-2xx final response"));
 
1438
 
 
1439
    status = perform_test(TARGET_URI, FROM_URI, TEST9_BRANCH_ID,
 
1440
                          20, /* allow 5 retransmissions */
 
1441
                          &pjsip_invite_method, 1, 0, 0);
 
1442
    if (status != 0)
 
1443
        return status;
 
1444
 
 
1445
 
 
1446
    return 0;
 
1447
}
 
1448
 
 
1449
 
 
1450
 
 
1451
/*****************************************************************************
 
1452
 **
 
1453
 ** TEST10_BRANCH_ID: test transport failure in TRYING state.
 
1454
 ** TEST11_BRANCH_ID: test transport failure in PROCEEDING state.
 
1455
 ** TEST12_BRANCH_ID: test transport failure in CONNECTED state.
 
1456
 ** TEST13_BRANCH_ID: test transport failure in CONFIRMED state.
 
1457
 **
 
1458
 *****************************************************************************
 
1459
 */
 
1460
static int tsx_transport_failure_test(void)
 
1461
{
 
1462
    struct test_desc
 
1463
    {
 
1464
        int transport_delay;
 
1465
        int fail_delay;
 
1466
        char *branch_id;
 
1467
        char *title;
 
1468
    } tests[] =
 
1469
    {
 
1470
        { 0,  10,   TEST10_BRANCH_ID, "test10: failed transport in TRYING state (no delay)" },
 
1471
        { 50, 10,   TEST10_BRANCH_ID, "test10: failed transport in TRYING state (50 ms delay)" },
 
1472
        { 0,  1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (no delay)" },
 
1473
        { 50, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (50 ms delay)" },
 
1474
        { 0,  2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (no delay)" },
 
1475
        { 50, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (50 ms delay)" },
 
1476
    };
 
1477
    int i, status;
 
1478
 
 
1479
    for (i=0; i<(int)PJ_ARRAY_SIZE(tests); ++i) {
 
1480
        pj_time_val fail_time, end_test, now;
 
1481
 
 
1482
        PJ_LOG(3,(THIS_FILE, "  %s", tests[i].title));
 
1483
        pjsip_loop_set_failure(loop, 0, NULL);
 
1484
        pjsip_loop_set_delay(loop, tests[i].transport_delay);
 
1485
 
 
1486
        status = perform_test(TARGET_URI, FROM_URI, tests[i].branch_id,
 
1487
                              0, &pjsip_invite_method, 1, 0, 1);
 
1488
        if (status && status != TEST_TIMEOUT_ERROR)
 
1489
            return status;
 
1490
        if (!status) {
 
1491
            PJ_LOG(3,(THIS_FILE, "   error: expecting timeout"));
 
1492
            return -40;
 
1493
        }
 
1494
 
 
1495
        pj_gettimeofday(&fail_time);
 
1496
        fail_time.msec += tests[i].fail_delay;
 
1497
        pj_time_val_normalize(&fail_time);
 
1498
 
 
1499
        do {
 
1500
            pj_time_val interval = { 0, 1 };
 
1501
            pj_gettimeofday(&now);
 
1502
            pjsip_endpt_handle_events(endpt, &interval);
 
1503
        } while (PJ_TIME_VAL_LT(now, fail_time));
 
1504
 
 
1505
        pjsip_loop_set_failure(loop, 1, NULL);
 
1506
 
 
1507
        end_test = now;
 
1508
        end_test.sec += 5;
 
1509
 
 
1510
        do {
 
1511
            pj_time_val interval = { 0, 1 };
 
1512
            pj_gettimeofday(&now);
 
1513
            pjsip_endpt_handle_events(endpt, &interval);
 
1514
        } while (!test_complete && PJ_TIME_VAL_LT(now, end_test));
 
1515
 
 
1516
        if (test_complete == 0) {
 
1517
            PJ_LOG(3,(THIS_FILE, "   error: test has timed out"));
 
1518
            return -41;
 
1519
        }
 
1520
 
 
1521
        if (test_complete != 1)
 
1522
            return test_complete;
 
1523
    }
 
1524
 
 
1525
    return 0;
 
1526
}
 
1527
 
 
1528
/*****************************************************************************
 
1529
 **
 
1530
 ** UAS Transaction Test.
 
1531
 **
 
1532
 *****************************************************************************
 
1533
 */
 
1534
int tsx_uas_test(struct tsx_test_param *param)
 
1535
{
 
1536
    pj_sockaddr_in addr;
 
1537
    pj_status_t status;
 
1538
 
 
1539
    test_param = param;
 
1540
    tp_flag = pjsip_transport_get_flag_from_type((pjsip_transport_type_e)param->type);
 
1541
 
 
1542
    pj_ansi_sprintf(TARGET_URI, "sip:bob@127.0.0.1:%d;transport=%s",
 
1543
                    param->port, param->tp_type);
 
1544
    pj_ansi_sprintf(FROM_URI, "sip:alice@127.0.0.1:%d;transport=%s",
 
1545
                    param->port, param->tp_type);
 
1546
 
 
1547
    /* Check if loop transport is configured. */
 
1548
    status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
 
1549
                                      &addr, sizeof(addr), NULL, &loop);
 
1550
    if (status != PJ_SUCCESS) {
 
1551
        PJ_LOG(3,(THIS_FILE, "  Error: loop transport is not configured!"));
 
1552
        return -10;
 
1553
    }
 
1554
    /* Register modules. */
 
1555
    status = pjsip_endpt_register_module(endpt, &tsx_user);
 
1556
    if (status != PJ_SUCCESS) {
 
1557
        app_perror("   Error: unable to register module", status);
 
1558
        return -3;
 
1559
    }
 
1560
    status = pjsip_endpt_register_module(endpt, &msg_sender);
 
1561
    if (status != PJ_SUCCESS) {
 
1562
        app_perror("   Error: unable to register module", status);
 
1563
        return -4;
 
1564
    }
 
1565
 
 
1566
    /* TEST1_BRANCH_ID: Basic 2xx final response.
 
1567
     * TEST2_BRANCH_ID: Basic non-2xx final response.
 
1568
     */
 
1569
    status = tsx_basic_final_response_test();
 
1570
    if (status != 0)
 
1571
        return status;
 
1572
 
 
1573
    /* TEST3_BRANCH_ID: with provisional response
 
1574
     */
 
1575
    status = tsx_basic_provisional_response_test();
 
1576
    if (status != 0)
 
1577
        return status;
 
1578
 
 
1579
    /* TEST4_BRANCH_ID: absorbs retransmissions in TRYING state
 
1580
     */
 
1581
    status = tsx_retransmit_last_response_test(TEST4_TITLE,
 
1582
                                               TEST4_BRANCH_ID,
 
1583
                                               TEST4_REQUEST_COUNT,
 
1584
                                               TEST4_STATUS_CODE);
 
1585
    if (status != 0)
 
1586
        return status;
 
1587
 
 
1588
    /* TEST5_BRANCH_ID: retransmit last response in PROCEEDING state
 
1589
     */
 
1590
    status = tsx_retransmit_last_response_test(TEST5_TITLE,
 
1591
                                               TEST5_BRANCH_ID,
 
1592
                                               TEST5_REQUEST_COUNT,
 
1593
                                               TEST5_STATUS_CODE);
 
1594
    if (status != 0)
 
1595
        return status;
 
1596
 
 
1597
    /* TEST6_BRANCH_ID: retransmit last response in COMPLETED state
 
1598
     *                  This only applies to non-reliable transports,
 
1599
     *                  since UAS transaction is destroyed as soon
 
1600
     *                  as final response is sent for reliable transports.
 
1601
     */
 
1602
    if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
 
1603
        status = tsx_retransmit_last_response_test(TEST6_TITLE,
 
1604
                                                   TEST6_BRANCH_ID,
 
1605
                                                   TEST6_REQUEST_COUNT,
 
1606
                                                   TEST6_STATUS_CODE);
 
1607
        if (status != 0)
 
1608
            return status;
 
1609
    }
 
1610
 
 
1611
    /* TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
 
1612
     * TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
 
1613
     */
 
1614
    status = tsx_final_response_retransmission_test();
 
1615
    if (status != 0)
 
1616
        return status;
 
1617
 
 
1618
    /* TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
 
1619
     * cease when ACK is received
 
1620
     * Only applicable for non-reliable transports.
 
1621
     */
 
1622
    if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
 
1623
        status = tsx_ack_test();
 
1624
        if (status != 0)
 
1625
            return status;
 
1626
    }
 
1627
 
 
1628
 
 
1629
    /* TEST10_BRANCH_ID: test transport failure in TRYING state.
 
1630
     * TEST11_BRANCH_ID: test transport failure in PROCEEDING state.
 
1631
     * TEST12_BRANCH_ID: test transport failure in CONNECTED state.
 
1632
     * TEST13_BRANCH_ID: test transport failure in CONFIRMED state.
 
1633
     */
 
1634
    /* Only valid for loop-dgram */
 
1635
    if (param->type == PJSIP_TRANSPORT_LOOP_DGRAM) {
 
1636
        status = tsx_transport_failure_test();
 
1637
        if (status != 0)
 
1638
            return status;
 
1639
    }
 
1640
 
 
1641
 
 
1642
    /* Register modules. */
 
1643
    status = pjsip_endpt_unregister_module(endpt, &tsx_user);
 
1644
    if (status != PJ_SUCCESS) {
 
1645
        app_perror("   Error: unable to unregister module", status);
 
1646
        return -8;
 
1647
    }
 
1648
    status = pjsip_endpt_unregister_module(endpt, &msg_sender);
 
1649
    if (status != PJ_SUCCESS) {
 
1650
        app_perror("   Error: unable to unregister module", status);
 
1651
        return -9;
 
1652
    }
 
1653
 
 
1654
 
 
1655
    if (loop)
 
1656
        pjsip_transport_dec_ref(loop);
 
1657
 
 
1658
    return 0;
 
1659
}
 
1660