~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

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