~noskcaj/ubuntu/saucy/sflphone/merge-1.2.3-2

« back to all changes in this revision

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

  • Committer: Jackson Doak
  • Date: 2013-07-10 21:04:46 UTC
  • mfrom: (20.1.3 sid)
  • Revision ID: noskcaj@ubuntu.com-20130710210446-y8f587vza807icr9
Properly merged from upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: inv_offer_answer_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_ua.h>
 
23
#include <pjsip.h>
 
24
#include <pjlib.h>
 
25
 
 
26
#define THIS_FILE   "inv_offer_answer_test.c"
 
27
#define PORT        5068
 
28
#define CONTACT     "sip:127.0.0.1:5068"
 
29
#define TRACE_(x)   PJ_LOG(3,x)
 
30
 
 
31
static struct oa_sdp_t
 
32
{
 
33
    const char *offer;
 
34
    const char *answer;
 
35
    unsigned    pt_result;
 
36
} oa_sdp[] =
 
37
{
 
38
    {
 
39
        /* Offer: */
 
40
        "v=0\r\n"
 
41
        "o=alice 1 1 IN IP4 host.anywhere.com\r\n"
 
42
        "s= \r\n"
 
43
        "c=IN IP4 host.anywhere.com\r\n"
 
44
        "t=0 0\r\n"
 
45
        "m=audio 49170 RTP/AVP 0\r\n"
 
46
        "a=rtpmap:0 PCMU/8000\r\n",
 
47
 
 
48
        /* Answer: */
 
49
        "v=0\r\n"
 
50
        "o=bob 1 1 IN IP4 host.example.com\r\n"
 
51
        "s= \r\n"
 
52
        "c=IN IP4 host.example.com\r\n"
 
53
        "t=0 0\r\n"
 
54
        "m=audio 49920 RTP/AVP 0\r\n"
 
55
        "a=rtpmap:0 PCMU/8000\r\n"
 
56
        "m=video 0 RTP/AVP 31\r\n",
 
57
 
 
58
        0
 
59
      },
 
60
 
 
61
      {
 
62
        /* Offer: */
 
63
        "v=0\r\n"
 
64
        "o=alice 2 2 IN IP4 host.anywhere.com\r\n"
 
65
        "s= \r\n"
 
66
        "c=IN IP4 host.anywhere.com\r\n"
 
67
        "t=0 0\r\n"
 
68
        "m=audio 49170 RTP/AVP 8\r\n"
 
69
        "a=rtpmap:0 PCMA/8000\r\n",
 
70
 
 
71
        /* Answer: */
 
72
        "v=0\r\n"
 
73
        "o=bob 2 2 IN IP4 host.example.com\r\n"
 
74
        "s= \r\n"
 
75
        "c=IN IP4 host.example.com\r\n"
 
76
        "t=0 0\r\n"
 
77
        "m=audio 49920 RTP/AVP 8\r\n"
 
78
        "a=rtpmap:0 PCMA/8000\r\n",
 
79
 
 
80
        8
 
81
      },
 
82
 
 
83
      {
 
84
        /* Offer: */
 
85
        "v=0\r\n"
 
86
        "o=alice 3 3 IN IP4 host.anywhere.com\r\n"
 
87
        "s= \r\n"
 
88
        "c=IN IP4 host.anywhere.com\r\n"
 
89
        "t=0 0\r\n"
 
90
        "m=audio 49170 RTP/AVP 3\r\n",
 
91
 
 
92
        /* Answer: */
 
93
        "v=0\r\n"
 
94
        "o=bob 3 3 IN IP4 host.example.com\r\n"
 
95
        "s= \r\n"
 
96
        "c=IN IP4 host.example.com\r\n"
 
97
        "t=0 0\r\n"
 
98
        "m=audio 49920 RTP/AVP 3\r\n",
 
99
 
 
100
        3
 
101
      },
 
102
 
 
103
      {
 
104
        /* Offer: */
 
105
        "v=0\r\n"
 
106
        "o=alice 4 4 IN IP4 host.anywhere.com\r\n"
 
107
        "s= \r\n"
 
108
        "c=IN IP4 host.anywhere.com\r\n"
 
109
        "t=0 0\r\n"
 
110
        "m=audio 49170 RTP/AVP 4\r\n",
 
111
 
 
112
        /* Answer: */
 
113
        "v=0\r\n"
 
114
        "o=bob 4 4 IN IP4 host.example.com\r\n"
 
115
        "s= \r\n"
 
116
        "c=IN IP4 host.example.com\r\n"
 
117
        "t=0 0\r\n"
 
118
        "m=audio 49920 RTP/AVP 4\r\n",
 
119
 
 
120
        4
 
121
    }
 
122
};
 
123
 
 
124
 
 
125
 
 
126
typedef enum oa_t
 
127
{
 
128
    OFFERER_NONE,
 
129
    OFFERER_UAC,
 
130
    OFFERER_UAS
 
131
} oa_t;
 
132
 
 
133
typedef struct inv_test_param_t
 
134
{
 
135
    char       *title;
 
136
    unsigned    inv_option;
 
137
    pj_bool_t   need_established;
 
138
    unsigned    count;
 
139
    oa_t        oa[4];
 
140
} inv_test_param_t;
 
141
 
 
142
typedef struct inv_test_t
 
143
{
 
144
    inv_test_param_t    param;
 
145
    pjsip_inv_session  *uac;
 
146
    pjsip_inv_session  *uas;
 
147
 
 
148
    pj_bool_t           complete;
 
149
    pj_bool_t           uas_complete,
 
150
                        uac_complete;
 
151
 
 
152
    unsigned            oa_index;
 
153
    unsigned            uac_update_cnt,
 
154
                        uas_update_cnt;
 
155
} inv_test_t;
 
156
 
 
157
 
 
158
/**************** GLOBALS ******************/
 
159
static inv_test_t   inv_test;
 
160
static unsigned     job_cnt;
 
161
 
 
162
typedef enum job_type
 
163
{
 
164
    SEND_OFFER,
 
165
    ESTABLISH_CALL
 
166
} job_type;
 
167
 
 
168
typedef struct job_t
 
169
{
 
170
    job_type        type;
 
171
    pjsip_role_e    who;
 
172
} job_t;
 
173
 
 
174
static job_t jobs[128];
 
175
 
 
176
 
 
177
/**************** UTILS ******************/
 
178
static pjmedia_sdp_session *create_sdp(pj_pool_t *pool, const char *body)
 
179
{
 
180
    pjmedia_sdp_session *sdp;
 
181
    pj_str_t dup;
 
182
    pj_status_t status;
 
183
 
 
184
    pj_strdup2_with_null(pool, &dup, body);
 
185
    status = pjmedia_sdp_parse(pool, dup.ptr, dup.slen, &sdp);
 
186
    pj_assert(status == PJ_SUCCESS);
 
187
 
 
188
    return sdp;
 
189
}
 
190
 
 
191
/**************** INVITE SESSION CALLBACKS ******************/
 
192
static void on_rx_offer(pjsip_inv_session *inv,
 
193
                        const pjmedia_sdp_session *offer)
 
194
{
 
195
    pjmedia_sdp_session *sdp;
 
196
 
 
197
    PJ_UNUSED_ARG(offer);
 
198
 
 
199
    sdp = create_sdp(inv->dlg->pool, oa_sdp[inv_test.oa_index].answer);
 
200
    pjsip_inv_set_sdp_answer(inv, sdp);
 
201
 
 
202
    if (inv_test.oa_index == inv_test.param.count-1 &&
 
203
        inv_test.param.need_established)
 
204
    {
 
205
        jobs[job_cnt].type = ESTABLISH_CALL;
 
206
        jobs[job_cnt].who = PJSIP_ROLE_UAS;
 
207
        job_cnt++;
 
208
    }
 
209
}
 
210
 
 
211
 
 
212
static void on_create_offer(pjsip_inv_session *inv,
 
213
                            pjmedia_sdp_session **p_offer)
 
214
{
 
215
    PJ_UNUSED_ARG(inv);
 
216
    PJ_UNUSED_ARG(p_offer);
 
217
 
 
218
    pj_assert(!"Should not happen");
 
219
}
 
220
 
 
221
static void on_media_update(pjsip_inv_session *inv_ses,
 
222
                            pj_status_t status)
 
223
{
 
224
    PJ_UNUSED_ARG(status);
 
225
 
 
226
    if (inv_ses == inv_test.uas) {
 
227
        inv_test.uas_update_cnt++;
 
228
        pj_assert(inv_test.uas_update_cnt - inv_test.uac_update_cnt <= 1);
 
229
        TRACE_((THIS_FILE, "      Callee media is established"));
 
230
    } else if (inv_ses == inv_test.uac) {
 
231
        inv_test.uac_update_cnt++;
 
232
        pj_assert(inv_test.uac_update_cnt - inv_test.uas_update_cnt <= 1);
 
233
        TRACE_((THIS_FILE, "      Caller media is established"));
 
234
 
 
235
    } else {
 
236
        pj_assert(!"Unknown session!");
 
237
    }
 
238
 
 
239
    if (inv_test.uac_update_cnt == inv_test.uas_update_cnt) {
 
240
        inv_test.oa_index++;
 
241
 
 
242
        if (inv_test.oa_index < inv_test.param.count) {
 
243
            switch (inv_test.param.oa[inv_test.oa_index]) {
 
244
            case OFFERER_UAC:
 
245
                jobs[job_cnt].type = SEND_OFFER;
 
246
                jobs[job_cnt].who = PJSIP_ROLE_UAC;
 
247
                job_cnt++;
 
248
                break;
 
249
            case OFFERER_UAS:
 
250
                jobs[job_cnt].type = SEND_OFFER;
 
251
                jobs[job_cnt].who = PJSIP_ROLE_UAS;
 
252
                job_cnt++;
 
253
                break;
 
254
            default:
 
255
                pj_assert(!"Invalid oa");
 
256
            }
 
257
        }
 
258
 
 
259
        pj_assert(job_cnt <= PJ_ARRAY_SIZE(jobs));
 
260
    }
 
261
}
 
262
 
 
263
static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
 
264
{
 
265
    const char *who = NULL;
 
266
 
 
267
    PJ_UNUSED_ARG(e);
 
268
 
 
269
    if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
 
270
        TRACE_((THIS_FILE, "      %s call disconnected",
 
271
                (inv==inv_test.uas ? "Callee" : "Caller")));
 
272
        return;
 
273
    }
 
274
 
 
275
    if (inv->state != PJSIP_INV_STATE_CONFIRMED)
 
276
        return;
 
277
 
 
278
    if (inv == inv_test.uas) {
 
279
        inv_test.uas_complete = PJ_TRUE;
 
280
        who = "Callee";
 
281
    } else if (inv == inv_test.uac) {
 
282
        inv_test.uac_complete = PJ_TRUE;
 
283
        who = "Caller";
 
284
    } else
 
285
        pj_assert(!"No session");
 
286
 
 
287
    TRACE_((THIS_FILE, "      %s call is confirmed", who));
 
288
 
 
289
    if (inv_test.uac_complete && inv_test.uas_complete)
 
290
        inv_test.complete = PJ_TRUE;
 
291
}
 
292
 
 
293
 
 
294
/**************** MODULE TO RECEIVE INITIAL INVITE ******************/
 
295
 
 
296
static pj_bool_t on_rx_request(pjsip_rx_data *rdata)
 
297
{
 
298
    if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG &&
 
299
        rdata->msg_info.msg->line.req.method.id == PJSIP_INVITE_METHOD)
 
300
    {
 
301
        pjsip_dialog *dlg;
 
302
        pjmedia_sdp_session *sdp = NULL;
 
303
        pj_str_t uri;
 
304
        pjsip_tx_data *tdata;
 
305
        pj_status_t status;
 
306
 
 
307
        /*
 
308
         * Create UAS
 
309
         */
 
310
        uri = pj_str(CONTACT);
 
311
        status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata,
 
312
                                      &uri, &dlg);
 
313
        pj_assert(status == PJ_SUCCESS);
 
314
 
 
315
        if (inv_test.param.oa[0] == OFFERER_UAC)
 
316
            sdp = create_sdp(rdata->tp_info.pool, oa_sdp[0].answer);
 
317
        else if (inv_test.param.oa[0] == OFFERER_UAS)
 
318
            sdp = create_sdp(rdata->tp_info.pool, oa_sdp[0].offer);
 
319
        else
 
320
            pj_assert(!"Invalid offerer type");
 
321
 
 
322
        status = pjsip_inv_create_uas(dlg, rdata, sdp, inv_test.param.inv_option, &inv_test.uas);
 
323
        pj_assert(status == PJ_SUCCESS);
 
324
 
 
325
        TRACE_((THIS_FILE, "    Sending 183 with SDP"));
 
326
 
 
327
        /*
 
328
         * Answer with 183
 
329
         */
 
330
        status = pjsip_inv_initial_answer(inv_test.uas, rdata, 183, NULL,
 
331
                                          NULL, &tdata);
 
332
        pj_assert(status == PJ_SUCCESS);
 
333
 
 
334
        status = pjsip_inv_send_msg(inv_test.uas, tdata);
 
335
        pj_assert(status == PJ_SUCCESS);
 
336
 
 
337
        return PJ_TRUE;
 
338
    }
 
339
 
 
340
    return PJ_FALSE;
 
341
}
 
342
 
 
343
static pjsip_module mod_inv_oa_test =
 
344
{
 
345
    NULL, NULL,                     /* prev, next.              */
 
346
    { "mod-inv-oa-test", 15 },      /* Name.                    */
 
347
    -1,                             /* Id                       */
 
348
    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority                 */
 
349
    NULL,                           /* load()                   */
 
350
    NULL,                           /* start()                  */
 
351
    NULL,                           /* stop()                   */
 
352
    NULL,                           /* unload()                 */
 
353
    &on_rx_request,                 /* on_rx_request()          */
 
354
    NULL,                           /* on_rx_response()         */
 
355
    NULL,                           /* on_tx_request.           */
 
356
    NULL,                           /* on_tx_response()         */
 
357
    NULL,                           /* on_tsx_state()           */
 
358
};
 
359
 
 
360
 
 
361
/**************** THE TEST ******************/
 
362
static void run_job(job_t *j)
 
363
{
 
364
    pjsip_inv_session *inv;
 
365
    pjsip_tx_data *tdata;
 
366
    pjmedia_sdp_session *sdp;
 
367
    pj_status_t status;
 
368
 
 
369
    if (j->who == PJSIP_ROLE_UAC)
 
370
        inv = inv_test.uac;
 
371
    else
 
372
        inv = inv_test.uas;
 
373
 
 
374
    switch (j->type) {
 
375
    case SEND_OFFER:
 
376
        sdp = create_sdp(inv->dlg->pool, oa_sdp[inv_test.oa_index].offer);
 
377
 
 
378
        TRACE_((THIS_FILE, "    Sending UPDATE with offer"));
 
379
        status = pjsip_inv_update(inv, NULL, sdp, &tdata);
 
380
        pj_assert(status == PJ_SUCCESS);
 
381
 
 
382
        status = pjsip_inv_send_msg(inv, tdata);
 
383
        pj_assert(status == PJ_SUCCESS);
 
384
        break;
 
385
    case ESTABLISH_CALL:
 
386
        TRACE_((THIS_FILE, "    Sending 200/OK"));
 
387
        status = pjsip_inv_answer(inv, 200, NULL, NULL, &tdata);
 
388
        pj_assert(status == PJ_SUCCESS);
 
389
 
 
390
        status = pjsip_inv_send_msg(inv, tdata);
 
391
        pj_assert(status == PJ_SUCCESS);
 
392
        break;
 
393
    }
 
394
}
 
395
 
 
396
 
 
397
static int perform_test(inv_test_param_t *param)
 
398
{
 
399
    pj_str_t uri;
 
400
    pjsip_dialog *dlg;
 
401
    pjmedia_sdp_session *sdp;
 
402
    pjsip_tx_data *tdata;
 
403
    pj_status_t status;
 
404
 
 
405
    PJ_LOG(3,(THIS_FILE, "  %s", param->title));
 
406
 
 
407
    pj_bzero(&inv_test, sizeof(inv_test));
 
408
    pj_memcpy(&inv_test.param, param, sizeof(*param));
 
409
    job_cnt = 0;
 
410
 
 
411
    uri = pj_str(CONTACT);
 
412
 
 
413
    /*
 
414
     * Create UAC
 
415
     */
 
416
    status = pjsip_dlg_create_uac(pjsip_ua_instance(),
 
417
                                  &uri, &uri, &uri, &uri, &dlg);
 
418
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -10);
 
419
 
 
420
    if (inv_test.param.oa[0] == OFFERER_UAC)
 
421
        sdp = create_sdp(dlg->pool, oa_sdp[0].offer);
 
422
    else
 
423
        sdp = NULL;
 
424
 
 
425
    status = pjsip_inv_create_uac(dlg, sdp, inv_test.param.inv_option, &inv_test.uac);
 
426
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -20);
 
427
 
 
428
    TRACE_((THIS_FILE, "    Sending INVITE %s offer", (sdp ? "with" : "without")));
 
429
 
 
430
    /*
 
431
     * Make call!
 
432
     */
 
433
    status = pjsip_inv_invite(inv_test.uac, &tdata);
 
434
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);
 
435
 
 
436
    status = pjsip_inv_send_msg(inv_test.uac, tdata);
 
437
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, -30);
 
438
 
 
439
    /*
 
440
     * Wait until test completes
 
441
     */
 
442
    while (!inv_test.complete) {
 
443
        pj_time_val delay = {0, 20};
 
444
 
 
445
        pjsip_endpt_handle_events(endpt, &delay);
 
446
 
 
447
        while (job_cnt) {
 
448
            job_t j;
 
449
 
 
450
            j = jobs[0];
 
451
            pj_array_erase(jobs, sizeof(jobs[0]), job_cnt, 0);
 
452
            --job_cnt;
 
453
 
 
454
            run_job(&j);
 
455
        }
 
456
    }
 
457
 
 
458
    flush_events(100);
 
459
 
 
460
    /*
 
461
     * Hangup
 
462
     */
 
463
    TRACE_((THIS_FILE, "    Disconnecting call"));
 
464
    status = pjsip_inv_end_session(inv_test.uas, PJSIP_SC_DECLINE, 0, &tdata);
 
465
    pj_assert(status == PJ_SUCCESS);
 
466
 
 
467
    status = pjsip_inv_send_msg(inv_test.uas, tdata);
 
468
    pj_assert(status == PJ_SUCCESS);
 
469
 
 
470
    flush_events(500);
 
471
 
 
472
    return 0;
 
473
}
 
474
 
 
475
 
 
476
static pj_bool_t log_on_rx_msg(pjsip_rx_data *rdata)
 
477
{
 
478
    pjsip_msg *msg = rdata->msg_info.msg;
 
479
    char info[80];
 
480
 
 
481
    if (msg->type == PJSIP_REQUEST_MSG)
 
482
        pj_ansi_snprintf(info, sizeof(info), "%.*s",
 
483
            (int)msg->line.req.method.name.slen,
 
484
            msg->line.req.method.name.ptr);
 
485
    else
 
486
        pj_ansi_snprintf(info, sizeof(info), "%d/%.*s",
 
487
            msg->line.status.code,
 
488
            (int)rdata->msg_info.cseq->method.name.slen,
 
489
            rdata->msg_info.cseq->method.name.ptr);
 
490
 
 
491
    TRACE_((THIS_FILE, "      Received %s %s sdp", info,
 
492
        (msg->body ? "with" : "without")));
 
493
 
 
494
    return PJ_FALSE;
 
495
}
 
496
 
 
497
 
 
498
/* Message logger module. */
 
499
static pjsip_module mod_msg_logger =
 
500
{
 
501
    NULL, NULL,                         /* prev and next        */
 
502
    { "mod-msg-loggee", 14},            /* Name.                */
 
503
    -1,                                 /* Id                   */
 
504
    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority            */
 
505
    NULL,                               /* load()               */
 
506
    NULL,                               /* start()              */
 
507
    NULL,                               /* stop()               */
 
508
    NULL,                               /* unload()             */
 
509
    &log_on_rx_msg,                     /* on_rx_request()      */
 
510
    &log_on_rx_msg,                     /* on_rx_response()     */
 
511
    NULL,                               /* on_tx_request()      */
 
512
    NULL,                               /* on_tx_response()     */
 
513
    NULL,                               /* on_tsx_state()       */
 
514
};
 
515
 
 
516
static inv_test_param_t test_params[] =
 
517
{
 
518
/* Normal scenario:
 
519
 
 
520
                                UAC             UAS
 
521
    INVITE (offer)      -->
 
522
    200/INVITE (answer) <--
 
523
    ACK                 -->
 
524
 */
 
525
#if 0
 
526
    {
 
527
        "Standard INVITE with offer",
 
528
        0,
 
529
        PJ_TRUE,
 
530
        1,
 
531
        { OFFERER_UAC }
 
532
    },
 
533
 
 
534
    {
 
535
        "Standard INVITE with offer, with 100rel",
 
536
        PJSIP_INV_REQUIRE_100REL,
 
537
        PJ_TRUE,
 
538
        1,
 
539
        { OFFERER_UAC }
 
540
    },
 
541
#endif
 
542
 
 
543
/* Delayed offer:
 
544
                                UAC             UAS
 
545
    INVITE (no SDP)     -->
 
546
    200/INVITE (offer)  <--
 
547
    ACK (answer)        -->
 
548
 */
 
549
#if 1
 
550
    {
 
551
        "INVITE with no offer",
 
552
        0,
 
553
        PJ_TRUE,
 
554
        1,
 
555
        { OFFERER_UAS }
 
556
    },
 
557
 
 
558
    {
 
559
        "INVITE with no offer, with 100rel",
 
560
        PJSIP_INV_REQUIRE_100REL,
 
561
        PJ_TRUE,
 
562
        1,
 
563
        { OFFERER_UAS }
 
564
    },
 
565
#endif
 
566
 
 
567
/* Subsequent UAC offer with UPDATE:
 
568
 
 
569
                                UAC             UAS
 
570
    INVITE (offer)      -->
 
571
    180/rel (answer)    <--
 
572
    UPDATE (offer)      -->     inv_update()    on_rx_offer()
 
573
                                                set_sdp_answer()
 
574
    200/UPDATE (answer) <--
 
575
    200/INVITE          <--
 
576
    ACK -->
 
577
*/
 
578
#if 1
 
579
    {
 
580
        "INVITE and UPDATE by UAC",
 
581
        0,
 
582
        PJ_TRUE,
 
583
        2,
 
584
        { OFFERER_UAC, OFFERER_UAC }
 
585
    },
 
586
    {
 
587
        "INVITE and UPDATE by UAC, with 100rel",
 
588
        PJSIP_INV_REQUIRE_100REL,
 
589
        PJ_TRUE,
 
590
        2,
 
591
        { OFFERER_UAC, OFFERER_UAC }
 
592
    },
 
593
#endif
 
594
 
 
595
/* Subsequent UAS offer with UPDATE:
 
596
 
 
597
    INVITE (offer       -->
 
598
    180/rel (answer)    <--
 
599
    UPDATE (offer)      <--                     inv_update()
 
600
                                on_rx_offer()
 
601
                                set_sdp_answer()
 
602
    200/UPDATE (answer) -->
 
603
    UPDATE (offer)      -->                     on_rx_offer()
 
604
                                                set_sdp_answer()
 
605
    200/UPDATE (answer) <--
 
606
    200/INVITE          <--
 
607
    ACK                 -->
 
608
 
 
609
 */
 
610
    {
 
611
        "INVITE and many UPDATE by UAC and UAS",
 
612
        0,
 
613
        PJ_TRUE,
 
614
        4,
 
615
        { OFFERER_UAC, OFFERER_UAS, OFFERER_UAC, OFFERER_UAS }
 
616
    },
 
617
 
 
618
};
 
619
 
 
620
 
 
621
static pjsip_dialog* on_dlg_forked(pjsip_dialog *first_set, pjsip_rx_data *res)
 
622
{
 
623
    PJ_UNUSED_ARG(first_set);
 
624
    PJ_UNUSED_ARG(res);
 
625
 
 
626
    return NULL;
 
627
}
 
628
 
 
629
 
 
630
static void on_new_session(pjsip_inv_session *inv, pjsip_event *e)
 
631
{
 
632
    PJ_UNUSED_ARG(inv);
 
633
    PJ_UNUSED_ARG(e);
 
634
}
 
635
 
 
636
 
 
637
int inv_offer_answer_test(void)
 
638
{
 
639
    unsigned i;
 
640
    int rc = 0;
 
641
 
 
642
    /* Init UA layer */
 
643
    if (pjsip_ua_instance()->id == -1) {
 
644
        pjsip_ua_init_param ua_param;
 
645
        pj_bzero(&ua_param, sizeof(ua_param));
 
646
        ua_param.on_dlg_forked = &on_dlg_forked;
 
647
        pjsip_ua_init_module(endpt, &ua_param);
 
648
    }
 
649
 
 
650
    /* Init inv-usage */
 
651
    if (pjsip_inv_usage_instance()->id == -1) {
 
652
        pjsip_inv_callback inv_cb;
 
653
        pj_bzero(&inv_cb, sizeof(inv_cb));
 
654
        inv_cb.on_media_update = &on_media_update;
 
655
        inv_cb.on_rx_offer = &on_rx_offer;
 
656
        inv_cb.on_create_offer = &on_create_offer;
 
657
        inv_cb.on_state_changed = &on_state_changed;
 
658
        inv_cb.on_new_session = &on_new_session;
 
659
        pjsip_inv_usage_init(endpt, &inv_cb);
 
660
    }
 
661
 
 
662
    /* 100rel module */
 
663
    pjsip_100rel_init_module(endpt);
 
664
 
 
665
    /* Our module */
 
666
    pjsip_endpt_register_module(endpt, &mod_inv_oa_test);
 
667
    pjsip_endpt_register_module(endpt, &mod_msg_logger);
 
668
 
 
669
    /* Create SIP UDP transport */
 
670
    {
 
671
        pj_sockaddr_in addr;
 
672
        pjsip_transport *tp;
 
673
        pj_status_t status;
 
674
 
 
675
        pj_sockaddr_in_init(&addr, NULL, PORT);
 
676
        status = pjsip_udp_transport_start(endpt, &addr, NULL, 1, &tp);
 
677
        pj_assert(status == PJ_SUCCESS);
 
678
    }
 
679
 
 
680
    /* Do tests */
 
681
    for (i=0; i<PJ_ARRAY_SIZE(test_params); ++i) {
 
682
        rc = perform_test(&test_params[i]);
 
683
        if (rc != 0)
 
684
            goto on_return;
 
685
    }
 
686
 
 
687
 
 
688
on_return:
 
689
    return rc;
 
690
}