1
/* $Id: sip_dialog.c 3031 2009-12-10 05:16:23Z bennylp $ */
3
* Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
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.
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.
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
20
* Additional permission under GNU GPL version 3 section 7:
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.
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>
41
#include <pj/string.h>
46
#include <pj/except.h>
50
#define THIS_FILE "sip_dialog.c"
52
long pjsip_dlg_lock_tls_id;
55
pj_bool_t pjsip_include_allow_hdr_in_dlg = PJSIP_INCLUDE_ALLOW_HDR_IN_DLG;
57
/* Contact header string */
58
static const pj_str_t HCONTACT = { "Contact", 7 };
60
PJ_DEF(pj_bool_t) pjsip_method_creates_dialog(const pjsip_method *m)
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}};
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, ¬ify)==0) ||
71
(pjsip_method_cmp(m, &update)==0);
74
static pj_status_t create_dialog( pjsip_user_agent *ua,
77
pjsip_endpoint *endpt;
82
endpt = pjsip_ua_get_endpt(ua);
86
pool = pjsip_endpt_create_pool(endpt, "dlg%p",
87
PJSIP_POOL_LEN_DIALOG,
88
PJSIP_POOL_INC_DIALOG);
92
dlg = PJ_POOL_ZALLOC_T(pool, pjsip_dialog);
93
PJ_ASSERT_RETURN(dlg != NULL, PJ_ENOMEM);
96
pj_ansi_snprintf(dlg->obj_name, sizeof(dlg->obj_name), "dlg%p", dlg);
99
dlg->state = PJSIP_DIALOG_STATE_NULL;
100
dlg->add_allow = pjsip_include_allow_hdr_in_dlg;
102
pj_list_init(&dlg->inv_hdr);
104
status = pj_mutex_create_recursive(pool, dlg->obj_name, &dlg->mutex_);
105
if (status != PJ_SUCCESS)
108
pjsip_target_set_init(&dlg->target_set);
115
pj_mutex_destroy(dlg->mutex_);
116
pjsip_endpt_release_pool(endpt, pool);
120
static void destroy_dialog( pjsip_dialog *dlg )
123
pj_mutex_destroy(dlg->mutex_);
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));
130
pjsip_endpt_release_pool(dlg->endpt, dlg->pool);
135
* Create an UAC dialog.
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)
148
/* Check arguments. */
149
PJ_ASSERT_RETURN(ua && local_uri && remote_uri && p_dlg, PJ_EINVAL);
151
/* Create dialog instance. */
152
status = create_dialog(ua, &dlg);
153
if (status != PJ_SUCCESS)
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);
160
status = PJSIP_EINVALIDURI;
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))
169
pjsip_sip_uri *uri = (pjsip_sip_uri*)pjsip_uri_get_uri(dlg->target);
171
param = uri->header_param.next;
172
while (param != &uri->header_param) {
176
c = param->value.ptr[param->value.slen];
177
param->value.ptr[param->value.slen] = '\0';
180
pjsip_parse_hdr(dlg->pool, ¶m->name, param->value.ptr,
181
param->value.slen, NULL);
183
param->value.ptr[param->value.slen] = (char)c;
186
status = PJSIP_EINVALIDURI;
189
pj_list_push_back(&dlg->inv_hdr, hdr);
194
/* Now must remove any header params from URL, since that would
195
* create another header in pjsip_endpt_create_request().
197
pj_list_init(&uri->header_param);
200
/* Add target to the target set */
201
pjsip_target_set_add_uri(&dlg->target_set, dlg->pool, dlg->target, 0);
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;
214
/* Generate local tag. */
215
pj_create_unique_string(dlg->pool, &dlg->local.info->tag);
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);
221
/* Randomize local CSeq. */
222
dlg->local.first_cseq = pj_rand() & 0x7FFF;
223
dlg->local.cseq = dlg->local.first_cseq;
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,
231
if (!dlg->local.contact) {
232
status = PJSIP_EINVALIDURI;
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;
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))
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)) {
256
/* Remove all header param */
257
pj_list_init(&sip_uri->header_param);
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,
264
dlg->remote.info_str.slen);
267
status = PJSIP_EURITOOLONG;
271
/* Assign remote.info_str */
272
dlg->remote.info_str = tmp;
277
/* Initialize remote's CSeq to -1. */
278
dlg->remote.cseq = dlg->remote.first_cseq = -1;
280
/* Initial role is UAC. */
281
dlg->role = PJSIP_ROLE_UAC;
284
dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);
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);
290
/* Initial route set is empty. */
291
pj_list_init(&dlg->route_set);
293
/* Init client authentication session. */
294
status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
296
if (status != PJ_SUCCESS)
299
/* Register this dialog to user agent. */
300
status = pjsip_ua_register_dlg( ua, dlg );
301
if (status != PJ_SUCCESS)
309
PJ_LOG(5,(dlg->obj_name, "UAC dialog created"));
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)
328
pjsip_hdr *pos = NULL;
329
pjsip_contact_hdr *contact_hdr;
331
pjsip_transaction *tsx = NULL;
337
/* Check arguments. */
338
PJ_ASSERT_RETURN(ua && rdata && p_dlg, PJ_EINVAL);
340
/* rdata must have request message. */
341
PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
342
PJSIP_ENOTREQUESTMSG);
344
/* Request must not have To tag.
345
* This should have been checked in the user agent (or application?).
347
PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen == 0, PJ_EINVALIDOP);
349
/* The request must be a dialog establishing request. */
351
pjsip_method_creates_dialog(&rdata->msg_info.msg->line.req.method),
354
/* Create dialog instance. */
355
status = create_dialog(ua, &dlg);
356
if (status != PJ_SUCCESS)
359
/* Temprary string for getting the string representation of
360
* both local and remote URI.
362
tmp.ptr = (char*) pj_pool_alloc(rdata->tp_info.pool, TMP_LEN);
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);
369
/* Generate local tag. */
370
pj_create_unique_string(dlg->pool, &dlg->local.info->tag);
373
/* Print the local info. */
374
len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
375
dlg->local.info->uri, tmp.ptr, TMP_LEN);
377
pj_ansi_strcpy(tmp.ptr, "<-error: uri too long->");
378
tmp.slen = pj_ansi_strlen(tmp.ptr);
382
/* Save the local info. */
383
pj_strdup(dlg->pool, &dlg->local.info_str, &tmp);
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);
390
/* Randomize local cseq */
391
dlg->local.first_cseq = pj_rand() & 0x7FFF;
392
dlg->local.cseq = dlg->local.first_cseq;
394
/* Init local contact. */
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.
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,
410
if (!dlg->local.contact) {
411
status = PJSIP_EINVALIDURI;
416
dlg->local.contact = pjsip_contact_hdr_create(dlg->pool);
417
dlg->local.contact->uri = dlg->local.info->uri;
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);
425
/* Print the remote info. */
426
len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
427
dlg->remote.info->uri, tmp.ptr, TMP_LEN);
429
pj_ansi_strcpy(tmp.ptr, "<-error: uri too long->");
430
tmp.slen = pj_ansi_strlen(tmp.ptr);
434
/* Save the remote info. */
435
pj_strdup(dlg->pool, &dlg->remote.info_str, &tmp);
438
/* Init remote's contact from Contact header.
439
* Iterate the Contact URI until we find sip: or sips: scheme.
442
contact_hdr = (pjsip_contact_hdr*)
443
pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
446
if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) &&
447
!PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri))
449
pos = (pjsip_hdr*)contact_hdr->next;
450
if (pos == &rdata->msg_info.msg->hdr)
456
} while (contact_hdr);
459
status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
463
dlg->remote.contact = (pjsip_contact_hdr*)
464
pjsip_hdr_clone(dlg->pool, (pjsip_hdr*)contact_hdr);
466
/* Init remote's CSeq from CSeq header */
467
dlg->remote.cseq = dlg->remote.first_cseq = rdata->msg_info.cseq->cseq;
469
/* Set initial target to remote's Contact. */
470
dlg->target = dlg->remote.contact->uri;
472
/* Initial role is UAS */
473
dlg->role = PJSIP_ROLE_UAS;
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.
480
dlg->secure = PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport) &&
481
PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri);
484
dlg->call_id = (pjsip_cid_hdr*)
485
pjsip_hdr_clone(dlg->pool, rdata->msg_info.cid);
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.
494
pj_list_init(&dlg->route_set);
495
rr = rdata->msg_info.record_route;
497
pjsip_route_hdr *route;
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);
503
/* Add to route set. */
504
pj_list_push_back(&dlg->route_set, route);
506
/* Find next Record-Route header. */
508
if (rr == (void*)&rdata->msg_info.msg->hdr)
510
rr = (pjsip_route_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
511
PJSIP_H_RECORD_ROUTE, rr);
513
dlg->route_set_frozen = PJ_TRUE;
515
/* Init client authentication session. */
516
status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
518
if (status != PJ_SUCCESS)
521
/* Create UAS transaction for this request. */
522
status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);
523
if (status != PJ_SUCCESS)
526
/* Associate this dialog to the transaction. */
527
tsx->mod_data[dlg->ua->id] = dlg;
529
/* Increment tsx counter */
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);
536
/* Register this dialog to user agent. */
537
status = pjsip_ua_register_dlg( ua, dlg );
538
if (status != PJ_SUCCESS)
541
/* Put this dialog in rdata's mod_data */
542
rdata->endpt_info.mod_data[ua->id] = dlg;
544
PJ_TODO(DIALOG_APP_TIMER);
546
/* Feed the first request to the transaction. */
547
pjsip_tsx_recv_msg(tsx, rdata);
551
PJ_LOG(5,(dlg->obj_name, "UAS dialog created"));
556
pjsip_tsx_terminate(tsx, 500);
557
pj_assert(dlg->tsx_count>0);
567
* Bind dialog to a specific transport/listener.
569
PJ_DEF(pj_status_t) pjsip_dlg_set_transport( pjsip_dialog *dlg,
570
const pjsip_tpselector *sel)
573
PJ_ASSERT_RETURN(dlg && sel, PJ_EINVAL);
575
/* Start locking the dialog. */
576
pjsip_dlg_inc_lock(dlg);
578
/* Decrement reference counter of previous transport selector */
579
pjsip_tpselector_dec_ref(&dlg->tp_sel);
581
/* Copy transport selector structure .*/
582
pj_memcpy(&dlg->tp_sel, sel, sizeof(*sel));
584
/* Increment reference counter */
585
pjsip_tpselector_add_ref(&dlg->tp_sel);
588
pjsip_dlg_dec_lock(dlg);
595
* Create forked dialog from a response.
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 )
602
const pjsip_msg *msg = rdata->msg_info.msg;
603
const pjsip_hdr *end_hdr, *hdr;
604
const pjsip_contact_hdr *contact;
607
/* Check arguments. */
608
PJ_ASSERT_RETURN(first_dlg && rdata && new_dlg, PJ_EINVAL);
610
/* rdata must be response message. */
611
PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG,
612
PJSIP_ENOTRESPONSEMSG);
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);
619
/* To tag must present in the response. */
620
PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen != 0, PJSIP_EMISSINGTAG);
622
/* Find Contact header in the response */
623
contact = (const pjsip_contact_hdr*)
624
pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
626
return PJSIP_EMISSINGHDR;
628
/* Create the dialog. */
629
status = create_dialog((pjsip_user_agent*)first_dlg->ua, &dlg);
630
if (status != PJ_SUCCESS)
633
/* Set remote target from the response. */
634
dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, contact->uri);
636
/* Clone local info. */
637
dlg->local.info = (pjsip_fromto_hdr*)
638
pjsip_hdr_clone(dlg->pool, first_dlg->local.info);
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;
644
/* Clone local CSeq. */
645
dlg->local.first_cseq = first_dlg->local.first_cseq;
646
dlg->local.cseq = first_dlg->local.cseq;
648
/* Clone local Contact. */
649
dlg->local.contact = (pjsip_contact_hdr*)
650
pjsip_hdr_clone(dlg->pool, first_dlg->local.contact);
652
/* Clone remote info. */
653
dlg->remote.info = (pjsip_fromto_hdr*)
654
pjsip_hdr_clone(dlg->pool, first_dlg->remote.info);
656
/* Set remote tag from the response. */
657
pj_strdup(dlg->pool, &dlg->remote.info->tag, &rdata->msg_info.to->tag);
659
/* Initialize remote's CSeq to -1. */
660
dlg->remote.cseq = dlg->remote.first_cseq = -1;
662
/* Initial role is UAC. */
663
dlg->role = PJSIP_ROLE_UAC;
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;
670
pj_assert(!"Invalid status code");
671
dlg->state = PJSIP_DIALOG_STATE_NULL;
675
dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);
677
/* Clone Call-ID header. */
678
dlg->call_id = (pjsip_cid_hdr*)
679
pjsip_hdr_clone(dlg->pool, first_dlg->call_id);
681
/* Get route-set from the response. */
682
pj_list_init(&dlg->route_set);
684
for (hdr=msg->hdr.prev; hdr!=end_hdr; hdr=hdr->prev) {
685
if (hdr->type == PJSIP_H_RECORD_ROUTE) {
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);
693
//dlg->route_set_frozen = PJ_TRUE;
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)
701
/* Register this dialog to user agent. */
702
status = pjsip_ua_register_dlg(dlg->ua, dlg );
703
if (status != PJ_SUCCESS)
710
PJ_LOG(5,(dlg->obj_name, "Forked dialog created"));
722
static pj_status_t unregister_and_destroy_dialog( pjsip_dialog *dlg )
726
/* Lock must have been held. */
728
/* Check dialog state. */
729
/* Number of sessions must be zero. */
730
PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);
732
/* MUST not have pending transactions. */
733
PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);
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!");
743
PJ_LOG(5,(dlg->obj_name, "Dialog destroyed"));
745
/* Destroy this dialog. */
753
* Forcefully terminate dialog.
755
PJ_DEF(pj_status_t) pjsip_dlg_terminate( pjsip_dialog *dlg )
757
/* Number of sessions must be zero. */
758
PJ_ASSERT_RETURN(dlg->sess_count==0, PJ_EINVALIDOP);
760
/* MUST not have pending transactions. */
761
PJ_ASSERT_RETURN(dlg->tsx_count==0, PJ_EINVALIDOP);
763
return unregister_and_destroy_dialog(dlg);
770
PJ_DEF(pj_status_t) pjsip_dlg_set_route_set( pjsip_dialog *dlg,
771
const pjsip_route_hdr *route_set )
775
PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
777
pjsip_dlg_inc_lock(dlg);
779
/* Clear route set. */
780
pj_list_init(&dlg->route_set);
783
pjsip_dlg_dec_lock(dlg);
788
while (r != route_set) {
789
pjsip_route_hdr *new_r;
791
new_r = (pjsip_route_hdr*) pjsip_hdr_clone(dlg->pool, r);
792
pj_list_push_back(&dlg->route_set, new_r);
797
pjsip_dlg_dec_lock(dlg);
803
* Increment session counter.
805
PJ_DEF(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
808
PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
810
pjsip_dlg_inc_lock(dlg);
812
pjsip_dlg_dec_lock(dlg);
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));
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.
825
PJ_DEF(void) pjsip_dlg_inc_lock(pjsip_dialog *dlg)
827
PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_inc_lock(), sess_count=%d",
830
pj_mutex_lock(dlg->mutex_);
833
PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_inc_lock(), sess_count=%d",
837
/* Try to acquire dialog's mutex, but bail out if mutex can not be
838
* acquired immediately.
840
PJ_DEF(pj_status_t) pjsip_dlg_try_inc_lock(pjsip_dialog *dlg)
844
PJ_LOG(6,(dlg->obj_name,"Entering pjsip_dlg_try_inc_lock(), sess_count=%d",
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"));
855
PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_try_inc_lock(), sess_count=%d",
863
* Unlock dialog and decrement session counter.
864
* It may delete the dialog!
866
PJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg)
868
PJ_ASSERT_ON_FAIL(dlg!=NULL, return);
870
PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_dec_lock(), sess_count=%d",
873
pj_assert(dlg->sess_count > 0);
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);
881
pj_mutex_unlock(dlg->mutex_);
884
PJ_LOG(6,(THIS_FILE, "Leaving pjsip_dlg_dec_lock() (dlg=%p)", dlg));
890
* Decrement session counter.
892
PJ_DEF(pj_status_t) pjsip_dlg_dec_session( pjsip_dialog *dlg,
895
PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
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));
900
pjsip_dlg_inc_lock(dlg);
902
pjsip_dlg_dec_lock(dlg);
910
PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
916
PJ_ASSERT_RETURN(dlg && mod, PJ_EINVAL);
917
PJ_ASSERT_RETURN(mod->id >= 0 && mod->id < PJSIP_MAX_MODULE,
919
PJ_ASSERT_RETURN(dlg->usage_cnt < PJSIP_MAX_MODULE, PJ_EBUG);
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));
925
pjsip_dlg_inc_lock(dlg);
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.
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.
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;
944
pjsip_dlg_dec_lock(dlg);
947
//pj_assert(!"This module is already registered");
948
//pjsip_dlg_dec_lock(dlg);
949
//return PJSIP_ETYPEEXISTS;
952
if (dlg->usage[index]->priority > mod->priority)
956
/* index holds position to put the module.
957
* Insert module at this index.
959
pj_array_insert(dlg->usage, sizeof(dlg->usage[0]), dlg->usage_cnt,
962
/* Set module data. */
963
dlg->mod_data[mod->id] = mod_data;
965
/* Increment count. */
968
pjsip_dlg_dec_lock(dlg);
975
* Attach module specific data to the dialog. Application can also set
976
* the value directly by accessing dlg->mod_data[module_id].
978
PJ_DEF(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,
982
PJ_ASSERT_RETURN(dlg, PJ_EINVAL);
983
PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,
985
dlg->mod_data[mod_id] = data;
990
* Get module specific data previously attached to the dialog. Application
991
* can also get value directly by accessing dlg->mod_data[module_id].
993
PJ_DEF(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,
996
PJ_ASSERT_RETURN(dlg, NULL);
997
PJ_ASSERT_RETURN(mod_id >= 0 && mod_id < PJSIP_MAX_MODULE,
999
return dlg->mod_data[mod_id];
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.
1008
static pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,
1009
const pjsip_method *method,
1011
pjsip_tx_data **p_tdata )
1013
pjsip_tx_data *tdata;
1014
pjsip_contact_hdr *contact;
1015
pjsip_route_hdr *route, *end_list;
1018
/* Contact Header field.
1019
* Contact can only be present in requests that establish dialog (in the
1020
* core SIP spec, only INVITE).
1022
if (pjsip_method_creates_dialog(method))
1023
contact = dlg->local.contact;
1028
* Create the request by cloning from the headers in the
1031
status = pjsip_endpt_create_request_from_hdr(dlg->endpt,
1041
if (status != PJ_SUCCESS)
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.
1048
route = dlg->route_set.next;
1049
end_list = &dlg->route_set;
1050
for (; route != end_list; route = route->next ) {
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);
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)
1073
* Create outgoing request.
1075
PJ_DEF(pj_status_t) pjsip_dlg_create_request( pjsip_dialog *dlg,
1076
const pjsip_method *method,
1078
pjsip_tx_data **p_tdata)
1081
pjsip_tx_data *tdata = NULL;
1084
PJ_ASSERT_RETURN(dlg && method && p_tdata, PJ_EINVAL);
1087
pjsip_dlg_inc_lock(dlg);
1089
/* Use outgoing CSeq and increment it by one. */
1091
cseq = dlg->local.cseq + 1;
1093
/* Keep compiler happy */
1096
/* Create the request. */
1098
status = dlg_create_request_throw(dlg, method, cseq, &tdata);
1105
/* Failed! Delete transmit data. */
1106
if (status != PJ_SUCCESS && tdata) {
1107
pjsip_tx_data_dec_ref( tdata );
1111
/* Unlock dialog. */
1112
pjsip_dlg_dec_lock(dlg);
1121
* Send request statefully, and update dialog'c CSeq.
1123
PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
1124
pjsip_tx_data *tdata,
1128
pjsip_transaction *tsx;
1129
pjsip_msg *msg = tdata->msg;
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);
1137
PJ_LOG(5,(dlg->obj_name, "Sending %s",
1138
pjsip_tx_data_get_info(tdata)));
1140
/* Lock and increment session */
1141
pjsip_dlg_inc_lock(dlg);
1143
/* Update dialog's CSeq and message's CSeq if request is not
1146
if (msg->line.req.method.id != PJSIP_CANCEL_METHOD &&
1147
msg->line.req.method.id != PJSIP_ACK_METHOD)
1151
ch = PJSIP_MSG_CSEQ_HDR(msg);
1152
PJ_ASSERT_RETURN(ch!=NULL, PJ_EBUG);
1154
ch->cseq = dlg->local.cseq++;
1156
/* Force the whole message to be re-printed. */
1157
pjsip_tx_data_invalidate_msg( tdata );
1160
/* Create a new transaction if method is not ACK.
1161
* The transaction user is the user agent module.
1163
if (msg->line.req.method.id != PJSIP_ACK_METHOD) {
1166
status = pjsip_tsx_create_uac(dlg->ua, tdata, &tsx);
1167
if (status != PJ_SUCCESS)
1170
/* Set transport selector */
1171
status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
1172
pj_assert(status == PJ_SUCCESS);
1174
/* Attach this dialog to the transaction, so that user agent
1175
* will dispatch events to this dialog.
1177
tsx->mod_data[dlg->ua->id] = dlg;
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;
1183
/* Increment transaction counter. */
1184
tsx_count = ++dlg->tsx_count;
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);
1195
/* Set transport selector */
1196
pjsip_tx_data_set_transport(tdata, &dlg->tp_sel);
1199
status = pjsip_endpt_send_request_stateless(dlg->endpt, tdata,
1201
if (status != PJ_SUCCESS)
1206
/* Unlock dialog, may destroy dialog. */
1207
pjsip_dlg_dec_lock(dlg);
1212
/* Unlock dialog, may destroy dialog. */
1213
pjsip_dlg_dec_lock(dlg);
1215
/* Whatever happen delete the message. */
1216
pjsip_tx_data_dec_ref( tdata );
1221
/* Add standard headers for certain types of response */
1222
static void dlg_beautify_response(pjsip_dialog *dlg,
1223
pj_bool_t add_headers,
1225
pjsip_tx_data *tdata)
1227
pjsip_cseq_hdr *cseq;
1229
const pjsip_hdr *c_hdr;
1232
cseq = PJSIP_MSG_CSEQ_HDR(tdata->msg);
1233
pj_assert(cseq != NULL);
1235
st_class = st_code / 100;
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) ||
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)
1247
hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool,
1248
dlg->local.contact);
1249
pjsip_msg_add_hdr(tdata->msg, hdr);
1253
/* Add Allow header in 18x, 2xx and 405 response. */
1254
if ((((st_code/10==18 || st_class==2) && dlg->add_allow)
1256
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ALLOW, NULL)==NULL)
1258
c_hdr = pjsip_endpt_get_capability(dlg->endpt,
1259
PJSIP_H_ALLOW, NULL);
1261
hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);
1262
pjsip_msg_add_hdr(tdata->msg, hdr);
1266
/* Add Supported header in 2xx response. */
1268
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL)==NULL)
1270
c_hdr = pjsip_endpt_get_capability(dlg->endpt,
1271
PJSIP_H_SUPPORTED, NULL);
1273
hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, c_hdr);
1274
pjsip_msg_add_hdr(tdata->msg, hdr);
1280
/* Add To tag in all responses except 100 */
1281
if (st_code != 100) {
1284
to = PJSIP_MSG_TO_HDR(tdata->msg);
1285
pj_assert(to != NULL);
1287
to->tag = dlg->local.info->tag;
1289
if (dlg->state == PJSIP_DIALOG_STATE_NULL)
1290
dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
1298
PJ_DEF(pj_status_t) pjsip_dlg_create_response( pjsip_dialog *dlg,
1299
pjsip_rx_data *rdata,
1301
const pj_str_t *st_text,
1302
pjsip_tx_data **p_tdata)
1305
pjsip_tx_data *tdata;
1307
/* Create generic response.
1308
* This will initialize response's Via, To, From, Call-ID, CSeq
1309
* and Record-Route headers from the request.
1311
status = pjsip_endpt_create_response(dlg->endpt,
1312
rdata, st_code, st_text, &tdata);
1313
if (status != PJ_SUCCESS)
1316
/* Lock the dialog. */
1317
pjsip_dlg_inc_lock(dlg);
1319
dlg_beautify_response(dlg, PJ_FALSE, st_code, tdata);
1321
/* Unlock the dialog. */
1322
pjsip_dlg_dec_lock(dlg);
1332
PJ_DEF(pj_status_t) pjsip_dlg_modify_response( pjsip_dialog *dlg,
1333
pjsip_tx_data *tdata,
1335
const pj_str_t *st_text)
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);
1344
/* Lock and increment session */
1345
pjsip_dlg_inc_lock(dlg);
1347
/* Replace status code and reason */
1348
tdata->msg->line.status.code = st_code;
1350
pj_strdup(tdata->pool, &tdata->msg->line.status.reason, st_text);
1352
tdata->msg->line.status.reason = *pjsip_get_status_text(st_code);
1355
/* Remove existing Contact header (without this, when dialog sent
1356
* 180 and then 302, the Contact in 302 will not get updated).
1358
hdr = (pjsip_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
1362
/* Add tag etc. if necessary */
1363
dlg_beautify_response(dlg, st_code/100 <= 2, st_code, tdata);
1366
/* Must add reference counter, since tsx_send_msg() will decrement it */
1367
pjsip_tx_data_add_ref(tdata);
1369
/* Force to re-print message. */
1370
pjsip_tx_data_invalidate_msg(tdata);
1372
/* Unlock dialog and dec session, may destroy dialog. */
1373
pjsip_dlg_dec_lock(dlg);
1379
* Send response statefully.
1381
PJ_DEF(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
1382
pjsip_transaction *tsx,
1383
pjsip_tx_data *tdata)
1388
PJ_ASSERT_RETURN(dlg && tsx && tdata && tdata->msg, PJ_EINVAL);
1389
PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_RESPONSE_MSG,
1390
PJSIP_ENOTRESPONSEMSG);
1392
/* The transaction must belong to this dialog. */
1393
PJ_ASSERT_RETURN(tsx->mod_data[dlg->ua->id] == dlg, PJ_EINVALIDOP);
1395
PJ_LOG(5,(dlg->obj_name, "Sending %s",
1396
pjsip_tx_data_get_info(tdata)));
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.
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,
1409
/* Must acquire dialog first, to prevent deadlock */
1410
pjsip_dlg_inc_lock(dlg);
1412
/* Last chance to add mandatory headers before the response is
1415
dlg_beautify_response(dlg, PJ_TRUE, tdata->msg->line.status.code, tdata);
1417
/* If the dialog is locked to transport, make sure that transaction
1418
* is locked to the same transport too.
1420
if (dlg->tp_sel.type != tsx->tp_sel.type ||
1421
dlg->tp_sel.u.ptr != tsx->tp_sel.u.ptr)
1423
status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel);
1424
pj_assert(status == PJ_SUCCESS);
1427
/* Ask transaction to send the response */
1428
status = pjsip_tsx_send_msg(tsx, tdata);
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.
1434
if (status != PJ_SUCCESS) {
1435
pjsip_tx_data_dec_ref(tdata);
1438
pjsip_dlg_dec_lock(dlg);
1445
* Combo function to create and send response statefully.
1447
PJ_DEF(pj_status_t) pjsip_dlg_respond( pjsip_dialog *dlg,
1448
pjsip_rx_data *rdata,
1450
const pj_str_t *st_text,
1451
const pjsip_hdr *hdr_list,
1452
const pjsip_msg_body *body )
1455
pjsip_tx_data *tdata;
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);
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,
1467
/* Create the response. */
1468
status = pjsip_dlg_create_response(dlg, rdata, st_code, st_text, &tdata);
1469
if (status != PJ_SUCCESS)
1472
/* Add additional header, if any */
1474
const pjsip_hdr *hdr;
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));
1484
/* Add the message body, if any. */
1486
tdata->msg->body = pjsip_msg_body_clone( tdata->pool, body);
1489
/* Send the response. */
1490
return pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
1494
/* This function is called by user agent upon receiving incoming response
1497
void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
1500
pjsip_transaction *tsx = NULL;
1501
pj_bool_t processed = PJ_FALSE;
1504
PJ_LOG(5,(dlg->obj_name, "Received %s",
1505
pjsip_rx_data_get_info(rdata)));
1507
/* Lock dialog and increment session. */
1508
pjsip_dlg_inc_lock(dlg);
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)
1516
* Respond statelessly with 500 (Internal Server Error)
1520
/* Unlock dialog and dec session, may destroy dialog. */
1521
pjsip_dlg_dec_lock(dlg);
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);
1531
dlg->remote.cseq = rdata->msg_info.cseq->cseq;
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).
1538
if (dlg->remote.info->tag.slen == 0) {
1539
pj_strdup(dlg->pool, &dlg->remote.info->tag,
1540
&rdata->msg_info.from->tag);
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)
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).
1552
char errmsg[PJ_ERR_MSG_SIZE];
1555
reason = pj_strerror(status, errmsg, sizeof(errmsg));
1556
pjsip_endpt_respond_stateless(dlg->endpt, rdata, 500, &reason,
1561
/* Put this dialog in the transaction data. */
1562
tsx->mod_data[dlg->ua->id] = dlg;
1564
/* Add transaction count. */
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).
1575
if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method)) {
1576
pjsip_contact_hdr *contact;
1578
contact = (pjsip_contact_hdr*)
1579
pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
1581
if (contact && (dlg->remote.contact==NULL ||
1582
pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
1583
dlg->remote.contact->uri,
1586
dlg->remote.contact = (pjsip_contact_hdr*)
1587
pjsip_hdr_clone(dlg->pool, contact);
1588
dlg->target = dlg->remote.contact->uri;
1592
/* Report the request to dialog usages. */
1593
for (i=0; i<dlg->usage_cnt; ++i) {
1595
if (!dlg->usage[i]->on_rx_request)
1598
processed = (*dlg->usage[i]->on_rx_request)(rdata);
1604
/* Feed the first request to the transaction. */
1606
pjsip_tsx_recv_msg(tsx, rdata);
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.
1612
if (!processed && tsx && tsx->status_code < 200) {
1613
pjsip_tx_data *tdata;
1614
const pj_str_t reason = { "Unhandled by dialog usages", 26};
1616
PJ_LOG(4,(tsx->obj_name, "%s was unhandled by "
1617
"dialog usages, sending 500 response",
1618
pjsip_rx_data_get_info(rdata)));
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);
1627
/* Unlock dialog and dec session, may destroy dialog. */
1628
pjsip_dlg_dec_lock(dlg);
1631
/* Update route-set from incoming message */
1632
static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
1634
const pjsip_hdr *hdr, *end_hdr;
1635
pj_int32_t msg_cseq;
1636
const pjsip_msg *msg;
1638
msg = rdata->msg_info.msg;
1639
msg_cseq = rdata->msg_info.cseq->cseq;
1641
/* Ignore if route set has been frozen */
1642
if (dlg->route_set_frozen)
1645
/* Only update route set if this message belongs to the same
1646
* transaction as the initial transaction that establishes dialog.
1648
if (dlg->role == PJSIP_ROLE_UAC) {
1650
/* Ignore subsequent request from remote */
1651
if (msg->type != PJSIP_RESPONSE_MSG)
1654
/* Ignore subsequent responses with higher CSeq than initial CSeq.
1655
* Unfortunately this would be broken when the first request is
1658
//if (msg_cseq != dlg->local.first_cseq)
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
1667
pj_assert(!"Should not happen");
1671
/* Based on the checks above, we should only get response message here */
1672
pj_assert(msg->type == PJSIP_RESPONSE_MSG);
1674
/* Ignore if this is not 1xx or 2xx response */
1675
if (msg->line.status.code >= 300)
1678
/* Reset route set */
1679
pj_list_init(&dlg->route_set);
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) {
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);
1692
PJ_LOG(5,(dlg->obj_name, "Route-set updated"));
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.
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.
1703
* The pjsip_method_creates_dialog() check protects from wrongly
1704
* freezing the route set upon receiving 200/OK response for PRACK.
1706
if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1707
PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200))
1709
dlg->route_set_frozen = PJ_TRUE;
1710
PJ_LOG(5,(dlg->obj_name, "Route-set frozen"));
1715
/* This function is called by user agent upon receiving incoming response
1718
void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
1723
PJ_LOG(5,(dlg->obj_name, "Received %s",
1724
pjsip_rx_data_get_info(rdata)));
1726
/* Lock the dialog and inc session. */
1727
pjsip_dlg_inc_lock(dlg);
1729
/* Check that rdata already has dialog in mod_data. */
1730
pj_assert(pjsip_rdata_get_dlg(rdata) == dlg);
1732
/* Keep the response's status code */
1733
res_code = rdata->msg_info.msg->line.status.code;
1735
/* When we receive response that establishes dialog, update To tag,
1736
* route set and dialog target.
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.
1744
* The workaround for this is to take the To tag received in the
1745
* 2xx response and set it as remote tag.
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
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)
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)))
1763
pjsip_contact_hdr *contact;
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. */
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.
1778
dlg_update_routeset(dlg, rdata);
1780
/* The remote target MUST be set to the URI from the Contact header
1781
* field of the response.
1783
contact = (pjsip_contact_hdr*)
1784
pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
1786
if (contact && (dlg->remote.contact==NULL ||
1787
pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
1788
dlg->remote.contact->uri,
1791
dlg->remote.contact = (pjsip_contact_hdr*)
1792
pjsip_hdr_clone(dlg->pool, contact);
1793
dlg->target = dlg->remote.contact->uri;
1796
dlg->state = PJSIP_DIALOG_STATE_ESTABLISHED;
1798
/* Prevent dialog from being updated just in case more 2xx
1799
* gets through this dialog (it shouldn't happen).
1801
if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx &&
1804
dlg->uac_has_2xx = PJ_TRUE;
1808
/* Update remote target (again) when receiving 2xx response messages
1809
* that's defined as target refresh.
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:
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
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
1828
if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
1831
pjsip_contact_hdr *contact;
1833
contact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
1836
if (contact && (dlg->remote.contact==NULL ||
1837
pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI,
1838
dlg->remote.contact->uri,
1841
dlg->remote.contact = (pjsip_contact_hdr*)
1842
pjsip_hdr_clone(dlg->pool, contact);
1843
dlg->target = dlg->remote.contact->uri;
1846
dlg_update_routeset(dlg, rdata);
1850
/* Pass to dialog usages. */
1851
for (i=0; i<dlg->usage_cnt; ++i) {
1852
pj_bool_t processed;
1854
if (!dlg->usage[i]->on_rx_response)
1857
processed = (*dlg->usage[i]->on_rx_response)(rdata);
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
1868
if (dlg->usage_cnt==0) {
1871
if (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD &&
1872
rdata->msg_info.msg->line.status.code/100 == 2)
1876
status = pjsip_dlg_create_request(dlg, &pjsip_ack_method,
1877
rdata->msg_info.cseq->cseq,
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)
1884
pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
1885
pjsip_tx_data *tdata;
1887
status = pjsip_auth_clt_reinit_req( &dlg->auth_sess,
1888
rdata, tsx->last_tx,
1891
if (status == PJ_SUCCESS) {
1892
/* Re-send request. */
1893
status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
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)));
1906
/* Unlock dialog and dec session, may destroy dialog. */
1907
pjsip_dlg_dec_lock(dlg);
1910
/* This function is called by user agent upon receiving transaction
1911
* state notification.
1913
void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
1914
pjsip_transaction *tsx,
1919
PJ_LOG(5,(dlg->obj_name, "Transaction %s state changed to %s",
1920
tsx->obj_name, pjsip_tsx_state_str(tsx->state)));
1922
/* Lock the dialog and increment session. */
1923
pjsip_dlg_inc_lock(dlg);
1925
/* Pass to dialog usages. */
1926
for (i=0; i<dlg->usage_cnt; ++i) {
1928
if (!dlg->usage[i]->on_tsx_state)
1931
(*dlg->usage[i]->on_tsx_state)(tsx, e);
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.
1939
if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
1940
tsx->mod_data[dlg->ua->id] == dlg)
1942
pj_assert(dlg->tsx_count>0);
1944
tsx->mod_data[dlg->ua->id] = NULL;
1947
/* Unlock dialog and dec session, may destroy dialog. */
1948
pjsip_dlg_dec_lock(dlg);