~ubuntu-branches/ubuntu/raring/sflphone/raring

« back to all changes in this revision

Viewing changes to sflphone-common/libs/pjproject/pjsip/src/pjsip/sip_dialog.c

  • Committer: Package Import Robot
  • Author(s): Francois Marier
  • Date: 2011-11-25 13:24:12 UTC
  • mfrom: (4.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20111125132412-dc4qvhyosk74cd42
Tags: 1.0.1-4
Don't assume that arch:all packages will get built (closes: #649726)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: sip_dialog.c 3031 2009-12-10 05:16:23Z bennylp $ */
2
 
/* 
3
 
 * Copyright (C) 2008-2009 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
 
 *  Additional permission under GNU GPL version 3 section 7:
21
 
 *
22
 
 *  If you modify this program, or any covered work, by linking or
23
 
 *  combining it with the OpenSSL project's OpenSSL library (or a
24
 
 *  modified version of that library), containing parts covered by the
25
 
 *  terms of the OpenSSL or SSLeay licenses, Teluu Inc. (http://www.teluu.com)
26
 
 *  grants you additional permission to convey the resulting work.
27
 
 *  Corresponding Source for a non-source form of such a combination
28
 
 *  shall include the source code for the parts of OpenSSL used as well
29
 
 *  as that of the covered work.
30
 
 */
31
 
#include <pjsip/sip_dialog.h>
32
 
#include <pjsip/sip_ua_layer.h>
33
 
#include <pjsip/sip_errno.h>
34
 
#include <pjsip/sip_endpoint.h>
35
 
#include <pjsip/sip_parser.h>
36
 
#include <pjsip/sip_module.h>
37
 
#include <pjsip/sip_util.h>
38
 
#include <pjsip/sip_transaction.h>
39
 
#include <pj/assert.h>
40
 
#include <pj/os.h>
41
 
#include <pj/string.h>
42
 
#include <pj/pool.h>
43
 
#include <pj/guid.h>
44
 
#include <pj/rand.h>
45
 
#include <pj/array.h>
46
 
#include <pj/except.h>
47
 
#include <pj/hash.h>
48
 
#include <pj/log.h>
49
 
 
50
 
#define THIS_FILE       "sip_dialog.c"
51
 
 
52
 
long pjsip_dlg_lock_tls_id;
53
 
 
54
 
/* Config */
55
 
pj_bool_t pjsip_include_allow_hdr_in_dlg = PJSIP_INCLUDE_ALLOW_HDR_IN_DLG;
56
 
 
57
 
/* Contact header string */
58
 
static const pj_str_t HCONTACT = { "Contact", 7 };
59
 
 
60
 
PJ_DEF(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m)
61
 
{
62
 
    const pjsip_method subscribe = { PJSIP_OTHER_METHOD, {"SUBSCRIBE", 9}};
63
 
    const pjsip_method refer = { PJSIP_OTHER_METHOD, {"REFER", 5}};
64
 
    const pjsip_method notify = { PJSIP_OTHER_METHOD, {"NOTIFY", 6}};
65
 
    const pjsip_method update = { PJSIP_OTHER_METHOD, {"UPDATE", 6}};
66
 
 
67
 
    return m->id == PJSIP_INVITE_METHOD ||
68
 
           (pjsip_method_cmp(m, &subscribe)==0) ||
69
 
           (pjsip_method_cmp(m, &refer)==0) ||
70
 
           (pjsip_method_cmp(m, &notify)==0) ||
71
 
           (pjsip_method_cmp(m, &update)==0);
72
 
}
73
 
 
74
 
static pj_status_t create_dialog( pjsip_user_agent *ua,
75
 
                                  pjsip_dialog **p_dlg)
76
 
{
77
 
    pjsip_endpoint *endpt;
78
 
    pj_pool_t *pool;
79
 
    pjsip_dialog *dlg;
80
 
    pj_status_t status;
81
 
 
82
 
    endpt = pjsip_ua_get_endpt(ua);
83
 
    if (!endpt)
84
 
        return PJ_EINVALIDOP;
85
 
 
86
 
    pool = pjsip_endpt_create_pool(endpt, "dlg%p", 
87
 
                                   PJSIP_POOL_LEN_DIALOG, 
88
 
                                   PJSIP_POOL_INC_DIALOG);
89
 
    if (!pool)
90
 
        return PJ_ENOMEM;
91
 
 
92
 
    dlg = PJ_POOL_ZALLOC_T(pool, pjsip_dialog);
93
 
    PJ_ASSERT_RETURN(dlg != NULL, PJ_ENOMEM);
94
 
 
95
 
    dlg->pool = pool;
96
 
    pj_ansi_snprintf(dlg->obj_name, sizeof(dlg->obj_name), "dlg%p", dlg);
97
 
    dlg->ua = ua;
98
 
    dlg->endpt = endpt;
99
 
    dlg->state = PJSIP_DIALOG_STATE_NULL;
100
 
    dlg->add_allow = pjsip_include_allow_hdr_in_dlg;
101
 
 
102
 
    pj_list_init(&dlg->inv_hdr);
103
 
 
104
 
    status = pj_mutex_create_recursive(pool, dlg->obj_name, &dlg->mutex_);
105
 
    if (status != PJ_SUCCESS)
106
 
        goto on_error;
107
 
 
108
 
    pjsip_target_set_init(&dlg->target_set);
109
 
 
110
 
    *p_dlg = dlg;
111
 
    return PJ_SUCCESS;
112
 
 
113
 
on_error:
114
 
    if (dlg->mutex_)
115
 
        pj_mutex_destroy(dlg->mutex_);
116
 
    pjsip_endpt_release_pool(endpt, pool);
117
 
    return status;
118
 
}
119
 
 
120
 
static void destroy_dialog( pjsip_dialog *dlg )
121
 
{
122
 
    if (dlg->mutex_) {
123
 
        pj_mutex_destroy(dlg->mutex_);
124
 
        dlg->mutex_ = NULL;
125
 
    }
126
 
    if (dlg->tp_sel.type != PJSIP_TPSELECTOR_NONE) {
127
 
        pjsip_tpselector_dec_ref(&dlg->tp_sel);
128
 
        pj_bzero(&dlg->tp_sel, sizeof(pjsip_tpselector));
129
 
    }
130
 
    pjsip_endpt_release_pool(dlg->endpt, dlg->pool);
131
 
}
132
 
 
133
 
 
134
 
/*
135
 
 * Create an UAC dialog.
136
 
 */
137
 
PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
138
 
                                          const pj_str_t *local_uri,
139
 
                                          const pj_str_t *local_contact,
140
 
                                          const pj_str_t *remote_uri,
141
 
                                          const pj_str_t *target,
142
 
                                          pjsip_dialog **p_dlg)
143
 
{
144
 
    pj_status_t status;
145
 
    pj_str_t tmp;
146
 
    pjsip_dialog *dlg;
147
 
 
148
 
    /* Check arguments. */
149
 
    PJ_ASSERT_RETURN(ua && local_uri && remote_uri && p_dlg, PJ_EINVAL);
150
 
 
151
 
    /* Create dialog instance. */
152
 
    status = create_dialog(ua, &dlg);
153
 
    if (status != PJ_SUCCESS)
154
 
        return status;
155
 
 
156
 
    /* Parse target. */
157
 
    pj_strdup_with_null(dlg->pool, &tmp, target ? target : remote_uri);
158
 
    dlg->target = pjsip_parse_uri(dlg->pool, tmp.ptr, tmp.slen, 0);
159
 
    if (!dlg->target) {
160
 
        status = PJSIP_EINVALIDURI;
161
 
        goto on_error;
162
 
    }
163
 
 
164
 
    /* Put any header param in the target URI into INVITE header list. */
165
 
    if (PJSIP_URI_SCHEME_IS_SIP(dlg->target) ||
166
 
        PJSIP_URI_SCHEME_IS_SIPS(dlg->target))
167
 
    {
168
 
        pjsip_param *param;
169
 
        pjsip_sip_uri *uri = (pjsip_sip_uri*)pjsip_uri_get_uri(dlg->target);
170
 
 
171
 
        param = uri->header_param.next;
172
 
        while (param != &uri->header_param) {
173
 
            pjsip_hdr *hdr;
174
 
            int c;
175
 
 
176
 
            c = param->value.ptr[param->value.slen];
177
 
            param->value.ptr[param->value.slen] = '\0';
178
 
 
179
 
            hdr = (pjsip_hdr*)
180
 
                  pjsip_parse_hdr(dlg->pool, &param->name, param->value.ptr,
181
 
                                  param->value.slen, NULL);
182
 
 
183
 
            param->value.ptr[param->value.slen] = (char)c;
184
 
 
185
 
            if (hdr == NULL) {
186
 
                status = PJSIP_EINVALIDURI;
187
 
                goto on_error;
188
 
            }
189
 
            pj_list_push_back(&dlg->inv_hdr, hdr);
190
 
 
191
 
            param = param->next;
192
 
        }
193
 
 
194
 
        /* Now must remove any header params from URL, since that would
195
 
         * create another header in pjsip_endpt_create_request().
196
 
         */
197
 
        pj_list_init(&uri->header_param);
198
 
    }
199
 
 
200
 
    /* Add target to the target set */
201
 
    pjsip_target_set_add_uri(&dlg->target_set, dlg->pool, dlg->target, 0);
202
 
 
203
 
    /* Init local info. */
204
 
    dlg->local.info = pjsip_from_hdr_create(dlg->pool);
205
 
    pj_strdup_with_null(dlg->pool, &dlg->local.info_str, local_uri);
206
 
    dlg->local.info->uri = pjsip_parse_uri(dlg->pool, 
207
 
                                           dlg->local.info_str.ptr, 
208
 
                                           dlg->local.info_str.slen, 0);
209
 
    if (!dlg->local.info->uri) {
210
 
        status = PJSIP_EINVALIDURI;
211
 
        goto on_error;
212
 
    }
213
 
 
214
 
    /* Generate local tag. */
215
 
    pj_create_unique_string(dlg->pool, &dlg->local.info->tag);
216
 
 
217
 
    /* Calculate hash value of local tag. */
218
 
    dlg->local.tag_hval = pj_hash_calc(0, dlg->local.info->tag.ptr,
219
 
                                       dlg->local.info->tag.slen);
220
 
 
221
 
    /* Randomize local CSeq. */
222
 
    dlg->local.first_cseq = pj_rand() & 0x7FFF;
223
 
    dlg->local.cseq = dlg->local.first_cseq;
224
 
 
225
 
    /* Init local contact. */
226
 
    pj_strdup_with_null(dlg->pool, &tmp, 
227
 
                        local_contact ? local_contact : local_uri);
228
 
    dlg->local.contact = (pjsip_contact_hdr*)
229
 
                         pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr, 
230
 
                                         tmp.slen, NULL);
231
 
    if (!dlg->local.contact) {
232
 
        status = PJSIP_EINVALIDURI;
233
 
        goto on_error;
234
 
    }
235
 
 
236
 
    /* Init remote info. */
237
 
    dlg->remote.info = pjsip_to_hdr_create(dlg->pool);
238
 
    pj_strdup_with_null(dlg->pool, &dlg->remote.info_str, remote_uri);
239
 
    dlg->remote.info->uri = pjsip_parse_uri(dlg->pool, 
240
 
                                            dlg->remote.info_str.ptr, 
241
 
                                            dlg->remote.info_str.slen, 0);
242
 
    if (!dlg->remote.info->uri) {
243
 
        status = PJSIP_EINVALIDURI;
244
 
        goto on_error;
245
 
    }
246
 
 
247
 
    /* Remove header param from remote.info_str, if any */
248
 
    if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) ||
249
 
        PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri))
250
 
    {
251
 
        pjsip_sip_uri *sip_uri = (pjsip_sip_uri *) 
252
 
                                 pjsip_uri_get_uri(dlg->remote.info->uri);
253
 
        if (!pj_list_empty(&sip_uri->header_param)) {
254
 
            pj_str_t tmp;
255
 
 
256
 
            /* Remove all header param */
257
 
            pj_list_init(&sip_uri->header_param);
258
 
 
259
 
            /* Print URI */
260
 
            tmp.ptr = (char*) pj_pool_alloc(dlg->pool, 
261
 
                                            dlg->remote.info_str.slen);
262
 
            tmp.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
263
 
                                       sip_uri, tmp.ptr, 
264
 
                                       dlg->remote.info_str.slen);
265
 
 
266
 
            if (tmp.slen < 1) {
267
 
                status = PJSIP_EURITOOLONG;
268
 
                goto on_error;
269
 
            }
270
 
 
271
 
            /* Assign remote.info_str */
272
 
            dlg->remote.info_str = tmp;
273
 
        }
274
 
    }
275
 
 
276
 
 
277
 
    /* Initialize remote's CSeq to -1. */
278
 
    dlg->remote.cseq = dlg->remote.first_cseq = -1;
279
 
 
280
 
    /* Initial role is UAC. */
281
 
    dlg->role = PJSIP_ROLE_UAC;
282
 
 
283
 
    /* Secure? */
284
 
    dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);
285
 
 
286
 
    /* Generate Call-ID header. */
287
 
    dlg->call_id = pjsip_cid_hdr_create(dlg->pool);
288
 
    pj_create_unique_string(dlg->pool, &dlg->call_id->id);
289
 
 
290
 
    /* Initial route set is empty. */
291
 
    pj_list_init(&dlg->route_set);
292
 
 
293
 
    /* Init client authentication session. */
294
 
    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt, 
295
 
                                 dlg->pool, 0);
296
 
    if (status != PJ_SUCCESS)
297
 
        goto on_error;
298
 
 
299
 
    /* Register this dialog to user agent. */
300
 
    status = pjsip_ua_register_dlg( ua, dlg );
301
 
    if (status != PJ_SUCCESS)
302
 
        goto on_error;
303
 
 
304
 
 
305
 
    /* Done! */
306
 
    *p_dlg = dlg;
307
 
 
308
 
 
309
 
    PJ_LOG(5,(dlg->obj_name, "UAC dialog created"));
310
 
 
311
 
    return PJ_SUCCESS;
312
 
 
313
 
on_error:
314
 
    destroy_dialog(dlg);
315
 
    return status;
316
 
}
317
 
 
318
 
 
319
 
/*
320
 
 * Create UAS dialog.
321
 
 */
322
 
PJ_DEF(pj_status_t) pjsip_dlg_create_uas(   pjsip_user_agent *ua,
323
 
                                            pjsip_rx_data *rdata,
324
 
                                            const pj_str_t *contact,
325
 
                                            pjsip_dialog **p_dlg)
326
 
{
327
 
    pj_status_t status;
328
 
    pjsip_hdr *pos = NULL;
329
 
    pjsip_contact_hdr *contact_hdr;
330
 
    pjsip_rr_hdr *rr;
331
 
    pjsip_transaction *tsx = NULL;
332
 
    pj_str_t tmp;
333
 
    enum { TMP_LEN=128};
334
 
    pj_ssize_t len;
335
 
    pjsip_dialog *dlg;
336
 
 
337
 
    /* Check arguments. */
338
 
    PJ_ASSERT_RETURN(ua && rdata && p_dlg, PJ_EINVAL);
339
 
 
340
 
    /* rdata must have request message. */
341
 
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
342
 
                     PJSIP_ENOTREQUESTMSG);
343
 
 
344
 
    /* Request must not have To tag. 
345
 
     * This should have been checked in the user agent (or application?).
346
 
     */
347
 
    PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen == 0, PJ_EINVALIDOP);
348
 
                     
349
 
    /* The request must be a dialog establishing request. */
350
 
    PJ_ASSERT_RETURN(
351
 
        pjsip_method_creates_dialog(&rdata->msg_info.msg->line.req.method),
352
 
        PJ_EINVALIDOP);
353
 
 
354
 
    /* Create dialog instance. */
355
 
    status = create_dialog(ua, &dlg);
356
 
    if (status != PJ_SUCCESS)
357
 
        return status;
358
 
 
359
 
    /* Temprary string for getting the string representation of
360
 
     * both local and remote URI.
361
 
     */
362
 
    tmp.ptr = (char*) pj_pool_alloc(rdata->tp_info.pool, TMP_LEN);
363
 
 
364
 
    /* Init local info from the To header. */
365
 
    dlg->local.info = (pjsip_fromto_hdr*)
366
 
                      pjsip_hdr_clone(dlg->pool, rdata->msg_info.to);
367
 
    pjsip_fromto_hdr_set_from(dlg->local.info);
368
 
 
369
 
    /* Generate local tag. */
370
 
    pj_create_unique_string(dlg->pool, &dlg->local.info->tag);
371
 
 
372
 
 
373
 
    /* Print the local info. */
374
 
    len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
375
 
                          dlg->local.info->uri, tmp.ptr, TMP_LEN);
376
 
    if (len < 1) {
377
 
        pj_ansi_strcpy(tmp.ptr, "<-error: uri too long->");
378
 
        tmp.slen = pj_ansi_strlen(tmp.ptr);
379
 
    } else
380
 
        tmp.slen = len;
381
 
 
382
 
    /* Save the local info. */
383
 
    pj_strdup(dlg->pool, &dlg->local.info_str, &tmp);
384
 
 
385
 
    /* Calculate hash value of local tag. */
386
 
    dlg->local.tag_hval = pj_hash_calc(0, dlg->local.info->tag.ptr,
387
 
                                       dlg->local.info->tag.slen);
388
 
 
389
 
 
390
 
    /* Randomize local cseq */
391
 
    dlg->local.first_cseq = pj_rand() & 0x7FFF;
392
 
    dlg->local.cseq = dlg->local.first_cseq;
393
 
 
394
 
    /* Init local contact. */
395
 
    /* TODO:
396
 
     *  Section 12.1.1, paragraph about using SIPS URI in Contact.
397
 
     *  If the request that initiated the dialog contained a SIPS URI 
398
 
     *  in the Request-URI or in the top Record-Route header field value, 
399
 
     *  if there was any, or the Contact header field if there was no 
400
 
     *  Record-Route header field, the Contact header field in the response
401
 
     *  MUST be a SIPS URI.
402
 
     */
403
 
    if (contact) {
404
 
        pj_str_t tmp;
405
 
 
406
 
        pj_strdup_with_null(dlg->pool, &tmp, contact);
407
 
        dlg->local.contact = (pjsip_contact_hdr*)
408
 
                             pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr, 
409
 
                                             tmp.slen, NULL);
410
 
        if (!dlg->local.contact) {
411
 
            status = PJSIP_EINVALIDURI;
412
 
            goto on_error;
413
 
        }
414
 
 
415
 
    } else {
416
 
        dlg->local.contact = pjsip_contact_hdr_create(dlg->pool);
417
 
        dlg->local.contact->uri = dlg->local.info->uri;
418
 
    }
419
 
 
420
 
    /* Init remote info from the From header. */
421
 
    dlg->remote.info = (pjsip_fromto_hdr*) 
422
 
                       pjsip_hdr_clone(dlg->pool, rdata->msg_info.from);
423
 
    pjsip_fromto_hdr_set_to(dlg->remote.info);
424
 
 
425
 
    /* Print the remote info. */
426
 
    len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
427
 
                          dlg->remote.info->uri, tmp.ptr, TMP_LEN);
428
 
    if (len < 1) {
429
 
        pj_ansi_strcpy(tmp.ptr, "<-error: uri too long->");
430
 
        tmp.slen = pj_ansi_strlen(tmp.ptr);
431
 
    } else
432
 
        tmp.slen = len;
433
 
 
434
 
    /* Save the remote info. */
435
 
    pj_strdup(dlg->pool, &dlg->remote.info_str, &tmp);
436
 
 
437
 
 
438
 
    /* Init remote's contact from Contact header. 
439
 
     * Iterate the Contact URI until we find sip: or sips: scheme.
440
 
     */
441
 
    do {
442
 
        contact_hdr = (pjsip_contact_hdr*)
443
 
                      pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
444
 
                                         pos);
445
 
        if (contact_hdr) {
446
 
            if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && 
447
 
                !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri))
448
 
            {
449
 
                pos = (pjsip_hdr*)contact_hdr->next;
450
 
                if (pos == &rdata->msg_info.msg->hdr)
451
 
                    contact_hdr = NULL;
452
 
            } else {
453
 
                break;
454
 
            }
455
 
        }
456
 
    } while (contact_hdr);
457
 
 
458
 
    if (!contact_hdr) {
459
 
        status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
460
 
        goto on_error;
461
 
    }
462
 
 
463
 
    dlg->remote.contact = (pjsip_contact_hdr*) 
464
 
                          pjsip_hdr_clone(dlg->pool, (pjsip_hdr*)contact_hdr);
465
 
 
466
 
    /* Init remote's CSeq from CSeq header */
467
 
    dlg->remote.cseq = dlg->remote.first_cseq = rdata->msg_info.cseq->cseq;
468
 
 
469
 
    /* Set initial target to remote's Contact. */
470
 
    dlg->target = dlg->remote.contact->uri;
471
 
 
472
 
    /* Initial role is UAS */
473
 
    dlg->role = PJSIP_ROLE_UAS;
474
 
 
475
 
    /* Secure? 
476
 
     *  RFC 3261 Section 12.1.1:
477
 
     *  If the request arrived over TLS, and the Request-URI contained a 
478
 
     *  SIPS URI, the 'secure' flag is set to TRUE.
479
 
     */
480
 
    dlg->secure = PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport) &&
481
 
                  PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri);
482
 
 
483
 
    /* Call-ID */
484
 
    dlg->call_id = (pjsip_cid_hdr*) 
485
 
                   pjsip_hdr_clone(dlg->pool, rdata->msg_info.cid);
486
 
 
487
 
    /* Route set. 
488
 
     *  RFC 3261 Section 12.1.1:
489
 
     *  The route set MUST be set to the list of URIs in the Record-Route 
490
 
     *  header field from the request, taken in order and preserving all URI 
491
 
     *  parameters. If no Record-Route header field is present in the request,
492
 
     * the route set MUST be set to the empty set.
493
 
     */
494
 
    pj_list_init(&dlg->route_set);
495
 
    rr = rdata->msg_info.record_route;
496
 
    while (rr != NULL) {
497
 
        pjsip_route_hdr *route;
498
 
 
499
 
        /* Clone the Record-Route, change the type to Route header. */
500
 
        route = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, rr);
501
 
        pjsip_routing_hdr_set_route(route);
502
 
 
503
 
        /* Add to route set. */
504
 
        pj_list_push_back(&dlg->route_set, route);
505
 
 
506
 
        /* Find next Record-Route header. */
507
 
        rr = rr->next;
508
 
        if (rr == (void*)&rdata->msg_info.msg->hdr)
509
 
            break;
510
 
        rr = (pjsip_route_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, 
511
 
                                                   PJSIP_H_RECORD_ROUTE, rr);
512
 
    }
513
 
    dlg->route_set_frozen = PJ_TRUE;
514
 
 
515
 
    /* Init client authentication session. */
516
 
    status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
517
 
                                 dlg->pool, 0);
518
 
    if (status != PJ_SUCCESS)
519
 
        goto on_error;
520
 
 
521
 
    /* Create UAS transaction for this request. */
522
 
    status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);
523
 
    if (status != PJ_SUCCESS)
524
 
        goto on_error;
525
 
 
526
 
    /* Associate this dialog to the transaction. */
527
 
    tsx->mod_data[dlg->ua->id] = dlg;
528
 
 
529
 
    /* Increment tsx counter */
530
 
    ++dlg->tsx_count;
531
 
 
532
 
    /* Calculate hash value of remote tag. */
533
 
    dlg->remote.tag_hval = pj_hash_calc(0, dlg->remote.info->tag.ptr, 
534
 
                                        dlg->remote.info->tag.slen);
535
 
 
536
 
    /* Register this dialog to user agent. */
537
 
    status = pjsip_ua_register_dlg( ua, dlg );
538
 
    if (status != PJ_SUCCESS)
539
 
        goto on_error;
540
 
 
541
 
    /* Put this dialog in rdata's mod_data */
542
 
    rdata->endpt_info.mod_data[ua->id] = dlg;
543
 
 
544
 
    PJ_TODO(DIALOG_APP_TIMER);
545
 
 
546
 
    /* Feed the first request to the transaction. */
547
 
    pjsip_tsx_recv_msg(tsx, rdata);
548
 
 
549
 
    /* Done. */
550
 
    *p_dlg = dlg;
551
 
    PJ_LOG(5,(dlg->obj_name, "UAS dialog created"));
552
 
    return PJ_SUCCESS;
553
 
 
554
 
on_error:
555
 
    if (tsx) {
556
 
        pjsip_tsx_terminate(tsx, 500);
557
 
        pj_assert(dlg->tsx_count>0);
558
 
        --dlg->tsx_count;
559
 
    }
560
 
 
561
 
    destroy_dialog(dlg);
562
 
    return status;
563
 
}
564
 
 
565
 
 
566
 
/*
567
 
 * Bind dialog to a specific transport/listener.
568
 
 */
569
 
PJ_DEF(pj_status_t) pjsip_dlg_set_transport( pjsip_dialog *dlg,
570
 
                                             const pjsip_tpselector *sel)
571
 
{
572
 
    /* Validate */
573
 
    PJ_ASSERT_RETURN(dlg && sel, PJ_EINVAL);
574
 
 
575
 
    /* Start locking the dialog. */
576
 
    pjsip_dlg_inc_lock(dlg);
577
 
 
578
 
    /* Decrement reference counter of previous transport selector */
579
 
    pjsip_tpselector_dec_ref(&dlg->tp_sel);
580
 
 
581
 
    /* Copy transport selector structure .*/
582
 
    pj_memcpy(&dlg->tp_sel, sel, sizeof(*sel));
583
 
 
584
 
    /* Increment reference counter */
585
 
    pjsip_tpselector_add_ref(&dlg->tp_sel);
586
 
 
587
 
    /* Unlock dialog. */
588
 
    pjsip_dlg_dec_lock(dlg);
589
 
 
590
 
    return PJ_SUCCESS;
591
 
}
592
 
 
593
 
 
594
 
/*
595
 
 * Create forked dialog from a response.
596
 
 */
597
 
PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
598
 
                                    const pjsip_rx_data *rdata,
599
 
                                    pjsip_dialog **new_dlg )
600
 
{
601
 
    pjsip_dialog *dlg;
602
 
    const pjsip_msg *msg = rdata->msg_info.msg;
603
 
    const pjsip_hdr *end_hdr, *hdr;
604
 
    const pjsip_contact_hdr *contact;
605
 
    pj_status_t status;
606
 
 
607
 
    /* Check arguments. */
608
 
    PJ_ASSERT_RETURN(first_dlg && rdata && new_dlg, PJ_EINVAL);
609
 
    
610
 
    /* rdata must be response message. */
611
 
    PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG,
612
 
                     PJSIP_ENOTRESPONSEMSG);
613
 
 
614
 
    /* Status code MUST be 1xx (but not 100), or 2xx */
615
 
    status = msg->line.status.code;
616
 
    PJ_ASSERT_RETURN( (status/100==1 && status!=100) ||
617
 
                      (status/100==2), PJ_EBUG);
618
 
 
619
 
    /* To tag must present in the response. */
620
 
    PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen != 0, PJSIP_EMISSINGTAG);
621
 
 
622
 
    /* Find Contact header in the response */
623
 
    contact = (const pjsip_contact_hdr*)
624
 
              pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
625
 
    if (contact == NULL)
626
 
        return PJSIP_EMISSINGHDR;
627
 
 
628
 
    /* Create the dialog. */
629
 
    status = create_dialog((pjsip_user_agent*)first_dlg->ua, &dlg);
630
 
    if (status != PJ_SUCCESS)
631
 
        return status;
632
 
 
633
 
    /* Set remote target from the response. */
634
 
    dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, contact->uri);
635
 
 
636
 
    /* Clone local info. */
637
 
    dlg->local.info = (pjsip_fromto_hdr*) 
638
 
                      pjsip_hdr_clone(dlg->pool, first_dlg->local.info);
639
 
 
640
 
    /* Clone local tag. */
641
 
    pj_strdup(dlg->pool, &dlg->local.info->tag, &first_dlg->local.info->tag);
642
 
    dlg->local.tag_hval = first_dlg->local.tag_hval;
643
 
 
644
 
    /* Clone local CSeq. */
645
 
    dlg->local.first_cseq = first_dlg->local.first_cseq;
646
 
    dlg->local.cseq = first_dlg->local.cseq;
647
 
 
648
 
    /* Clone local Contact. */
649
 
    dlg->local.contact = (pjsip_contact_hdr*) 
650
 
                         pjsip_hdr_clone(dlg->pool, first_dlg->local.contact);
651
 
 
652
 
    /* Clone remote info. */
653
 
    dlg->remote.info = (pjsip_fromto_hdr*) 
654
 
                       pjsip_hdr_clone(dlg->pool, first_dlg->remote.info);
655
 
 
656
 
    /* Set remote tag from the response. */
657
 
    pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);
658
 
 
659
 
    /* Initialize remote's CSeq to -1. */
660
 
    dlg->remote.cseq = dlg->remote.first_cseq = -1;
661
 
 
662
 
    /* Initial role is UAC. */
663
 
    dlg->role = PJSIP_ROLE_UAC;
664
 
 
665
 
    /* Dialog state depends on the response. */
666
 
    status = msg->line.status.code/100;
667
 
    if (status == 1 || status == 2)
668
 
        dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
669
 
    else {
670
 
        pj_assert(!"Invalid status code");
671
 
        dlg->state = PJSIP_DIALOG_STATE_NULL;
672
 
    }
673
 
 
674
 
    /* Secure? */
675
 
    dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);
676
 
 
677
 
    /* Clone Call-ID header. */
678
 
    dlg->call_id = (pjsip_cid_hdr*) 
679
 
                   pjsip_hdr_clone(dlg->pool, first_dlg->call_id);
680
 
 
681
 
    /* Get route-set from the response. */
682
 
    pj_list_init(&dlg->route_set);
683
 
    end_hdr = &msg->hdr;
684
 
    for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {
685
 
        if (hdr->type == PJSIP_H_RECORD_ROUTE) {
686
 
            pjsip_route_hdr *r;
687
 
            r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);
688
 
            pjsip_routing_hdr_set_route(r);
689
 
            pj_list_push_back(&dlg->route_set, r);
690
 
        }
691
 
    }
692
 
 
693
 
    //dlg->route_set_frozen = PJ_TRUE;
694
 
 
695
 
    /* Clone client authentication session. */
696
 
    status = pjsip_auth_clt_clone(dlg->pool, &dlg->auth_sess, 
697
 
                                  &first_dlg->auth_sess);
698
 
    if (status != PJ_SUCCESS)
699
 
        goto on_error;
700
 
 
701
 
    /* Register this dialog to user agent. */
702
 
    status = pjsip_ua_register_dlg(dlg->ua, dlg );
703
 
    if (status != PJ_SUCCESS)
704
 
        goto on_error;
705
 
 
706
 
 
707
 
    /* Done! */
708
 
    *new_dlg = dlg;
709
 
 
710
 
    PJ_LOG(5,(dlg->obj_name, "Forked dialog created"));
711
 
    return PJ_SUCCESS;
712
 
 
713
 
on_error:
714
 
    destroy_dialog(dlg);
715
 
    return status;
716
 
}
717
 
 
718
 
 
719
 
/*
720
 
 * Destroy dialog.
721
 
 */
722
 
static pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg )
723
 
{
724
 
    pj_status_t status;
725
 
 
726
 
    /* Lock must have been held. */
727
 
 
728
 
    /* Check dialog state. */
729
 
    /* Number of sessions must be zero. */
730
 
    PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);
731
 
 
732
 
    /* MUST not have pending transactions. */
733
 
    PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);
734
 
 
735
 
    /* Unregister from user agent. */
736
 
    status = pjsip_ua_unregister_dlg(dlg->ua, dlg);
737
 
    if (status != PJ_SUCCESS) {
738
 
        pj_assert(!"Unexpected failed unregistration!");
739
 
        return status;
740
 
    }
741
 
 
742
 
    /* Log */
743
 
    PJ_LOG(5,(dlg->obj_name, "Dialog destroyed"));
744
 
 
745
 
    /* Destroy this dialog. */
746
 
    destroy_dialog(dlg);
747
 
 
748
 
    return PJ_SUCCESS;
749
 
}
750
 
 
751
 
 
752
 
/*
753
 
 * Forcefully terminate dialog.
754
 
 */
755
 
PJ_DEF(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg )
756
 
{
757
 
    /* Number of sessions must be zero. */
758
 
    PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);
759
 
 
760
 
    /* MUST not have pending transactions. */
761
 
    PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);
762
 
 
763
 
    return unregister_and_destroy_dialog(dlg);
764
 
}
765
 
 
766
 
 
767
 
/*
768
 
 * Set route_set
769
 
 */
770
 
PJ_DEF(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,
771
 
                                             const pjsip_route_hdr *route_set )
772
 
{
773
 
    pjsip_route_hdr *r;
774
 
 
775
 
    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
776
 
 
777
 
    pjsip_dlg_inc_lock(dlg);
778
 
 
779
 
    /* Clear route set. */
780
 
    pj_list_init(&dlg->route_set);
781
 
 
782
 
    if (!route_set) {
783
 
        pjsip_dlg_dec_lock(dlg);
784
 
        return PJ_SUCCESS;
785
 
    }
786
 
 
787
 
    r = route_set->next;
788
 
    while (r != route_set) {
789
 
        pjsip_route_hdr *new_r;
790
 
 
791
 
        new_r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, r);
792
 
        pj_list_push_back(&dlg->route_set, new_r);
793
 
 
794
 
        r = r->next;
795
 
    }
796
 
 
797
 
    pjsip_dlg_dec_lock(dlg);
798
 
    return PJ_SUCCESS;
799
 
}
800
 
 
801
 
 
802
 
/*
803
 
 * Increment session counter.
804
 
 */
805
 
PJ_DEF(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
806
 
                                           pjsip_module *mod )
807
 
{
808
 
    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
809
 
 
810
 
    pjsip_dlg_inc_lock(dlg);
811
 
    ++dlg->sess_count;
812
 
    pjsip_dlg_dec_lock(dlg);
813
 
 
814
 
    PJ_LOG(5,(dlg->obj_name, "Session count inc to %d by %.*s",
815
 
              dlg->sess_count, (int)mod->name.slen, mod->name.ptr));
816
 
 
817
 
    return PJ_SUCCESS;
818
 
}
819
 
 
820
 
/*
821
 
 * Lock dialog and increment session counter temporarily
822
 
 * to prevent it from being deleted. In addition, it must lock
823
 
 * the user agent's dialog table first, to prevent deadlock.
824
 
 */
825
 
PJ_DEF(void) pjsip_dlg_inc_lock(pjsip_dialog *dlg)
826
 
{
827
 
    PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_inc_lock(), sess_count=%d", 
828
 
              dlg->sess_count));
829
 
 
830
 
    pj_mutex_lock(dlg->mutex_);
831
 
    dlg->sess_count++;
832
 
 
833
 
    PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_inc_lock(), sess_count=%d", 
834
 
              dlg->sess_count));
835
 
}
836
 
 
837
 
/* Try to acquire dialog's mutex, but bail out if mutex can not be
838
 
 * acquired immediately.
839
 
 */
840
 
PJ_DEF(pj_status_t) pjsip_dlg_try_inc_lock(pjsip_dialog *dlg)
841
 
{
842
 
    pj_status_t status;
843
 
 
844
 
    PJ_LOG(6,(dlg->obj_name,"Entering pjsip_dlg_try_inc_lock(), sess_count=%d", 
845
 
              dlg->sess_count));
846
 
 
847
 
    status = pj_mutex_trylock(dlg->mutex_);
848
 
    if (status != PJ_SUCCESS) {
849
 
        PJ_LOG(6,(dlg->obj_name, "pjsip_dlg_try_inc_lock() failed"));
850
 
        return status;
851
 
    }
852
 
 
853
 
    dlg->sess_count++;
854
 
 
855
 
    PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_try_inc_lock(), sess_count=%d", 
856
 
              dlg->sess_count));
857
 
 
858
 
    return PJ_SUCCESS;
859
 
}
860
 
 
861
 
 
862
 
/*
863
 
 * Unlock dialog and decrement session counter.
864
 
 * It may delete the dialog!
865
 
 */
866
 
PJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg)
867
 
{
868
 
    PJ_ASSERT_ON_FAIL(dlg!=NULL, return);
869
 
 
870
 
    PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_dec_lock(), sess_count=%d", 
871
 
              dlg->sess_count));
872
 
 
873
 
    pj_assert(dlg->sess_count > 0);
874
 
    --dlg->sess_count;
875
 
 
876
 
    if (dlg->sess_count==0 && dlg->tsx_count==0) {
877
 
        pj_mutex_unlock(dlg->mutex_);
878
 
        pj_mutex_lock(dlg->mutex_);
879
 
        unregister_and_destroy_dialog(dlg);
880
 
    } else {
881
 
        pj_mutex_unlock(dlg->mutex_);
882
 
    }
883
 
 
884
 
    PJ_LOG(6,(THIS_FILE, "Leaving pjsip_dlg_dec_lock() (dlg=%p)", dlg));
885
 
}
886
 
 
887
 
 
888
 
 
889
 
/*
890
 
 * Decrement session counter.
891
 
 */
892
 
PJ_DEF(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
893
 
                                           pjsip_module *mod)
894
 
{
895
 
    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
896
 
 
897
 
    PJ_LOG(5,(dlg->obj_name, "Session count dec to %d by %.*s",
898
 
              dlg->sess_count-1, (int)mod->name.slen, mod->name.ptr));
899
 
 
900
 
    pjsip_dlg_inc_lock(dlg);
901
 
    --dlg->sess_count;
902
 
    pjsip_dlg_dec_lock(dlg);
903
 
 
904
 
    return PJ_SUCCESS;
905
 
}
906
 
 
907
 
/*
908
 
 * Add usage.
909
 
 */
910
 
PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
911
 
                                         pjsip_module *mod,
912
 
                                         void *mod_data )
913
 
{
914
 
    unsigned index;
915
 
 
916
 
    PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
917
 
    PJ_ASSERT_RETURN(mod->id >= 0 && mod->id < PJSIP_MAX_MODULE,
918
 
                     PJ_EINVAL);
919
 
    PJ_ASSERT_RETURN(dlg->usage_cnt < PJSIP_MAX_MODULE, PJ_EBUG);
920
 
 
921
 
    PJ_LOG(5,(dlg->obj_name, 
922
 
              "Module %.*s added as dialog usage, data=%p",
923
 
              (int)mod->name.slen, mod->name.ptr, mod_data));
924
 
 
925
 
    pjsip_dlg_inc_lock(dlg);
926
 
 
927
 
    /* Usages are sorted on priority, lowest number first.
928
 
     * Find position to put the new module, also makes sure that
929
 
     * this module has not been registered before.
930
 
     */
931
 
    for (index=0; index<dlg->usage_cnt; ++index) {
932
 
        if (dlg->usage[index] == mod) {
933
 
            /* Module may be registered more than once in the same dialog.
934
 
             * For example, when call transfer fails, application may retry
935
 
             * call transfer on the same dialog.
936
 
             * So return PJ_SUCCESS here.
937
 
             */
938
 
            PJ_LOG(4,(dlg->obj_name, 
939
 
                      "Module %.*s already registered as dialog usage, "
940
 
                      "updating the data %p",
941
 
                      (int)mod->name.slen, mod->name.ptr, mod_data));
942
 
            dlg->mod_data[mod->id] = mod_data;
943
 
 
944
 
            pjsip_dlg_dec_lock(dlg);
945
 
            return PJ_SUCCESS;
946
 
 
947
 
            //pj_assert(!"This module is already registered");
948
 
            //pjsip_dlg_dec_lock(dlg);
949
 
            //return PJSIP_ETYPEEXISTS;
950
 
        }
951
 
 
952
 
        if (dlg->usage[index]->priority > mod->priority)
953
 
            break;
954
 
    }
955
 
 
956
 
    /* index holds position to put the module.
957
 
     * Insert module at this index.
958
 
     */
959
 
    pj_array_insert(dlg->usage, sizeof(dlg->usage[0]), dlg->usage_cnt,
960
 
                    index, &mod);
961
 
    
962
 
    /* Set module data. */
963
 
    dlg->mod_data[mod->id] = mod_data;
964
 
 
965
 
    /* Increment count. */
966
 
    ++dlg->usage_cnt;
967
 
 
968
 
    pjsip_dlg_dec_lock(dlg);
969
 
 
970
 
    return PJ_SUCCESS;
971
 
}
972
 
 
973
 
 
974
 
/*
975
 
 * Attach module specific data to the dialog. Application can also set 
976
 
 * the value directly by accessing dlg->mod_data[module_id].
977
 
 */
978
 
PJ_DEF(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,
979
 
                                            int mod_id,
980
 
                                            void *data )
981
 
{
982
 
    PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
983
 
    PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,
984
 
                     PJ_EINVAL);
985
 
    dlg->mod_data[mod_id] = data;
986
 
    return PJ_SUCCESS;
987
 
}
988
 
 
989
 
/**
990
 
 * Get module specific data previously attached to the dialog. Application
991
 
 * can also get value directly by accessing dlg->mod_data[module_id].
992
 
 */
993
 
PJ_DEF(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,
994
 
                                      int mod_id)
995
 
{
996
 
    PJ_ASSERT_RETURN(dlg, NULL);
997
 
    PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,
998
 
                     NULL);
999
 
    return dlg->mod_data[mod_id];
1000
 
}
1001
 
 
1002
 
 
1003
 
/*
1004
 
 * Create a new request within dialog (i.e. after the dialog session has been
1005
 
 * established). The construction of such requests follows the rule in 
1006
 
 * RFC3261 section 12.2.1.
1007
 
 */
1008
 
static pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,
1009
 
                                             const pjsip_method *method,
1010
 
                                             int cseq,
1011
 
                                             pjsip_tx_data **p_tdata )
1012
 
{
1013
 
    pjsip_tx_data *tdata;
1014
 
    pjsip_contact_hdr *contact;
1015
 
    pjsip_route_hdr *route, *end_list;
1016
 
    pj_status_t status;
1017
 
 
1018
 
    /* Contact Header field.
1019
 
     * Contact can only be present in requests that establish dialog (in the 
1020
 
     * core SIP spec, only INVITE).
1021
 
     */
1022
 
    if (pjsip_method_creates_dialog(method))
1023
 
        contact = dlg->local.contact;
1024
 
    else
1025
 
        contact = NULL;
1026
 
 
1027
 
    /*
1028
 
     * Create the request by cloning from the headers in the
1029
 
     * dialog.
1030
 
     */
1031
 
    status = pjsip_endpt_create_request_from_hdr(dlg->endpt,
1032
 
                                                 method,
1033
 
                                                 dlg->target,
1034
 
                                                 dlg->local.info,
1035
 
                                                 dlg->remote.info,
1036
 
                                                 contact,
1037
 
                                                 dlg->call_id,
1038
 
                                                 cseq,
1039
 
                                                 NULL,
1040
 
                                                 &tdata);
1041
 
    if (status != PJ_SUCCESS)
1042
 
        return status;
1043
 
 
1044
 
    /* Just copy dialog route-set to Route header. 
1045
 
     * The transaction will do the processing as specified in Section 12.2.1
1046
 
     * of RFC 3261 in function tsx_process_route() in sip_transaction.c.
1047
 
     */
1048
 
    route = dlg->route_set.next;
1049
 
    end_list = &dlg->route_set;
1050
 
    for (; route != end_list; route = route->next ) {
1051
 
        pjsip_route_hdr *r;
1052
 
        r = (pjsip_route_hdr*) pjsip_hdr_shallow_clone( tdata->pool, route );
1053
 
        pjsip_routing_hdr_set_route(r);
1054
 
        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)r);
1055
 
    }
1056
 
 
1057
 
    /* Copy authorization headers, if request is not ACK or CANCEL. */
1058
 
    if (method->id != PJSIP_ACK_METHOD && method->id != PJSIP_CANCEL_METHOD) {
1059
 
        status = pjsip_auth_clt_init_req( &dlg->auth_sess, tdata );
1060
 
        if (status != PJ_SUCCESS)
1061
 
            return status;
1062
 
    }
1063
 
 
1064
 
    /* Done. */
1065
 
    *p_tdata = tdata;
1066
 
 
1067
 
    return PJ_SUCCESS;
1068
 
}
1069
 
 
1070
 
 
1071
 
 
1072
 
/*
1073
 
 * Create outgoing request.
1074
 
 */
1075
 
PJ_DEF(pj_status_t) pjsip_dlg_create_request( pjsip_dialog *dlg,
1076
 
                                              const pjsip_method *method,
1077
 
                                              int cseq,
1078
 
                                              pjsip_tx_data **p_tdata)
1079
 
{
1080
 
    pj_status_t status;
1081
 
    pjsip_tx_data *tdata = NULL;
1082
 
    PJ_USE_EXCEPTION;
1083
 
 
1084
 
    PJ_ASSERT_RETURN(dlg && method && p_tdata, PJ_EINVAL);
1085
 
 
1086
 
    /* Lock dialog. */
1087
 
    pjsip_dlg_inc_lock(dlg);
1088
 
 
1089
 
    /* Use outgoing CSeq and increment it by one. */
1090
 
    if (cseq < 0)
1091
 
        cseq = dlg->local.cseq + 1;
1092
 
 
1093
 
    /* Keep compiler happy */
1094
 
    status = PJ_EBUG;
1095
 
 
1096
 
    /* Create the request. */
1097
 
    PJ_TRY {
1098
 
        status = dlg_create_request_throw(dlg, method, cseq, &tdata);
1099
 
    }
1100
 
    PJ_CATCH_ANY {
1101
 
        status = PJ_ENOMEM;
1102
 
    }
1103
 
    PJ_END;
1104
 
 
1105
 
    /* Failed! Delete transmit data. */
1106
 
    if (status != PJ_SUCCESS && tdata) {
1107
 
        pjsip_tx_data_dec_ref( tdata );
1108
 
        tdata = NULL;
1109
 
    }
1110
 
 
1111
 
    /* Unlock dialog. */
1112
 
    pjsip_dlg_dec_lock(dlg);
1113
 
 
1114
 
    *p_tdata = tdata;
1115
 
 
1116
 
    return status;
1117
 
}
1118
 
 
1119
 
 
1120
 
/*
1121
 
 * Send request statefully, and update dialog'c CSeq.
1122
 
 */
1123
 
PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
1124
 
                                            pjsip_tx_data *tdata,
1125
 
                                            int mod_data_id,
1126
 
                                            void *mod_data)
1127
 
{
1128
 
    pjsip_transaction *tsx;
1129
 
    pjsip_msg *msg = tdata->msg;
1130
 
    pj_status_t status;
1131
 
 
1132
 
    /* Check arguments. */
1133
 
    PJ_ASSERT_RETURN(dlg && tdata && tdata->msg, PJ_EINVAL);
1134
 
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
1135
 
                     PJSIP_ENOTREQUESTMSG);
1136
 
 
1137
 
    PJ_LOG(5,(dlg->obj_name, "Sending %s",
1138
 
              pjsip_tx_data_get_info(tdata)));
1139
 
 
1140
 
    /* Lock and increment session */
1141
 
    pjsip_dlg_inc_lock(dlg);
1142
 
 
1143
 
    /* Update dialog's CSeq and message's CSeq if request is not
1144
 
     * ACK nor CANCEL.
1145
 
     */
1146
 
    if (msg->line.req.method.id != PJSIP_CANCEL_METHOD &&
1147
 
        msg->line.req.method.id != PJSIP_ACK_METHOD) 
1148
 
    {
1149
 
        pjsip_cseq_hdr *ch;
1150
 
        
1151
 
        ch = PJSIP_MSG_CSEQ_HDR(msg);
1152
 
        PJ_ASSERT_RETURN(ch!=NULL, PJ_EBUG);
1153
 
 
1154
 
        ch->cseq = dlg->local.cseq++;
1155
 
 
1156
 
        /* Force the whole message to be re-printed. */
1157
 
        pjsip_tx_data_invalidate_msg( tdata );
1158
 
    }
1159
 
 
1160
 
    /* Create a new transaction if method is not ACK.
1161
 
     * The transaction user is the user agent module.
1162
 
     */
1163
 
    if (msg->line.req.method.id != PJSIP_ACK_METHOD) {
1164
 
        int tsx_count;
1165
 
 
1166
 
        status = pjsip_tsx_create_uac(dlg->ua, tdata, &tsx);
1167
 
        if (status != PJ_SUCCESS)
1168
 
            goto on_error;
1169
 
 
1170
 
        /* Set transport selector */
1171
 
        status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
1172
 
        pj_assert(status == PJ_SUCCESS);
1173
 
 
1174
 
        /* Attach this dialog to the transaction, so that user agent
1175
 
         * will dispatch events to this dialog.
1176
 
         */
1177
 
        tsx->mod_data[dlg->ua->id] = dlg;
1178
 
 
1179
 
        /* Copy optional caller's mod_data, if present */
1180
 
        if (mod_data_id >= 0 && mod_data_id < PJSIP_MAX_MODULE)
1181
 
            tsx->mod_data[mod_data_id] = mod_data;
1182
 
 
1183
 
        /* Increment transaction counter. */
1184
 
        tsx_count = ++dlg->tsx_count;
1185
 
 
1186
 
        /* Send the message. */
1187
 
        status = pjsip_tsx_send_msg(tsx, tdata);
1188
 
        if (status != PJ_SUCCESS) {
1189
 
            if (dlg->tsx_count == tsx_count)
1190
 
                pjsip_tsx_terminate(tsx, tsx->status_code);
1191
 
            goto on_error;
1192
 
        }
1193
 
 
1194
 
    } else {
1195
 
        /* Set transport selector */
1196
 
        pjsip_tx_data_set_transport(tdata, &dlg->tp_sel);
1197
 
 
1198
 
        /* Send request */
1199
 
        status = pjsip_endpt_send_request_stateless(dlg->endpt, tdata, 
1200
 
                                                    NULL, NULL);
1201
 
        if (status != PJ_SUCCESS)
1202
 
            goto on_error;
1203
 
 
1204
 
    }
1205
 
 
1206
 
    /* Unlock dialog, may destroy dialog. */
1207
 
    pjsip_dlg_dec_lock(dlg);
1208
 
 
1209
 
    return PJ_SUCCESS;
1210
 
 
1211
 
on_error:
1212
 
    /* Unlock dialog, may destroy dialog. */
1213
 
    pjsip_dlg_dec_lock(dlg);
1214
 
   
1215
 
    /* Whatever happen delete the message. */
1216
 
    pjsip_tx_data_dec_ref( tdata );
1217
 
 
1218
 
    return status;
1219
 
}
1220
 
 
1221
 
/* Add standard headers for certain types of response */
1222
 
static void dlg_beautify_response(pjsip_dialog *dlg,
1223
 
                                  pj_bool_t add_headers,
1224
 
                                  int st_code,
1225
 
                                  pjsip_tx_data *tdata)
1226
 
{
1227
 
    pjsip_cseq_hdr *cseq;
1228
 
    int st_class;
1229
 
    const pjsip_hdr *c_hdr;
1230
 
    pjsip_hdr *hdr;
1231
 
 
1232
 
    cseq = PJSIP_MSG_CSEQ_HDR(tdata->msg);
1233
 
    pj_assert(cseq != NULL);
1234
 
 
1235
 
    st_class = st_code / 100;
1236
 
 
1237
 
    /* Contact, Allow, Supported header. */
1238
 
    if (add_headers && pjsip_method_creates_dialog(&cseq->method)) {
1239
 
        /* Add Contact header for 1xx, 2xx, 3xx and 485 response. */
1240
 
        if (st_class==2 || st_class==3 || (st_class==1 && st_code != 100) ||
1241
 
            st_code==485) 
1242
 
        {
1243
 
            /* Add contact header only if one is not present. */
1244
 
            if (pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL) == 0 &&
1245
 
                pjsip_msg_find_hdr_by_name(tdata->msg, &HCONTACT, NULL) == 0) 
1246
 
            {
1247
 
                hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, 
1248
 
                                                   dlg->local.contact);
1249
 
                pjsip_msg_add_hdr(tdata->msg, hdr);
1250
 
            }
1251
 
        }
1252
 
 
1253
 
        /* Add Allow header in 18x, 2xx and 405 response. */
1254
 
        if ((((st_code/10==18 || st_class==2) && dlg->add_allow)
1255
 
             || st_code==405) &&
1256
 
            pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ALLOW, NULL)==NULL) 
1257
 
        {
1258
 
            c_hdr = pjsip_endpt_get_capability(dlg->endpt,
1259
 
                                               PJSIP_H_ALLOW, NULL);
1260
 
            if (c_hdr) {
1261
 
                hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);
1262
 
                pjsip_msg_add_hdr(tdata->msg, hdr);
1263
 
            }
1264
 
        }
1265
 
 
1266
 
        /* Add Supported header in 2xx response. */
1267
 
        if (st_class==2 && 
1268
 
            pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL)==NULL) 
1269
 
        {
1270
 
            c_hdr = pjsip_endpt_get_capability(dlg->endpt,
1271
 
                                               PJSIP_H_SUPPORTED, NULL);
1272
 
            if (c_hdr) {
1273
 
                hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);
1274
 
                pjsip_msg_add_hdr(tdata->msg, hdr);
1275
 
            }
1276
 
        }
1277
 
 
1278
 
    }
1279
 
 
1280
 
    /* Add To tag in all responses except 100 */
1281
 
    if (st_code != 100) {
1282
 
        pjsip_to_hdr *to;
1283
 
 
1284
 
        to = PJSIP_MSG_TO_HDR(tdata->msg);
1285
 
        pj_assert(to != NULL);
1286
 
 
1287
 
        to->tag = dlg->local.info->tag;
1288
 
 
1289
 
        if (dlg->state == PJSIP_DIALOG_STATE_NULL)
1290
 
            dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
1291
 
    }
1292
 
}
1293
 
 
1294
 
 
1295
 
/*
1296
 
 * Create response.
1297
 
 */
1298
 
PJ_DEF(pj_status_t) pjsip_dlg_create_response(  pjsip_dialog *dlg,
1299
 
                                                pjsip_rx_data *rdata,
1300
 
                                                int st_code,
1301
 
                                                const pj_str_t *st_text,
1302
 
                                                pjsip_tx_data **p_tdata)
1303
 
{
1304
 
    pj_status_t status;
1305
 
    pjsip_tx_data *tdata;
1306
 
 
1307
 
    /* Create generic response.
1308
 
     * This will initialize response's Via, To, From, Call-ID, CSeq
1309
 
     * and Record-Route headers from the request.
1310
 
     */
1311
 
    status = pjsip_endpt_create_response(dlg->endpt,
1312
 
                                         rdata, st_code, st_text, &tdata);
1313
 
    if (status != PJ_SUCCESS)
1314
 
        return status;
1315
 
 
1316
 
    /* Lock the dialog. */
1317
 
    pjsip_dlg_inc_lock(dlg);
1318
 
 
1319
 
    dlg_beautify_response(dlg, PJ_FALSE, st_code, tdata);
1320
 
 
1321
 
    /* Unlock the dialog. */
1322
 
    pjsip_dlg_dec_lock(dlg);
1323
 
 
1324
 
    /* Done. */
1325
 
    *p_tdata = tdata;
1326
 
    return PJ_SUCCESS;
1327
 
}
1328
 
 
1329
 
/*
1330
 
 * Modify response.
1331
 
 */
1332
 
PJ_DEF(pj_status_t) pjsip_dlg_modify_response(  pjsip_dialog *dlg,
1333
 
                                                pjsip_tx_data *tdata,
1334
 
                                                int st_code,
1335
 
                                                const pj_str_t *st_text)
1336
 
{
1337
 
    pjsip_hdr *hdr;
1338
 
 
1339
 
    PJ_ASSERT_RETURN(dlg && tdata && tdata->msg, PJ_EINVAL);
1340
 
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,
1341
 
                     PJSIP_ENOTRESPONSEMSG);
1342
 
    PJ_ASSERT_RETURN(st_code >= 100 && st_code <= 699, PJ_EINVAL);
1343
 
 
1344
 
    /* Lock and increment session */
1345
 
    pjsip_dlg_inc_lock(dlg);
1346
 
 
1347
 
    /* Replace status code and reason */
1348
 
    tdata->msg->line.status.code = st_code;
1349
 
    if (st_text) {
1350
 
        pj_strdup(tdata->pool, &tdata->msg->line.status.reason, st_text);
1351
 
    } else {
1352
 
        tdata->msg->line.status.reason = *pjsip_get_status_text(st_code);
1353
 
    }
1354
 
 
1355
 
    /* Remove existing Contact header (without this, when dialog sent 
1356
 
     * 180 and then 302, the Contact in 302 will not get updated).
1357
 
     */
1358
 
    hdr = (pjsip_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
1359
 
    if (hdr)
1360
 
        pj_list_erase(hdr);
1361
 
 
1362
 
    /* Add tag etc. if necessary */
1363
 
    dlg_beautify_response(dlg, st_code/100 <= 2, st_code, tdata);
1364
 
 
1365
 
 
1366
 
    /* Must add reference counter, since tsx_send_msg() will decrement it */
1367
 
    pjsip_tx_data_add_ref(tdata);
1368
 
 
1369
 
    /* Force to re-print message. */
1370
 
    pjsip_tx_data_invalidate_msg(tdata);
1371
 
 
1372
 
    /* Unlock dialog and dec session, may destroy dialog. */
1373
 
    pjsip_dlg_dec_lock(dlg);
1374
 
 
1375
 
    return PJ_SUCCESS;
1376
 
}
1377
 
 
1378
 
/*
1379
 
 * Send response statefully.
1380
 
 */
1381
 
PJ_DEF(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
1382
 
                                             pjsip_transaction *tsx,
1383
 
                                             pjsip_tx_data *tdata)
1384
 
{
1385
 
    pj_status_t status;
1386
 
 
1387
 
    /* Sanity check. */
1388
 
    PJ_ASSERT_RETURN(dlg && tsx && tdata && tdata->msg, PJ_EINVAL);
1389
 
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,
1390
 
                     PJSIP_ENOTRESPONSEMSG);
1391
 
 
1392
 
    /* The transaction must belong to this dialog.  */
1393
 
    PJ_ASSERT_RETURN(tsx->mod_data[dlg->ua->id] == dlg, PJ_EINVALIDOP);
1394
 
 
1395
 
    PJ_LOG(5,(dlg->obj_name, "Sending %s",
1396
 
              pjsip_tx_data_get_info(tdata)));
1397
 
 
1398
 
    /* Check that transaction method and cseq match the response. 
1399
 
     * This operation is sloooww (search CSeq header twice), that's why
1400
 
     * we only do it in debug mode.
1401
 
     */
1402
 
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
1403
 
    PJ_ASSERT_RETURN( PJSIP_MSG_CSEQ_HDR(tdata->msg)->cseq == tsx->cseq &&
1404
 
                      pjsip_method_cmp(&PJSIP_MSG_CSEQ_HDR(tdata->msg)->method, 
1405
 
                                       &tsx->method)==0,
1406
 
                      PJ_EINVALIDOP);
1407
 
#endif
1408
 
 
1409
 
    /* Must acquire dialog first, to prevent deadlock */
1410
 
    pjsip_dlg_inc_lock(dlg);
1411
 
 
1412
 
    /* Last chance to add mandatory headers before the response is
1413
 
     * sent.
1414
 
     */
1415
 
    dlg_beautify_response(dlg, PJ_TRUE, tdata->msg->line.status.code, tdata);
1416
 
 
1417
 
    /* If the dialog is locked to transport, make sure that transaction
1418
 
     * is locked to the same transport too.
1419
 
     */
1420
 
    if (dlg->tp_sel.type != tsx->tp_sel.type ||
1421
 
        dlg->tp_sel.u.ptr != tsx->tp_sel.u.ptr)
1422
 
    {
1423
 
        status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
1424
 
        pj_assert(status == PJ_SUCCESS);
1425
 
    }
1426
 
 
1427
 
    /* Ask transaction to send the response */
1428
 
    status = pjsip_tsx_send_msg(tsx, tdata);
1429
 
 
1430
 
    /* This function must decrement transmit data request counter 
1431
 
     * regardless of the operation status. The transaction only
1432
 
     * decrements the counter if the operation is successful.
1433
 
     */
1434
 
    if (status != PJ_SUCCESS) {
1435
 
        pjsip_tx_data_dec_ref(tdata);
1436
 
    }
1437
 
 
1438
 
    pjsip_dlg_dec_lock(dlg);
1439
 
 
1440
 
    return status;
1441
 
}
1442
 
 
1443
 
 
1444
 
/*
1445
 
 * Combo function to create and send response statefully.
1446
 
 */
1447
 
PJ_DEF(pj_status_t) pjsip_dlg_respond(  pjsip_dialog *dlg,
1448
 
                                        pjsip_rx_data *rdata,
1449
 
                                        int st_code,
1450
 
                                        const pj_str_t *st_text,
1451
 
                                        const pjsip_hdr *hdr_list,
1452
 
                                        const pjsip_msg_body *body )
1453
 
{
1454
 
    pj_status_t status;
1455
 
    pjsip_tx_data *tdata;
1456
 
 
1457
 
    /* Sanity check. */
1458
 
    PJ_ASSERT_RETURN(dlg && rdata && rdata->msg_info.msg, PJ_EINVAL);
1459
 
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
1460
 
                     PJSIP_ENOTREQUESTMSG);
1461
 
 
1462
 
    /* The transaction must belong to this dialog.  */
1463
 
    PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata) &&
1464
 
                     pjsip_rdata_get_tsx(rdata)->mod_data[dlg->ua->id] == dlg,
1465
 
                     PJ_EINVALIDOP);
1466
 
 
1467
 
    /* Create the response. */
1468
 
    status = pjsip_dlg_create_response(dlg, rdata, st_code, st_text, &tdata);
1469
 
    if (status != PJ_SUCCESS)
1470
 
        return status;
1471
 
 
1472
 
    /* Add additional header, if any */
1473
 
    if (hdr_list) {
1474
 
        const pjsip_hdr *hdr;
1475
 
 
1476
 
        hdr = hdr_list->next;
1477
 
        while (hdr != hdr_list) {
1478
 
            pjsip_msg_add_hdr(tdata->msg,
1479
 
                              (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
1480
 
            hdr = hdr->next;
1481
 
        }
1482
 
    }
1483
 
 
1484
 
    /* Add the message body, if any. */
1485
 
    if (body) {
1486
 
        tdata->msg->body = pjsip_msg_body_clone( tdata->pool, body);
1487
 
    }
1488
 
 
1489
 
    /* Send the response. */
1490
 
    return pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
1491
 
}
1492
 
 
1493
 
 
1494
 
/* This function is called by user agent upon receiving incoming response
1495
 
 * message.
1496
 
 */
1497
 
void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
1498
 
{
1499
 
    pj_status_t status;
1500
 
    pjsip_transaction *tsx = NULL;
1501
 
    pj_bool_t processed = PJ_FALSE;
1502
 
    unsigned i;
1503
 
 
1504
 
    PJ_LOG(5,(dlg->obj_name, "Received %s",
1505
 
              pjsip_rx_data_get_info(rdata)));
1506
 
 
1507
 
    /* Lock dialog and increment session. */
1508
 
    pjsip_dlg_inc_lock(dlg);
1509
 
 
1510
 
    /* Check CSeq */
1511
 
    if (rdata->msg_info.cseq->cseq <= dlg->remote.cseq &&
1512
 
        rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD &&
1513
 
        rdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD) 
1514
 
    {
1515
 
        /* Invalid CSeq.
1516
 
         * Respond statelessly with 500 (Internal Server Error)
1517
 
         */
1518
 
        pj_str_t warn_text;
1519
 
 
1520
 
        /* Unlock dialog and dec session, may destroy dialog. */
1521
 
        pjsip_dlg_dec_lock(dlg);
1522
 
 
1523
 
        pj_assert(pjsip_rdata_get_tsx(rdata) == NULL);
1524
 
        warn_text = pj_str("Invalid CSeq");
1525
 
        pjsip_endpt_respond_stateless(dlg->endpt,
1526
 
                                      rdata, 500, &warn_text, NULL, NULL);
1527
 
        return;
1528
 
    }
1529
 
 
1530
 
    /* Update CSeq. */
1531
 
    dlg->remote.cseq = rdata->msg_info.cseq->cseq;
1532
 
 
1533
 
    /* Update To tag if necessary.
1534
 
     * This only happens if UAS sends a new request before answering
1535
 
     * our request (e.g. UAS sends NOTIFY before answering our
1536
 
     * SUBSCRIBE request).
1537
 
     */
1538
 
    if (dlg->remote.info->tag.slen == 0) {
1539
 
        pj_strdup(dlg->pool, &dlg->remote.info->tag,
1540
 
                  &rdata->msg_info.from->tag);
1541
 
    }
1542
 
 
1543
 
    /* Create UAS transaction for this request. */
1544
 
    if (pjsip_rdata_get_tsx(rdata) == NULL && 
1545
 
        rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) 
1546
 
    {
1547
 
        status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);
1548
 
        if (status != PJ_SUCCESS) {
1549
 
            /* Once case for this is when re-INVITE contains same
1550
 
             * Via branch value as previous INVITE (ticket #965).
1551
 
             */
1552
 
            char errmsg[PJ_ERR_MSG_SIZE];
1553
 
            pj_str_t reason;
1554
 
 
1555
 
            reason = pj_strerror(status, errmsg, sizeof(errmsg));
1556
 
            pjsip_endpt_respond_stateless(dlg->endpt, rdata, 500, &reason,
1557
 
                                          NULL, NULL);
1558
 
            goto on_return;
1559
 
        }
1560
 
 
1561
 
        /* Put this dialog in the transaction data. */
1562
 
        tsx->mod_data[dlg->ua->id] = dlg;
1563
 
 
1564
 
        /* Add transaction count. */
1565
 
        ++dlg->tsx_count;
1566
 
    }
1567
 
 
1568
 
    /* Update the target URI if this is a target refresh request.
1569
 
     * We have passed the basic checking for the request, I think we
1570
 
     * should update the target URI regardless of whether the request
1571
 
     * is accepted or not (e.g. when re-INVITE is answered with 488,
1572
 
     * we would still need to update the target URI, otherwise our
1573
 
     * target URI would be wrong, wouldn't it).
1574
 
     */
1575
 
    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method)) {
1576
 
        pjsip_contact_hdr *contact;
1577
 
 
1578
 
        contact = (pjsip_contact_hdr*)
1579
 
                  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, 
1580
 
                                     NULL);
1581
 
        if (contact && (dlg->remote.contact==NULL ||
1582
 
                        pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, 
1583
 
                                      dlg->remote.contact->uri, 
1584
 
                                      contact->uri)))
1585
 
        {
1586
 
            dlg->remote.contact = (pjsip_contact_hdr*) 
1587
 
                                  pjsip_hdr_clone(dlg->pool, contact);
1588
 
            dlg->target = dlg->remote.contact->uri;
1589
 
        }
1590
 
    }
1591
 
 
1592
 
    /* Report the request to dialog usages. */
1593
 
    for (i=0; i<dlg->usage_cnt; ++i) {
1594
 
 
1595
 
        if (!dlg->usage[i]->on_rx_request)
1596
 
            continue;
1597
 
 
1598
 
        processed = (*dlg->usage[i]->on_rx_request)(rdata);
1599
 
 
1600
 
        if (processed)
1601
 
            break;
1602
 
    }
1603
 
 
1604
 
    /* Feed the first request to the transaction. */
1605
 
    if (tsx)
1606
 
        pjsip_tsx_recv_msg(tsx, rdata);
1607
 
 
1608
 
    /* If no dialog usages has claimed the processing of the transaction,
1609
 
     * and if transaction has not sent final response, respond with
1610
 
     * 500/Internal Server Error.
1611
 
     */
1612
 
    if (!processed && tsx && tsx->status_code < 200) {
1613
 
        pjsip_tx_data *tdata;
1614
 
        const pj_str_t reason = { "Unhandled by dialog usages", 26};
1615
 
 
1616
 
        PJ_LOG(4,(tsx->obj_name, "%s was unhandled by "
1617
 
                                 "dialog usages, sending 500 response",
1618
 
                                 pjsip_rx_data_get_info(rdata)));
1619
 
 
1620
 
        status = pjsip_dlg_create_response(dlg, rdata, 500, &reason, &tdata);
1621
 
        if (status == PJ_SUCCESS) {
1622
 
            status = pjsip_dlg_send_response(dlg, tsx, tdata);
1623
 
        }
1624
 
    }
1625
 
 
1626
 
on_return:
1627
 
    /* Unlock dialog and dec session, may destroy dialog. */
1628
 
    pjsip_dlg_dec_lock(dlg);
1629
 
}
1630
 
 
1631
 
/* Update route-set from incoming message */
1632
 
static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
1633
 
{
1634
 
    const pjsip_hdr *hdr, *end_hdr;
1635
 
    pj_int32_t msg_cseq;
1636
 
    const pjsip_msg *msg;
1637
 
 
1638
 
    msg = rdata->msg_info.msg;
1639
 
    msg_cseq = rdata->msg_info.cseq->cseq;
1640
 
 
1641
 
    /* Ignore if route set has been frozen */
1642
 
    if (dlg->route_set_frozen)
1643
 
        return;
1644
 
 
1645
 
    /* Only update route set if this message belongs to the same
1646
 
     * transaction as the initial transaction that establishes dialog.
1647
 
     */
1648
 
    if (dlg->role == PJSIP_ROLE_UAC) {
1649
 
 
1650
 
        /* Ignore subsequent request from remote */
1651
 
        if (msg->type != PJSIP_RESPONSE_MSG)
1652
 
            return;
1653
 
 
1654
 
        /* Ignore subsequent responses with higher CSeq than initial CSeq.
1655
 
         * Unfortunately this would be broken when the first request is 
1656
 
         * challenged!
1657
 
         */
1658
 
        //if (msg_cseq != dlg->local.first_cseq)
1659
 
        //    return;
1660
 
 
1661
 
    } else {
1662
 
 
1663
 
        /* For callee dialog, route set should have been set by initial
1664
 
         * request and it will have been rejected by dlg->route_set_frozen
1665
 
         * check above.
1666
 
         */
1667
 
        pj_assert(!"Should not happen");
1668
 
 
1669
 
    }
1670
 
 
1671
 
    /* Based on the checks above, we should only get response message here */
1672
 
    pj_assert(msg->type == PJSIP_RESPONSE_MSG);
1673
 
 
1674
 
    /* Ignore if this is not 1xx or 2xx response */
1675
 
    if (msg->line.status.code >= 300)
1676
 
        return;
1677
 
 
1678
 
    /* Reset route set */
1679
 
    pj_list_init(&dlg->route_set);
1680
 
 
1681
 
    /* Update route set */
1682
 
    end_hdr = &msg->hdr;
1683
 
    for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {
1684
 
        if (hdr->type == PJSIP_H_RECORD_ROUTE) {
1685
 
            pjsip_route_hdr *r;
1686
 
            r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, hdr);
1687
 
            pjsip_routing_hdr_set_route(r);
1688
 
            pj_list_push_back(&dlg->route_set, r);
1689
 
        }
1690
 
    }
1691
 
 
1692
 
    PJ_LOG(5,(dlg->obj_name, "Route-set updated"));
1693
 
 
1694
 
    /* Freeze the route set only when the route set comes in 2xx response. 
1695
 
     * If it is in 1xx response, prepare to recompute the route set when 
1696
 
     * the 2xx response comes in.
1697
 
     *
1698
 
     * There is a debate whether route set should be frozen when the dialog
1699
 
     * is established with reliable provisional response, but I think
1700
 
     * it is safer to not freeze the route set (thus recompute the route set
1701
 
     * upon receiving 2xx response). Also RFC 3261 says so in 13.2.2.4.
1702
 
     *
1703
 
     * The pjsip_method_creates_dialog() check protects from wrongly 
1704
 
     * freezing the route set upon receiving 200/OK response for PRACK.
1705
 
     */
1706
 
    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1707
 
        PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200)) 
1708
 
    {
1709
 
        dlg->route_set_frozen = PJ_TRUE;
1710
 
        PJ_LOG(5,(dlg->obj_name, "Route-set frozen"));
1711
 
    }
1712
 
}
1713
 
 
1714
 
 
1715
 
/* This function is called by user agent upon receiving incoming response
1716
 
 * message.
1717
 
 */
1718
 
void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
1719
 
{
1720
 
    unsigned i;
1721
 
    int res_code;
1722
 
 
1723
 
    PJ_LOG(5,(dlg->obj_name, "Received %s",
1724
 
              pjsip_rx_data_get_info(rdata)));
1725
 
 
1726
 
    /* Lock the dialog and inc session. */
1727
 
    pjsip_dlg_inc_lock(dlg);
1728
 
 
1729
 
    /* Check that rdata already has dialog in mod_data. */
1730
 
    pj_assert(pjsip_rdata_get_dlg(rdata) == dlg);
1731
 
 
1732
 
    /* Keep the response's status code */
1733
 
    res_code = rdata->msg_info.msg->line.status.code;
1734
 
 
1735
 
    /* When we receive response that establishes dialog, update To tag, 
1736
 
     * route set and dialog target.
1737
 
     *
1738
 
     * The second condition of the "if" is a workaround for forking.
1739
 
     * Originally, the dialog takes the first To tag seen and set it as
1740
 
     * the remote tag. If the tag in 2xx response is different than this
1741
 
     * tag, ACK will be sent with wrong To tag and incoming request with
1742
 
     * this tag will be rejected with 481.
1743
 
     *
1744
 
     * The workaround for this is to take the To tag received in the
1745
 
     * 2xx response and set it as remote tag.
1746
 
     *
1747
 
     * New update:
1748
 
     * We also need to update the dialog for 1xx responses, to handle the
1749
 
     * case when 100rel is used, otherwise PRACK will be sent to the 
1750
 
     * wrong target.
1751
 
     */
1752
 
    if ((dlg->state == PJSIP_DIALOG_STATE_NULL && 
1753
 
         pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1754
 
         (res_code > 100 && res_code < 300) &&
1755
 
         rdata->msg_info.to->tag.slen) 
1756
 
         ||
1757
 
        (dlg->role==PJSIP_ROLE_UAC &&
1758
 
         !dlg->uac_has_2xx &&
1759
 
         res_code/100 <= 2 &&
1760
 
         pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1761
 
         pj_strcmp(&dlg->remote.info->tag, &rdata->msg_info.to->tag)))
1762
 
    {
1763
 
        pjsip_contact_hdr *contact;
1764
 
 
1765
 
        /* Update To tag. */
1766
 
        pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);
1767
 
        /* No need to update remote's tag_hval since its never used. */
1768
 
 
1769
 
 
1770
 
        /* RFC 3271 Section 12.1.2:
1771
 
         * The route set MUST be set to the list of URIs in the Record-Route
1772
 
         * header field from the response, taken in reverse order and 
1773
 
         * preserving all URI parameters. If no Record-Route header field 
1774
 
         * is present in the response, the route set MUST be set to the 
1775
 
         * empty set. This route set, even if empty, overrides any pre-existing
1776
 
         * route set for future requests in this dialog.
1777
 
         */
1778
 
        dlg_update_routeset(dlg, rdata);
1779
 
 
1780
 
        /* The remote target MUST be set to the URI from the Contact header 
1781
 
         * field of the response.
1782
 
         */
1783
 
        contact = (pjsip_contact_hdr*)
1784
 
                  pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, 
1785
 
                                     NULL);
1786
 
        if (contact && (dlg->remote.contact==NULL ||
1787
 
                        pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, 
1788
 
                                      dlg->remote.contact->uri, 
1789
 
                                      contact->uri)))
1790
 
        {
1791
 
            dlg->remote.contact = (pjsip_contact_hdr*) 
1792
 
                                  pjsip_hdr_clone(dlg->pool, contact);
1793
 
            dlg->target = dlg->remote.contact->uri;
1794
 
        }
1795
 
 
1796
 
        dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
1797
 
 
1798
 
        /* Prevent dialog from being updated just in case more 2xx
1799
 
         * gets through this dialog (it shouldn't happen).
1800
 
         */
1801
 
        if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx && 
1802
 
            res_code/100==2) 
1803
 
        {
1804
 
            dlg->uac_has_2xx = PJ_TRUE;
1805
 
        }
1806
 
    }
1807
 
 
1808
 
    /* Update remote target (again) when receiving 2xx response messages
1809
 
     * that's defined as target refresh. 
1810
 
     *
1811
 
     * Also upon receiving 2xx response, recheck again the route set.
1812
 
     * This is for compatibility with RFC 2543, as described in Section
1813
 
     * 13.2.2.4 of RFC 3261:
1814
 
 
1815
 
        If the dialog identifier in the 2xx response matches the dialog
1816
 
        identifier of an existing dialog, the dialog MUST be transitioned to
1817
 
        the "confirmed" state, and the route set for the dialog MUST be
1818
 
        recomputed based on the 2xx response using the procedures of Section
1819
 
        12.2.1.2. 
1820
 
 
1821
 
        Note that the only piece of state that is recomputed is the route
1822
 
        set.  Other pieces of state such as the highest sequence numbers
1823
 
        (remote and local) sent within the dialog are not recomputed.  The
1824
 
        route set only is recomputed for backwards compatibility.  RFC
1825
 
        2543 did not mandate mirroring of the Record-Route header field in
1826
 
        a 1xx, only 2xx.
1827
 
     */
1828
 
    if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1829
 
        res_code/100 == 2)
1830
 
    {
1831
 
        pjsip_contact_hdr *contact;
1832
 
 
1833
 
        contact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
1834
 
                                                          PJSIP_H_CONTACT, 
1835
 
                                                          NULL);
1836
 
        if (contact && (dlg->remote.contact==NULL ||
1837
 
                        pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, 
1838
 
                                      dlg->remote.contact->uri, 
1839
 
                                      contact->uri)))
1840
 
        {
1841
 
            dlg->remote.contact = (pjsip_contact_hdr*) 
1842
 
                                  pjsip_hdr_clone(dlg->pool, contact);
1843
 
            dlg->target = dlg->remote.contact->uri;
1844
 
        }
1845
 
 
1846
 
        dlg_update_routeset(dlg, rdata);
1847
 
    }
1848
 
 
1849
 
 
1850
 
    /* Pass to dialog usages. */
1851
 
    for (i=0; i<dlg->usage_cnt; ++i) {
1852
 
        pj_bool_t processed;
1853
 
 
1854
 
        if (!dlg->usage[i]->on_rx_response)
1855
 
            continue;
1856
 
 
1857
 
        processed = (*dlg->usage[i]->on_rx_response)(rdata);
1858
 
 
1859
 
        if (processed)
1860
 
            break;
1861
 
    }
1862
 
 
1863
 
    /* Handle the case of forked response, when the application creates
1864
 
     * the forked dialog but not the invite session. In this case, the
1865
 
     * forked 200/OK response will be unhandled, and we must send ACK
1866
 
     * here.
1867
 
     */
1868
 
    if (dlg->usage_cnt==0) {
1869
 
        pj_status_t status;
1870
 
 
1871
 
        if (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD && 
1872
 
            rdata->msg_info.msg->line.status.code/100 == 2) 
1873
 
        {
1874
 
            pjsip_tx_data *ack;
1875
 
 
1876
 
            status = pjsip_dlg_create_request(dlg, &pjsip_ack_method,
1877
 
                                              rdata->msg_info.cseq->cseq,
1878
 
                                              &ack);
1879
 
            if (status == PJ_SUCCESS)
1880
 
                status = pjsip_dlg_send_request(dlg, ack, -1, NULL);
1881
 
        } else if (rdata->msg_info.msg->line.status.code==401 ||
1882
 
                   rdata->msg_info.msg->line.status.code==407)
1883
 
        {
1884
 
            pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
1885
 
            pjsip_tx_data *tdata;
1886
 
            
1887
 
            status = pjsip_auth_clt_reinit_req( &dlg->auth_sess, 
1888
 
                                                rdata, tsx->last_tx,
1889
 
                                                &tdata);
1890
 
            
1891
 
            if (status == PJ_SUCCESS) {
1892
 
                /* Re-send request. */
1893
 
                status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
1894
 
            }
1895
 
        }
1896
 
    }
1897
 
 
1898
 
    /* Unhandled response does not necessarily mean error because
1899
 
       dialog usages may choose to process the transaction state instead.
1900
 
    if (i==dlg->usage_cnt) {
1901
 
        PJ_LOG(4,(dlg->obj_name, "%s was not claimed by any dialog usages",
1902
 
                  pjsip_rx_data_get_info(rdata)));
1903
 
    }
1904
 
    */
1905
 
 
1906
 
    /* Unlock dialog and dec session, may destroy dialog. */
1907
 
    pjsip_dlg_dec_lock(dlg);
1908
 
}
1909
 
 
1910
 
/* This function is called by user agent upon receiving transaction
1911
 
 * state notification.
1912
 
 */
1913
 
void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
1914
 
                             pjsip_transaction *tsx,
1915
 
                             pjsip_event *e )
1916
 
{
1917
 
    unsigned i;
1918
 
 
1919
 
    PJ_LOG(5,(dlg->obj_name, "Transaction %s state changed to %s",
1920
 
              tsx->obj_name, pjsip_tsx_state_str(tsx->state)));
1921
 
 
1922
 
    /* Lock the dialog and increment session. */
1923
 
    pjsip_dlg_inc_lock(dlg);
1924
 
 
1925
 
    /* Pass to dialog usages. */
1926
 
    for (i=0; i<dlg->usage_cnt; ++i) {
1927
 
 
1928
 
        if (!dlg->usage[i]->on_tsx_state)
1929
 
            continue;
1930
 
 
1931
 
        (*dlg->usage[i]->on_tsx_state)(tsx, e);
1932
 
    }
1933
 
 
1934
 
 
1935
 
    /* It is possible that the transaction is terminated and this function
1936
 
     * is called while we're calling on_tsx_state(). So only decrement
1937
 
     * the tsx_count if we're still attached to the transaction.
1938
 
     */
1939
 
    if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
1940
 
        tsx->mod_data[dlg->ua->id] == dlg) 
1941
 
    {
1942
 
        pj_assert(dlg->tsx_count>0);
1943
 
        --dlg->tsx_count;
1944
 
        tsx->mod_data[dlg->ua->id] = NULL;
1945
 
    }
1946
 
 
1947
 
    /* Unlock dialog and dec session, may destroy dialog. */
1948
 
    pjsip_dlg_dec_lock(dlg);
1949
 
}
1950