~ubuntu-branches/ubuntu/vivid/sflphone/vivid

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2013-06-30 11:40:56 UTC
  • mfrom: (4.1.18 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130630114056-0np50jkyqo6vnmii
Tags: 1.2.3-2
* changeset_r92d62cfc54732bbbcfff2b1d36c096b120b981a5.diff 
  - fixes automatic endian detection 
* Update Vcs: fixes vcs-field-not-canonical

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: sip_transaction.c 4165 2012-06-14 09:04:20Z bennylp $ */
 
2
/*
 
3
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 */
 
20
#include <pjsip/sip_transaction.h>
 
21
#include <pjsip/sip_util.h>
 
22
#include <pjsip/sip_module.h>
 
23
#include <pjsip/sip_endpoint.h>
 
24
#include <pjsip/sip_errno.h>
 
25
#include <pjsip/sip_event.h>
 
26
#include <pjlib-util/errno.h>
 
27
#include <pj/hash.h>
 
28
#include <pj/pool.h>
 
29
#include <pj/os.h>
 
30
#include <pj/string.h>
 
31
#include <pj/assert.h>
 
32
#include <pj/guid.h>
 
33
#include <pj/log.h>
 
34
 
 
35
#define THIS_FILE   "sip_transaction.c"
 
36
 
 
37
#if 0
 
38
#define TSX_TRACE_(expr)    PJ_LOG(3,expr)
 
39
#else
 
40
#define TSX_TRACE_(expr)
 
41
#endif
 
42
 
 
43
/* When this macro is set, transaction will keep the hashed value
 
44
 * so that future lookup (to unregister transaction) does not need
 
45
 * to recalculate the hash again. It should gains a little bit of
 
46
 * performance, so generally we'd want this.
 
47
 */
 
48
#define PRECALC_HASH
 
49
 
 
50
 
 
51
/* Defined in sip_util_statefull.c */
 
52
extern pjsip_module mod_stateful_util;
 
53
 
 
54
 
 
55
/*****************************************************************************
 
56
 **
 
57
 ** Declarations and static variable definitions section.
 
58
 **
 
59
 *****************************************************************************
 
60
 **/
 
61
/* Prototypes. */
 
62
static pj_status_t mod_tsx_layer_load(pjsip_endpoint *endpt);
 
63
static pj_status_t mod_tsx_layer_start(void);
 
64
static pj_status_t mod_tsx_layer_stop(void);
 
65
static pj_status_t mod_tsx_layer_unload(void);
 
66
static pj_bool_t   mod_tsx_layer_on_rx_request(pjsip_rx_data *rdata);
 
67
static pj_bool_t   mod_tsx_layer_on_rx_response(pjsip_rx_data *rdata);
 
68
 
 
69
/* Transaction layer module definition. */
 
70
static struct mod_tsx_layer
 
71
{
 
72
    struct pjsip_module  mod;
 
73
    pj_pool_t           *pool;
 
74
    pjsip_endpoint      *endpt;
 
75
    pj_mutex_t          *mutex;
 
76
    pj_hash_table_t     *htable;
 
77
} mod_tsx_layer =
 
78
{   {
 
79
        NULL, NULL,                     /* List's prev and next.    */
 
80
        { "mod-tsx-layer", 13 },        /* Module name.             */
 
81
        -1,                             /* Module ID                */
 
82
        PJSIP_MOD_PRIORITY_TSX_LAYER,   /* Priority.                */
 
83
        mod_tsx_layer_load,             /* load().                  */
 
84
        mod_tsx_layer_start,            /* start()                  */
 
85
        mod_tsx_layer_stop,             /* stop()                   */
 
86
        mod_tsx_layer_unload,           /* unload()                 */
 
87
        mod_tsx_layer_on_rx_request,    /* on_rx_request()          */
 
88
        mod_tsx_layer_on_rx_response,   /* on_rx_response()         */
 
89
        NULL
 
90
    }
 
91
};
 
92
 
 
93
/* Thread Local Storage ID for transaction lock */
 
94
static long pjsip_tsx_lock_tls_id;
 
95
 
 
96
/* Transaction state names */
 
97
static const char *state_str[] =
 
98
{
 
99
    "Null",
 
100
    "Calling",
 
101
    "Trying",
 
102
    "Proceeding",
 
103
    "Completed",
 
104
    "Confirmed",
 
105
    "Terminated",
 
106
    "Destroyed",
 
107
};
 
108
 
 
109
/* Role names */
 
110
static const char *role_name[] =
 
111
{
 
112
    "UAC",
 
113
    "UAS"
 
114
};
 
115
 
 
116
/* Transport flag. */
 
117
enum
 
118
{
 
119
    TSX_HAS_PENDING_TRANSPORT   = 1,
 
120
    TSX_HAS_PENDING_RESCHED     = 2,
 
121
    TSX_HAS_PENDING_SEND        = 4,
 
122
    TSX_HAS_PENDING_DESTROY     = 8,
 
123
    TSX_HAS_RESOLVED_SERVER     = 16,
 
124
};
 
125
 
 
126
/* Transaction lock. */
 
127
typedef struct tsx_lock_data {
 
128
    struct tsx_lock_data *prev;
 
129
    pjsip_transaction    *tsx;
 
130
    int                   is_alive;
 
131
} tsx_lock_data;
 
132
 
 
133
 
 
134
/* Timer timeout value constants */
 
135
static pj_time_val t1_timer_val = { PJSIP_T1_TIMEOUT/1000,
 
136
                                    PJSIP_T1_TIMEOUT%1000 };
 
137
static pj_time_val t2_timer_val = { PJSIP_T2_TIMEOUT/1000,
 
138
                                    PJSIP_T2_TIMEOUT%1000 };
 
139
static pj_time_val t4_timer_val = { PJSIP_T4_TIMEOUT/1000,
 
140
                                    PJSIP_T4_TIMEOUT%1000 };
 
141
static pj_time_val td_timer_val = { PJSIP_TD_TIMEOUT/1000,
 
142
                                    PJSIP_TD_TIMEOUT%1000 };
 
143
static pj_time_val timeout_timer_val = { (64*PJSIP_T1_TIMEOUT)/1000,
 
144
                                         (64*PJSIP_T1_TIMEOUT)%1000 };
 
145
 
 
146
#define TIMER_INACTIVE  0
 
147
#define TIMER_ACTIVE    1
 
148
 
 
149
 
 
150
/* Prototypes. */
 
151
static void        lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck);
 
152
static pj_status_t unlock_tsx( pjsip_transaction *tsx,
 
153
                               struct tsx_lock_data *lck);
 
154
static pj_status_t tsx_on_state_null(           pjsip_transaction *tsx,
 
155
                                                pjsip_event *event);
 
156
static pj_status_t tsx_on_state_calling(        pjsip_transaction *tsx,
 
157
                                                pjsip_event *event);
 
158
static pj_status_t tsx_on_state_trying(         pjsip_transaction *tsx,
 
159
                                                pjsip_event *event);
 
160
static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
 
161
                                                pjsip_event *event);
 
162
static pj_status_t tsx_on_state_proceeding_uac( pjsip_transaction *tsx,
 
163
                                                pjsip_event *event);
 
164
static pj_status_t tsx_on_state_completed_uas(  pjsip_transaction *tsx,
 
165
                                                pjsip_event *event);
 
166
static pj_status_t tsx_on_state_completed_uac(  pjsip_transaction *tsx,
 
167
                                                pjsip_event *event);
 
168
static pj_status_t tsx_on_state_confirmed(      pjsip_transaction *tsx,
 
169
                                                pjsip_event *event);
 
170
static pj_status_t tsx_on_state_terminated(     pjsip_transaction *tsx,
 
171
                                                pjsip_event *event);
 
172
static pj_status_t tsx_on_state_destroyed(      pjsip_transaction *tsx,
 
173
                                                pjsip_event *event);
 
174
static void        tsx_timer_callback( pj_timer_heap_t *theap,
 
175
                                       pj_timer_entry *entry);
 
176
static void        tsx_tp_state_callback(
 
177
                                       pjsip_transport *tp,
 
178
                                       pjsip_transport_state state,
 
179
                                       const pjsip_transport_state_info *info);
 
180
static pj_status_t tsx_create( pjsip_module *tsx_user,
 
181
                               pjsip_transaction **p_tsx);
 
182
static pj_status_t tsx_destroy( pjsip_transaction *tsx );
 
183
static void        tsx_resched_retransmission( pjsip_transaction *tsx );
 
184
static pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched);
 
185
static int         tsx_send_msg( pjsip_transaction *tsx,
 
186
                                 pjsip_tx_data *tdata);
 
187
static void        tsx_update_transport( pjsip_transaction *tsx,
 
188
                                         pjsip_transport *tp);
 
189
 
 
190
 
 
191
/* State handlers for UAC, indexed by state */
 
192
static int  (*tsx_state_handler_uac[PJSIP_TSX_STATE_MAX])(pjsip_transaction *,
 
193
                                                          pjsip_event *) =
 
194
{
 
195
    &tsx_on_state_null,
 
196
    &tsx_on_state_calling,
 
197
    NULL,
 
198
    &tsx_on_state_proceeding_uac,
 
199
    &tsx_on_state_completed_uac,
 
200
    &tsx_on_state_confirmed,
 
201
    &tsx_on_state_terminated,
 
202
    &tsx_on_state_destroyed,
 
203
};
 
204
 
 
205
/* State handlers for UAS */
 
206
static int  (*tsx_state_handler_uas[PJSIP_TSX_STATE_MAX])(pjsip_transaction *,
 
207
                                                          pjsip_event *) =
 
208
{
 
209
    &tsx_on_state_null,
 
210
    NULL,
 
211
    &tsx_on_state_trying,
 
212
    &tsx_on_state_proceeding_uas,
 
213
    &tsx_on_state_completed_uas,
 
214
    &tsx_on_state_confirmed,
 
215
    &tsx_on_state_terminated,
 
216
    &tsx_on_state_destroyed,
 
217
};
 
218
 
 
219
/*****************************************************************************
 
220
 **
 
221
 ** Utilities
 
222
 **
 
223
 *****************************************************************************
 
224
 */
 
225
/*
 
226
 * Get transaction state name.
 
227
 */
 
228
PJ_DEF(const char *) pjsip_tsx_state_str(pjsip_tsx_state_e state)
 
229
{
 
230
    return state_str[state];
 
231
}
 
232
 
 
233
/*
 
234
 * Get the role name.
 
235
 */
 
236
PJ_DEF(const char *) pjsip_role_name(pjsip_role_e role)
 
237
{
 
238
    return role_name[role];
 
239
}
 
240
 
 
241
 
 
242
/*
 
243
 * Create transaction key for RFC2543 compliant messages, which don't have
 
244
 * unique branch parameter in the top most Via header.
 
245
 *
 
246
 * INVITE requests matches a transaction if the following attributes
 
247
 * match the original request:
 
248
 *      - Request-URI
 
249
 *      - To tag
 
250
 *      - From tag
 
251
 *      - Call-ID
 
252
 *      - CSeq
 
253
 *      - top Via header
 
254
 *
 
255
 * CANCEL matching is done similarly as INVITE, except:
 
256
 *      - CSeq method will differ
 
257
 *      - To tag is not matched.
 
258
 *
 
259
 * ACK matching is done similarly, except that:
 
260
 *      - method of the CSeq will differ,
 
261
 *      - To tag is matched to the response sent by the server transaction.
 
262
 *
 
263
 * The transaction key is constructed from the common components of above
 
264
 * components. Additional comparison is needed to fully match a transaction.
 
265
 */
 
266
static pj_status_t create_tsx_key_2543( pj_pool_t *pool,
 
267
                                        pj_str_t *str,
 
268
                                        pjsip_role_e role,
 
269
                                        const pjsip_method *method,
 
270
                                        const pjsip_rx_data *rdata )
 
271
{
 
272
#define SEPARATOR   '$'
 
273
    char *key, *p, *end;
 
274
    int len;
 
275
    pj_size_t len_required;
 
276
    pjsip_uri *req_uri;
 
277
    pj_str_t *host;
 
278
 
 
279
    PJ_ASSERT_RETURN(pool && str && method && rdata, PJ_EINVAL);
 
280
    PJ_ASSERT_RETURN(rdata->msg_info.msg, PJ_EINVAL);
 
281
    PJ_ASSERT_RETURN(rdata->msg_info.via, PJSIP_EMISSINGHDR);
 
282
    PJ_ASSERT_RETURN(rdata->msg_info.cseq, PJSIP_EMISSINGHDR);
 
283
    PJ_ASSERT_RETURN(rdata->msg_info.from, PJSIP_EMISSINGHDR);
 
284
 
 
285
    host = &rdata->msg_info.via->sent_by.host;
 
286
    req_uri = (pjsip_uri*)rdata->msg_info.msg->line.req.uri;
 
287
 
 
288
    /* Calculate length required. */
 
289
    len_required = 9 +                      /* CSeq number */
 
290
                   rdata->msg_info.from->tag.slen +   /* From tag. */
 
291
                   rdata->msg_info.cid->id.slen +    /* Call-ID */
 
292
                   host->slen +             /* Via host. */
 
293
                   9 +                      /* Via port. */
 
294
                   16;                      /* Separator+Allowance. */
 
295
    key = p = (char*) pj_pool_alloc(pool, len_required);
 
296
    end = p + len_required;
 
297
 
 
298
    /* Add role. */
 
299
    *p++ = (char)(role==PJSIP_ROLE_UAC ? 'c' : 's');
 
300
    *p++ = SEPARATOR;
 
301
 
 
302
    /* Add method, except when method is INVITE or ACK. */
 
303
    if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) {
 
304
        pj_memcpy(p, method->name.ptr, method->name.slen);
 
305
        p += method->name.slen;
 
306
        *p++ = '$';
 
307
    }
 
308
 
 
309
    /* Add CSeq (only the number). */
 
310
    len = pj_utoa(rdata->msg_info.cseq->cseq, p);
 
311
    p += len;
 
312
    *p++ = SEPARATOR;
 
313
 
 
314
    /* Add From tag. */
 
315
    len = rdata->msg_info.from->tag.slen;
 
316
    pj_memcpy( p, rdata->msg_info.from->tag.ptr, len);
 
317
    p += len;
 
318
    *p++ = SEPARATOR;
 
319
 
 
320
    /* Add Call-ID. */
 
321
    len = rdata->msg_info.cid->id.slen;
 
322
    pj_memcpy( p, rdata->msg_info.cid->id.ptr, len );
 
323
    p += len;
 
324
    *p++ = SEPARATOR;
 
325
 
 
326
    /* Add top Via header.
 
327
     * We don't really care whether the port contains the real port (because
 
328
     * it can be omited if default port is used). Anyway this function is
 
329
     * only used to match request retransmission, and we expect that the
 
330
     * request retransmissions will contain the same port.
 
331
     */
 
332
    pj_memcpy(p, host->ptr, host->slen);
 
333
    p += host->slen;
 
334
    *p++ = ':';
 
335
 
 
336
    len = pj_utoa(rdata->msg_info.via->sent_by.port, p);
 
337
    p += len;
 
338
    *p++ = SEPARATOR;
 
339
 
 
340
    *p++ = '\0';
 
341
 
 
342
    /* Done. */
 
343
    str->ptr = key;
 
344
    str->slen = p-key;
 
345
 
 
346
    return PJ_SUCCESS;
 
347
}
 
348
 
 
349
/*
 
350
 * Create transaction key for RFC3161 compliant system.
 
351
 */
 
352
static pj_status_t create_tsx_key_3261( pj_pool_t *pool,
 
353
                                        pj_str_t *key,
 
354
                                        pjsip_role_e role,
 
355
                                        const pjsip_method *method,
 
356
                                        const pj_str_t *branch)
 
357
{
 
358
    char *p;
 
359
 
 
360
    PJ_ASSERT_RETURN(pool && key && method && branch, PJ_EINVAL);
 
361
 
 
362
    p = key->ptr = (char*)
 
363
                   pj_pool_alloc(pool, branch->slen + method->name.slen + 4 );
 
364
 
 
365
    /* Add role. */
 
366
    *p++ = (char)(role==PJSIP_ROLE_UAC ? 'c' : 's');
 
367
    *p++ = SEPARATOR;
 
368
 
 
369
    /* Add method, except when method is INVITE or ACK. */
 
370
    if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) {
 
371
        pj_memcpy(p, method->name.ptr, method->name.slen);
 
372
        p += method->name.slen;
 
373
        *p++ = '$';
 
374
    }
 
375
 
 
376
    /* Add branch ID. */
 
377
    pj_memcpy(p, branch->ptr, branch->slen);
 
378
    p += branch->slen;
 
379
 
 
380
    /* Set length */
 
381
    key->slen = p - key->ptr;
 
382
 
 
383
    return PJ_SUCCESS;
 
384
}
 
385
 
 
386
/*
 
387
 * Create key from the incoming data, to be used to search the transaction
 
388
 * in the transaction hash table.
 
389
 */
 
390
PJ_DEF(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool, pj_str_t *key,
 
391
                                          pjsip_role_e role,
 
392
                                          const pjsip_method *method,
 
393
                                          const pjsip_rx_data *rdata)
 
394
{
 
395
    pj_str_t rfc3261_branch = {PJSIP_RFC3261_BRANCH_ID,
 
396
                               PJSIP_RFC3261_BRANCH_LEN};
 
397
 
 
398
 
 
399
    /* Get the branch parameter in the top-most Via.
 
400
     * If branch parameter is started with "z9hG4bK", then the message was
 
401
     * generated by agent compliant with RFC3261. Otherwise, it will be
 
402
     * handled as RFC2543.
 
403
     */
 
404
    const pj_str_t *branch = &rdata->msg_info.via->branch_param;
 
405
 
 
406
    if (pj_strncmp(branch,&rfc3261_branch,PJSIP_RFC3261_BRANCH_LEN)==0) {
 
407
 
 
408
        /* Create transaction key. */
 
409
        return create_tsx_key_3261(pool, key, role, method, branch);
 
410
 
 
411
    } else {
 
412
        /* Create the key for the message. This key will be matched up
 
413
         * with the transaction key. For RFC2563 transactions, the
 
414
         * transaction key was created by the same function, so it will
 
415
         * match the message.
 
416
         */
 
417
        return create_tsx_key_2543( pool, key, role, method, rdata );
 
418
    }
 
419
}
 
420
 
 
421
/*****************************************************************************
 
422
 **
 
423
 ** Transaction layer module
 
424
 **
 
425
 *****************************************************************************
 
426
 **/
 
427
/*
 
428
 * Create transaction layer module and registers it to the endpoint.
 
429
 */
 
430
PJ_DEF(pj_status_t) pjsip_tsx_layer_init_module(pjsip_endpoint *endpt)
 
431
{
 
432
    pj_pool_t *pool;
 
433
    pj_status_t status;
 
434
 
 
435
 
 
436
    PJ_ASSERT_RETURN(mod_tsx_layer.endpt==NULL, PJ_EINVALIDOP);
 
437
 
 
438
    /* Initialize timer values */
 
439
    t1_timer_val.sec  = pjsip_cfg()->tsx.t1 / 1000;
 
440
    t1_timer_val.msec = pjsip_cfg()->tsx.t1 % 1000;
 
441
    t2_timer_val.sec  = pjsip_cfg()->tsx.t2 / 1000;
 
442
    t2_timer_val.msec = pjsip_cfg()->tsx.t2 % 1000;
 
443
    t4_timer_val.sec  = pjsip_cfg()->tsx.t4 / 1000;
 
444
    t4_timer_val.msec = pjsip_cfg()->tsx.t4 % 1000;
 
445
    td_timer_val.sec  = pjsip_cfg()->tsx.td / 1000;
 
446
    td_timer_val.msec = pjsip_cfg()->tsx.td % 1000;
 
447
    /* Changed the initialization below to use td_timer_val instead, to enable
 
448
     * customization to the timeout value.
 
449
     */
 
450
    //timeout_timer_val.sec  = (64 * pjsip_cfg()->tsx.t1) / 1000;
 
451
    //timeout_timer_val.msec = (64 * pjsip_cfg()->tsx.t1) % 1000;
 
452
    timeout_timer_val = td_timer_val;
 
453
 
 
454
    /* Initialize TLS ID for transaction lock. */
 
455
    status = pj_thread_local_alloc(&pjsip_tsx_lock_tls_id);
 
456
    if (status != PJ_SUCCESS)
 
457
        return status;
 
458
 
 
459
    pj_thread_local_set(pjsip_tsx_lock_tls_id, NULL);
 
460
 
 
461
    /*
 
462
     * Initialize transaction layer structure.
 
463
     */
 
464
 
 
465
    /* Create pool for the module. */
 
466
    pool = pjsip_endpt_create_pool(endpt, "tsxlayer",
 
467
                                   PJSIP_POOL_TSX_LAYER_LEN,
 
468
                                   PJSIP_POOL_TSX_LAYER_INC );
 
469
    if (!pool)
 
470
        return PJ_ENOMEM;
 
471
 
 
472
 
 
473
    /* Initialize some attributes. */
 
474
    mod_tsx_layer.pool = pool;
 
475
    mod_tsx_layer.endpt = endpt;
 
476
 
 
477
 
 
478
    /* Create hash table. */
 
479
    mod_tsx_layer.htable = pj_hash_create( pool, pjsip_cfg()->tsx.max_count );
 
480
    if (!mod_tsx_layer.htable) {
 
481
        pjsip_endpt_release_pool(endpt, pool);
 
482
        return PJ_ENOMEM;
 
483
    }
 
484
 
 
485
    /* Create mutex. */
 
486
    status = pj_mutex_create_recursive(pool, "tsxlayer", &mod_tsx_layer.mutex);
 
487
    if (status != PJ_SUCCESS) {
 
488
        pjsip_endpt_release_pool(endpt, pool);
 
489
        return status;
 
490
    }
 
491
 
 
492
    /*
 
493
     * Register transaction layer module to endpoint.
 
494
     */
 
495
    status = pjsip_endpt_register_module( endpt, &mod_tsx_layer.mod );
 
496
    if (status != PJ_SUCCESS) {
 
497
        pj_mutex_destroy(mod_tsx_layer.mutex);
 
498
        pjsip_endpt_release_pool(endpt, pool);
 
499
        return status;
 
500
    }
 
501
 
 
502
    /* Register mod_stateful_util module (sip_util_statefull.c) */
 
503
    status = pjsip_endpt_register_module(endpt, &mod_stateful_util);
 
504
    if (status != PJ_SUCCESS) {
 
505
        return status;
 
506
    }
 
507
 
 
508
    return PJ_SUCCESS;
 
509
}
 
510
 
 
511
 
 
512
/*
 
513
 * Get the instance of transaction layer module.
 
514
 */
 
515
PJ_DEF(pjsip_module*) pjsip_tsx_layer_instance(void)
 
516
{
 
517
    return &mod_tsx_layer.mod;
 
518
}
 
519
 
 
520
 
 
521
/*
 
522
 * Unregister and destroy transaction layer module.
 
523
 */
 
524
PJ_DEF(pj_status_t) pjsip_tsx_layer_destroy(void)
 
525
{
 
526
    /* Are we registered? */
 
527
    PJ_ASSERT_RETURN(mod_tsx_layer.endpt!=NULL, PJ_EINVALIDOP);
 
528
 
 
529
    /* Unregister from endpoint.
 
530
     * Clean-ups will be done in the unload() module callback.
 
531
     */
 
532
    return pjsip_endpt_unregister_module( mod_tsx_layer.endpt,
 
533
                                          &mod_tsx_layer.mod);
 
534
}
 
535
 
 
536
 
 
537
/*
 
538
 * Register the transaction to the hash table.
 
539
 */
 
540
static pj_status_t mod_tsx_layer_register_tsx( pjsip_transaction *tsx)
 
541
{
 
542
    pj_assert(tsx->transaction_key.slen != 0);
 
543
 
 
544
    /* Lock hash table mutex. */
 
545
    pj_mutex_lock(mod_tsx_layer.mutex);
 
546
 
 
547
    /* Check if no transaction with the same key exists.
 
548
     * Do not use PJ_ASSERT_RETURN since it evaluates the expression
 
549
     * twice!
 
550
     */
 
551
    if(pj_hash_get(mod_tsx_layer.htable,
 
552
                   tsx->transaction_key.ptr,
 
553
                   tsx->transaction_key.slen,
 
554
                   NULL))
 
555
    {
 
556
        pj_mutex_unlock(mod_tsx_layer.mutex);
 
557
        PJ_LOG(2,(THIS_FILE,
 
558
                  "Unable to register %.*s transaction (key exists)",
 
559
                  (int)tsx->method.name.slen,
 
560
                  tsx->method.name.ptr));
 
561
        return PJ_EEXISTS;
 
562
    }
 
563
 
 
564
    TSX_TRACE_((THIS_FILE,
 
565
                "Transaction %p registered with hkey=0x%p and key=%.*s",
 
566
                tsx, tsx->hashed_key, tsx->transaction_key.slen,
 
567
                tsx->transaction_key.ptr));
 
568
 
 
569
    /* Register the transaction to the hash table. */
 
570
#ifdef PRECALC_HASH
 
571
    pj_hash_set( tsx->pool, mod_tsx_layer.htable, tsx->transaction_key.ptr,
 
572
                 tsx->transaction_key.slen, tsx->hashed_key, tsx);
 
573
#else
 
574
    pj_hash_set( tsx->pool, mod_tsx_layer.htable, tsx->transaction_key.ptr,
 
575
                 tsx->transaction_key.slen, 0, tsx);
 
576
#endif
 
577
 
 
578
    /* Unlock mutex. */
 
579
    pj_mutex_unlock(mod_tsx_layer.mutex);
 
580
 
 
581
    return PJ_SUCCESS;
 
582
}
 
583
 
 
584
 
 
585
/*
 
586
 * Unregister the transaction from the hash table.
 
587
 */
 
588
static void mod_tsx_layer_unregister_tsx( pjsip_transaction *tsx)
 
589
{
 
590
    if (mod_tsx_layer.mod.id == -1) {
 
591
        /* The transaction layer has been unregistered. This could happen
 
592
         * if the transaction was pending on transport and the application
 
593
         * is shutdown. See http://trac.pjsip.org/repos/ticket/1033. In
 
594
         * this case just do nothing.
 
595
         */
 
596
        return;
 
597
    }
 
598
 
 
599
    pj_assert(tsx->transaction_key.slen != 0);
 
600
    //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL);
 
601
 
 
602
    /* Lock hash table mutex. */
 
603
    pj_mutex_lock(mod_tsx_layer.mutex);
 
604
 
 
605
    /* Register the transaction to the hash table. */
 
606
#ifdef PRECALC_HASH
 
607
    pj_hash_set( NULL, mod_tsx_layer.htable, tsx->transaction_key.ptr,
 
608
                 tsx->transaction_key.slen, tsx->hashed_key, NULL);
 
609
#else
 
610
    pj_hash_set( NULL, mod_tsx_layer.htable, tsx->transaction_key.ptr,
 
611
                 tsx->transaction_key.slen, 0, NULL);
 
612
#endif
 
613
 
 
614
    TSX_TRACE_((THIS_FILE,
 
615
                "Transaction %p unregistered, hkey=0x%p and key=%.*s",
 
616
                tsx, tsx->hashed_key, tsx->transaction_key.slen,
 
617
                tsx->transaction_key.ptr));
 
618
 
 
619
    /* Unlock mutex. */
 
620
    pj_mutex_unlock(mod_tsx_layer.mutex);
 
621
}
 
622
 
 
623
 
 
624
/*
 
625
 * Retrieve the current number of transactions currently registered in
 
626
 * the hash table.
 
627
 */
 
628
PJ_DEF(unsigned) pjsip_tsx_layer_get_tsx_count(void)
 
629
{
 
630
    unsigned count;
 
631
 
 
632
    /* Are we registered? */
 
633
    PJ_ASSERT_RETURN(mod_tsx_layer.endpt!=NULL, 0);
 
634
 
 
635
    pj_mutex_lock(mod_tsx_layer.mutex);
 
636
    count = pj_hash_count(mod_tsx_layer.htable);
 
637
    pj_mutex_unlock(mod_tsx_layer.mutex);
 
638
 
 
639
    return count;
 
640
}
 
641
 
 
642
 
 
643
/*
 
644
 * Find a transaction.
 
645
 */
 
646
PJ_DEF(pjsip_transaction*) pjsip_tsx_layer_find_tsx( const pj_str_t *key,
 
647
                                                     pj_bool_t lock )
 
648
{
 
649
    pjsip_transaction *tsx;
 
650
    pj_uint32_t hval = 0;
 
651
 
 
652
    pj_mutex_lock(mod_tsx_layer.mutex);
 
653
    tsx = (pjsip_transaction*)
 
654
          pj_hash_get( mod_tsx_layer.htable, key->ptr, key->slen, &hval );
 
655
    pj_mutex_unlock(mod_tsx_layer.mutex);
 
656
 
 
657
    TSX_TRACE_((THIS_FILE,
 
658
                "Finding tsx with hkey=0x%p and key=%.*s: found %p",
 
659
                hval, key->slen, key->ptr, tsx));
 
660
 
 
661
    /* Race condition!
 
662
     * Transaction may gets deleted before we have chance to lock it.
 
663
     */
 
664
    PJ_TODO(FIX_RACE_CONDITION_HERE);
 
665
    if (tsx && lock)
 
666
        pj_mutex_lock(tsx->mutex);
 
667
 
 
668
    return tsx;
 
669
}
 
670
 
 
671
 
 
672
/* This module callback is called when module is being loaded by
 
673
 * endpoint. It does nothing for this module.
 
674
 */
 
675
static pj_status_t mod_tsx_layer_load(pjsip_endpoint *endpt)
 
676
{
 
677
    PJ_UNUSED_ARG(endpt);
 
678
    return PJ_SUCCESS;
 
679
}
 
680
 
 
681
 
 
682
/* This module callback is called when module is being started by
 
683
 * endpoint. It does nothing for this module.
 
684
 */
 
685
static pj_status_t mod_tsx_layer_start(void)
 
686
{
 
687
    return PJ_SUCCESS;
 
688
}
 
689
 
 
690
 
 
691
/* This module callback is called when module is being stopped by
 
692
 * endpoint.
 
693
 */
 
694
static pj_status_t mod_tsx_layer_stop(void)
 
695
{
 
696
    pj_hash_iterator_t it_buf, *it;
 
697
 
 
698
    PJ_LOG(4,(THIS_FILE, "Stopping transaction layer module"));
 
699
 
 
700
    pj_mutex_lock(mod_tsx_layer.mutex);
 
701
 
 
702
    /* Destroy all transactions. */
 
703
    it = pj_hash_first(mod_tsx_layer.htable, &it_buf);
 
704
    while (it) {
 
705
        pjsip_transaction *tsx = (pjsip_transaction*)
 
706
                                 pj_hash_this(mod_tsx_layer.htable, it);
 
707
        pj_hash_iterator_t *next = pj_hash_next(mod_tsx_layer.htable, it);
 
708
        if (tsx) {
 
709
            pjsip_tsx_terminate(tsx, PJSIP_SC_SERVICE_UNAVAILABLE);
 
710
            mod_tsx_layer_unregister_tsx(tsx);
 
711
            tsx_destroy(tsx);
 
712
        }
 
713
        it = next;
 
714
    }
 
715
 
 
716
    pj_mutex_unlock(mod_tsx_layer.mutex);
 
717
 
 
718
    PJ_LOG(4,(THIS_FILE, "Stopped transaction layer module"));
 
719
 
 
720
    return PJ_SUCCESS;
 
721
}
 
722
 
 
723
 
 
724
/* Destroy this module */
 
725
static void tsx_layer_destroy(pjsip_endpoint *endpt)
 
726
{
 
727
    PJ_UNUSED_ARG(endpt);
 
728
 
 
729
    /* Destroy mutex. */
 
730
    pj_mutex_destroy(mod_tsx_layer.mutex);
 
731
 
 
732
    /* Release pool. */
 
733
    pjsip_endpt_release_pool(mod_tsx_layer.endpt, mod_tsx_layer.pool);
 
734
 
 
735
    /* Free TLS */
 
736
    pj_thread_local_free(pjsip_tsx_lock_tls_id);
 
737
 
 
738
    /* Mark as unregistered. */
 
739
    mod_tsx_layer.endpt = NULL;
 
740
 
 
741
    PJ_LOG(4,(THIS_FILE, "Transaction layer module destroyed"));
 
742
}
 
743
 
 
744
 
 
745
/* This module callback is called when module is being unloaded by
 
746
 * endpoint.
 
747
 */
 
748
static pj_status_t mod_tsx_layer_unload(void)
 
749
{
 
750
    /* Only self destroy when there's no transaction in the table.
 
751
     * Transaction may refuse to destroy when it has pending
 
752
     * transmission. If we destroy the module now, application will
 
753
     * crash when the pending transaction finally got error response
 
754
     * from transport and when it tries to unregister itself.
 
755
     */
 
756
    if (pj_hash_count(mod_tsx_layer.htable) != 0) {
 
757
        if (pjsip_endpt_atexit(mod_tsx_layer.endpt, &tsx_layer_destroy) !=
 
758
            PJ_SUCCESS)
 
759
        {
 
760
            PJ_LOG(3,(THIS_FILE, "Failed to register transaction layer "
 
761
                                 "module destroy."));
 
762
        }
 
763
        return PJ_EBUSY;
 
764
    }
 
765
 
 
766
    tsx_layer_destroy(mod_tsx_layer.endpt);
 
767
 
 
768
    return PJ_SUCCESS;
 
769
}
 
770
 
 
771
 
 
772
/* This module callback is called when endpoint has received an
 
773
 * incoming request message.
 
774
 */
 
775
static pj_bool_t mod_tsx_layer_on_rx_request(pjsip_rx_data *rdata)
 
776
{
 
777
    pj_str_t key;
 
778
    pj_uint32_t hval = 0;
 
779
    pjsip_transaction *tsx;
 
780
 
 
781
    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS,
 
782
                         &rdata->msg_info.cseq->method, rdata);
 
783
 
 
784
    /* Find transaction. */
 
785
    pj_mutex_lock( mod_tsx_layer.mutex );
 
786
 
 
787
    tsx = (pjsip_transaction*)
 
788
          pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen, &hval );
 
789
 
 
790
 
 
791
    TSX_TRACE_((THIS_FILE,
 
792
                "Finding tsx for request, hkey=0x%p and key=%.*s, found %p",
 
793
                hval, key.slen, key.ptr, tsx));
 
794
 
 
795
 
 
796
    if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) {
 
797
        /* Transaction not found.
 
798
         * Reject the request so that endpoint passes the request to
 
799
         * upper layer modules.
 
800
         */
 
801
        pj_mutex_unlock( mod_tsx_layer.mutex);
 
802
        return PJ_FALSE;
 
803
    }
 
804
 
 
805
    /* Unlock hash table. */
 
806
    pj_mutex_unlock( mod_tsx_layer.mutex );
 
807
 
 
808
    /* Race condition!
 
809
     * Transaction may gets deleted before we have chance to lock it
 
810
     * in pjsip_tsx_recv_msg().
 
811
     */
 
812
    PJ_TODO(FIX_RACE_CONDITION_HERE);
 
813
 
 
814
    /* Pass the message to the transaction. */
 
815
    pjsip_tsx_recv_msg(tsx, rdata );
 
816
 
 
817
    return PJ_TRUE;
 
818
}
 
819
 
 
820
 
 
821
/* This module callback is called when endpoint has received an
 
822
 * incoming response message.
 
823
 */
 
824
static pj_bool_t mod_tsx_layer_on_rx_response(pjsip_rx_data *rdata)
 
825
{
 
826
    pj_str_t key;
 
827
    pj_uint32_t hval = 0;
 
828
    pjsip_transaction *tsx;
 
829
 
 
830
    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAC,
 
831
                         &rdata->msg_info.cseq->method, rdata);
 
832
 
 
833
    /* Find transaction. */
 
834
    pj_mutex_lock( mod_tsx_layer.mutex );
 
835
 
 
836
    tsx = (pjsip_transaction*)
 
837
          pj_hash_get( mod_tsx_layer.htable, key.ptr, key.slen, &hval );
 
838
 
 
839
 
 
840
    TSX_TRACE_((THIS_FILE,
 
841
                "Finding tsx for response, hkey=0x%p and key=%.*s, found %p",
 
842
                hval, key.slen, key.ptr, tsx));
 
843
 
 
844
 
 
845
    if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) {
 
846
        /* Transaction not found.
 
847
         * Reject the request so that endpoint passes the request to
 
848
         * upper layer modules.
 
849
         */
 
850
        pj_mutex_unlock( mod_tsx_layer.mutex);
 
851
        return PJ_FALSE;
 
852
    }
 
853
 
 
854
    /* Unlock hash table. */
 
855
    pj_mutex_unlock( mod_tsx_layer.mutex );
 
856
 
 
857
    /* Race condition!
 
858
     * Transaction may gets deleted before we have chance to lock it
 
859
     * in pjsip_tsx_recv_msg().
 
860
     */
 
861
    PJ_TODO(FIX_RACE_CONDITION_HERE);
 
862
 
 
863
    /* Pass the message to the transaction. */
 
864
    pjsip_tsx_recv_msg(tsx, rdata );
 
865
 
 
866
    return PJ_TRUE;
 
867
}
 
868
 
 
869
 
 
870
/*
 
871
 * Get transaction instance in the rdata.
 
872
 */
 
873
PJ_DEF(pjsip_transaction*) pjsip_rdata_get_tsx( pjsip_rx_data *rdata )
 
874
{
 
875
    return (pjsip_transaction*)
 
876
           rdata->endpt_info.mod_data[mod_tsx_layer.mod.id];
 
877
}
 
878
 
 
879
 
 
880
/*
 
881
 * Dump transaction layer.
 
882
 */
 
883
PJ_DEF(void) pjsip_tsx_layer_dump(pj_bool_t detail)
 
884
{
 
885
#if PJ_LOG_MAX_LEVEL >= 3
 
886
    pj_hash_iterator_t itbuf, *it;
 
887
 
 
888
    /* Lock mutex. */
 
889
    pj_mutex_lock(mod_tsx_layer.mutex);
 
890
 
 
891
    PJ_LOG(3, (THIS_FILE, "Dumping transaction table:"));
 
892
    PJ_LOG(3, (THIS_FILE, " Total %d transactions",
 
893
                          pj_hash_count(mod_tsx_layer.htable)));
 
894
 
 
895
    if (detail) {
 
896
        it = pj_hash_first(mod_tsx_layer.htable, &itbuf);
 
897
        if (it == NULL) {
 
898
            PJ_LOG(3, (THIS_FILE, " - none - "));
 
899
        } else {
 
900
            while (it != NULL) {
 
901
                pjsip_transaction *tsx = (pjsip_transaction*)
 
902
                                         pj_hash_this(mod_tsx_layer.htable,it);
 
903
 
 
904
                PJ_LOG(3, (THIS_FILE, " %s %s|%d|%s",
 
905
                           tsx->obj_name,
 
906
                           (tsx->last_tx?
 
907
                                pjsip_tx_data_get_info(tsx->last_tx):
 
908
                                "none"),
 
909
                           tsx->status_code,
 
910
                           pjsip_tsx_state_str(tsx->state)));
 
911
 
 
912
                it = pj_hash_next(mod_tsx_layer.htable, it);
 
913
            }
 
914
        }
 
915
    }
 
916
 
 
917
    /* Unlock mutex. */
 
918
    pj_mutex_unlock(mod_tsx_layer.mutex);
 
919
#endif
 
920
}
 
921
 
 
922
/*****************************************************************************
 
923
 **
 
924
 ** Transaction
 
925
 **
 
926
 *****************************************************************************
 
927
 **/
 
928
/*
 
929
 * Lock transaction and set the value of Thread Local Storage.
 
930
 */
 
931
static void lock_tsx(pjsip_transaction *tsx, struct tsx_lock_data *lck)
 
932
{
 
933
    struct tsx_lock_data *prev_data;
 
934
 
 
935
    pj_mutex_lock(tsx->mutex);
 
936
    prev_data = (struct tsx_lock_data *)
 
937
                    pj_thread_local_get(pjsip_tsx_lock_tls_id);
 
938
    lck->prev = prev_data;
 
939
    lck->tsx = tsx;
 
940
    lck->is_alive = 1;
 
941
    pj_thread_local_set(pjsip_tsx_lock_tls_id, lck);
 
942
}
 
943
 
 
944
 
 
945
/*
 
946
 * Unlock transaction.
 
947
 * This will selectively unlock the mutex ONLY IF the transaction has not been
 
948
 * destroyed. The function knows whether the transaction has been destroyed
 
949
 * because when transaction is destroyed the is_alive flag for the transaction
 
950
 * will be set to zero.
 
951
 */
 
952
static pj_status_t unlock_tsx( pjsip_transaction *tsx,
 
953
                               struct tsx_lock_data *lck)
 
954
{
 
955
    pj_assert( (void*)pj_thread_local_get(pjsip_tsx_lock_tls_id) == lck);
 
956
    pj_assert( lck->tsx == tsx );
 
957
    pj_thread_local_set(pjsip_tsx_lock_tls_id, lck->prev);
 
958
    if (lck->is_alive)
 
959
        pj_mutex_unlock(tsx->mutex);
 
960
 
 
961
    return lck->is_alive ? PJ_SUCCESS : PJSIP_ETSXDESTROYED;
 
962
}
 
963
 
 
964
 
 
965
/* Lock transaction for accessing the timeout timer only. */
 
966
static void lock_timer(pjsip_transaction *tsx)
 
967
{
 
968
    pj_mutex_lock(tsx->mutex_b);
 
969
}
 
970
 
 
971
/* Unlock timer */
 
972
static void unlock_timer(pjsip_transaction *tsx)
 
973
{
 
974
    pj_mutex_unlock(tsx->mutex_b);
 
975
}
 
976
 
 
977
/* Create and initialize basic transaction structure.
 
978
 * This function is called by both UAC and UAS creation.
 
979
 */
 
980
static pj_status_t tsx_create( pjsip_module *tsx_user,
 
981
                               pjsip_transaction **p_tsx)
 
982
{
 
983
    pj_pool_t *pool;
 
984
    pjsip_transaction *tsx;
 
985
    pj_status_t status;
 
986
 
 
987
    pool = pjsip_endpt_create_pool( mod_tsx_layer.endpt, "tsx",
 
988
                                    PJSIP_POOL_TSX_LEN, PJSIP_POOL_TSX_INC );
 
989
    if (!pool)
 
990
        return PJ_ENOMEM;
 
991
 
 
992
    tsx = PJ_POOL_ZALLOC_T(pool, pjsip_transaction);
 
993
    tsx->pool = pool;
 
994
    tsx->tsx_user = tsx_user;
 
995
    tsx->endpt = mod_tsx_layer.endpt;
 
996
 
 
997
    pj_ansi_snprintf(tsx->obj_name, sizeof(tsx->obj_name),
 
998
                     "tsx%p", tsx);
 
999
    pj_memcpy(pool->obj_name, tsx->obj_name, sizeof(pool->obj_name));
 
1000
 
 
1001
    tsx->handle_200resp = 1;
 
1002
    tsx->retransmit_timer.id = 0;
 
1003
    tsx->retransmit_timer.user_data = tsx;
 
1004
    tsx->retransmit_timer.cb = &tsx_timer_callback;
 
1005
    tsx->timeout_timer.id = 0;
 
1006
    tsx->timeout_timer.user_data = tsx;
 
1007
    tsx->timeout_timer.cb = &tsx_timer_callback;
 
1008
 
 
1009
    status = pj_mutex_create_recursive(pool, tsx->obj_name, &tsx->mutex);
 
1010
    if (status != PJ_SUCCESS) {
 
1011
        pjsip_endpt_release_pool(mod_tsx_layer.endpt, pool);
 
1012
        return status;
 
1013
    }
 
1014
 
 
1015
    status = pj_mutex_create_simple(pool, tsx->obj_name, &tsx->mutex_b);
 
1016
    if (status != PJ_SUCCESS) {
 
1017
        pj_mutex_destroy(tsx->mutex);
 
1018
        pjsip_endpt_release_pool(mod_tsx_layer.endpt, pool);
 
1019
        return status;
 
1020
    }
 
1021
 
 
1022
    *p_tsx = tsx;
 
1023
    return PJ_SUCCESS;
 
1024
}
 
1025
 
 
1026
 
 
1027
/* Destroy transaction. */
 
1028
static pj_status_t tsx_destroy( pjsip_transaction *tsx )
 
1029
{
 
1030
    struct tsx_lock_data *lck;
 
1031
 
 
1032
    /* Release the transport */
 
1033
    tsx_update_transport(tsx, NULL);
 
1034
 
 
1035
    /* Decrement reference counter in transport selector */
 
1036
    pjsip_tpselector_dec_ref(&tsx->tp_sel);
 
1037
 
 
1038
    /* Free last transmitted message. */
 
1039
    if (tsx->last_tx) {
 
1040
        pjsip_tx_data_dec_ref( tsx->last_tx );
 
1041
        tsx->last_tx = NULL;
 
1042
    }
 
1043
    /* Cancel timeout timer. */
 
1044
    if (tsx->timeout_timer.id != 0) {
 
1045
        pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
 
1046
        tsx->timeout_timer.id = 0;
 
1047
    }
 
1048
    /* Cancel retransmission timer. */
 
1049
    if (tsx->retransmit_timer.id != 0) {
 
1050
        pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
1051
        tsx->retransmit_timer.id = 0;
 
1052
    }
 
1053
 
 
1054
    /* Clear some pending flags. */
 
1055
    tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED | TSX_HAS_PENDING_SEND);
 
1056
 
 
1057
    /* Refuse to destroy transaction if it has pending resolving. */
 
1058
    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
1059
        tsx->transport_flag |= TSX_HAS_PENDING_DESTROY;
 
1060
        tsx->tsx_user = NULL;
 
1061
        PJ_LOG(4,(tsx->obj_name, "Will destroy later because transport is "
 
1062
                                 "in progress"));
 
1063
        return PJ_EBUSY;
 
1064
    }
 
1065
 
 
1066
    /* Clear TLS, so that mutex will not be unlocked */
 
1067
    lck = (struct tsx_lock_data*) pj_thread_local_get(pjsip_tsx_lock_tls_id);
 
1068
    while (lck) {
 
1069
        if (lck->tsx == tsx) {
 
1070
            lck->is_alive = 0;
 
1071
        }
 
1072
        lck = lck->prev;
 
1073
    }
 
1074
 
 
1075
    pj_mutex_destroy(tsx->mutex_b);
 
1076
    pj_mutex_destroy(tsx->mutex);
 
1077
 
 
1078
    PJ_LOG(5,(tsx->obj_name, "Transaction destroyed!"));
 
1079
 
 
1080
    pjsip_endpt_release_pool(tsx->endpt, tsx->pool);
 
1081
 
 
1082
    return PJ_SUCCESS;
 
1083
}
 
1084
 
 
1085
 
 
1086
/*
 
1087
 * Callback when timer expires.
 
1088
 */
 
1089
static void tsx_timer_callback( pj_timer_heap_t *theap, pj_timer_entry *entry)
 
1090
{
 
1091
    pjsip_event event;
 
1092
    pjsip_transaction *tsx = (pjsip_transaction*) entry->user_data;
 
1093
    struct tsx_lock_data lck;
 
1094
 
 
1095
    PJ_UNUSED_ARG(theap);
 
1096
 
 
1097
    entry->id = 0;
 
1098
 
 
1099
    PJ_LOG(5,(tsx->obj_name, "%s timer event",
 
1100
             (entry==&tsx->retransmit_timer ? "Retransmit":"Timeout")));
 
1101
    pj_log_push_indent();
 
1102
 
 
1103
 
 
1104
    PJSIP_EVENT_INIT_TIMER(event, entry);
 
1105
 
 
1106
    /* Dispatch event to transaction. */
 
1107
    lock_tsx(tsx, &lck);
 
1108
    (*tsx->state_handler)(tsx, &event);
 
1109
    unlock_tsx(tsx, &lck);
 
1110
 
 
1111
    pj_log_pop_indent();
 
1112
}
 
1113
 
 
1114
 
 
1115
/*
 
1116
 * Set transaction state, and inform TU about the transaction state change.
 
1117
 */
 
1118
static void tsx_set_state( pjsip_transaction *tsx,
 
1119
                           pjsip_tsx_state_e state,
 
1120
                           pjsip_event_id_e event_src_type,
 
1121
                           void *event_src )
 
1122
{
 
1123
    pjsip_tsx_state_e prev_state = tsx->state;
 
1124
 
 
1125
    /* New state must be greater than previous state */
 
1126
    pj_assert(state >= tsx->state);
 
1127
 
 
1128
    PJ_LOG(5, (tsx->obj_name, "State changed from %s to %s, event=%s",
 
1129
               state_str[tsx->state], state_str[state],
 
1130
               pjsip_event_str(event_src_type)));
 
1131
    pj_log_push_indent();
 
1132
 
 
1133
    /* Change state. */
 
1134
    tsx->state = state;
 
1135
 
 
1136
    /* Update the state handlers. */
 
1137
    if (tsx->role == PJSIP_ROLE_UAC) {
 
1138
        tsx->state_handler = tsx_state_handler_uac[state];
 
1139
    } else {
 
1140
        tsx->state_handler = tsx_state_handler_uas[state];
 
1141
    }
 
1142
 
 
1143
    /* Before informing TU about state changed, inform TU about
 
1144
     * rx event.
 
1145
     */
 
1146
    if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user) {
 
1147
        pjsip_rx_data *rdata = (pjsip_rx_data*) event_src;
 
1148
 
 
1149
        pj_assert(rdata != NULL);
 
1150
 
 
1151
        if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG &&
 
1152
                   tsx->tsx_user->on_rx_response)
 
1153
        {
 
1154
            (*tsx->tsx_user->on_rx_response)(rdata);
 
1155
        }
 
1156
 
 
1157
    }
 
1158
 
 
1159
    /* Inform TU about state changed. */
 
1160
    if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) {
 
1161
        pjsip_event e;
 
1162
        PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src,
 
1163
                                   prev_state);
 
1164
        (*tsx->tsx_user->on_tsx_state)(tsx, &e);
 
1165
    }
 
1166
 
 
1167
 
 
1168
    /* When the transaction is terminated, release transport, and free the
 
1169
     * saved last transmitted message.
 
1170
     */
 
1171
    if (state == PJSIP_TSX_STATE_TERMINATED) {
 
1172
        pj_time_val timeout = {0, 0};
 
1173
 
 
1174
        /* If we're still waiting for a message to be sent.. */
 
1175
        if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
1176
            /* Disassociate ourselves from the outstanding transmit data
 
1177
             * so that when the send callback is called we will be able
 
1178
             * to ignore that (otherwise we'll get assertion, see
 
1179
             * http://trac.pjsip.org/repos/ticket/1033)
 
1180
             */
 
1181
            if (tsx->pending_tx) {
 
1182
                tsx->pending_tx->mod_data[mod_tsx_layer.mod.id] = NULL;
 
1183
                tsx->pending_tx = NULL;
 
1184
            }
 
1185
            tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);
 
1186
        }
 
1187
 
 
1188
        lock_timer(tsx);
 
1189
 
 
1190
        /* Cancel timeout timer. */
 
1191
        if (tsx->timeout_timer.id != 0) {
 
1192
            pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
 
1193
            tsx->timeout_timer.id = 0;
 
1194
        }
 
1195
 
 
1196
        tsx->timeout_timer.id = TIMER_ACTIVE;
 
1197
        pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
 
1198
                                    &timeout);
 
1199
 
 
1200
        unlock_timer(tsx);
 
1201
 
 
1202
    } else if (state == PJSIP_TSX_STATE_DESTROYED) {
 
1203
 
 
1204
        /* Unregister transaction. */
 
1205
        mod_tsx_layer_unregister_tsx(tsx);
 
1206
 
 
1207
        /* Destroy transaction. */
 
1208
        tsx_destroy(tsx);
 
1209
    }
 
1210
 
 
1211
    pj_log_pop_indent();
 
1212
}
 
1213
 
 
1214
 
 
1215
/*
 
1216
 * Create, initialize, and register UAC transaction.
 
1217
 */
 
1218
PJ_DEF(pj_status_t) pjsip_tsx_create_uac( pjsip_module *tsx_user,
 
1219
                                          pjsip_tx_data *tdata,
 
1220
                                          pjsip_transaction **p_tsx)
 
1221
{
 
1222
    pjsip_transaction *tsx;
 
1223
    pjsip_msg *msg;
 
1224
    pjsip_cseq_hdr *cseq;
 
1225
    pjsip_via_hdr *via;
 
1226
    pjsip_host_info dst_info;
 
1227
    struct tsx_lock_data lck;
 
1228
    pj_status_t status;
 
1229
 
 
1230
    /* Validate arguments. */
 
1231
    PJ_ASSERT_RETURN(tdata && tdata->msg && p_tsx, PJ_EINVAL);
 
1232
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
 
1233
                     PJSIP_ENOTREQUESTMSG);
 
1234
 
 
1235
    /* Method MUST NOT be ACK! */
 
1236
    PJ_ASSERT_RETURN(tdata->msg->line.req.method.id != PJSIP_ACK_METHOD,
 
1237
                     PJ_EINVALIDOP);
 
1238
 
 
1239
    /* Keep shortcut */
 
1240
    msg = tdata->msg;
 
1241
 
 
1242
    /* Make sure CSeq header is present. */
 
1243
    cseq = (pjsip_cseq_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);
 
1244
    if (!cseq) {
 
1245
        pj_assert(!"CSeq header not present in outgoing message!");
 
1246
        return PJSIP_EMISSINGHDR;
 
1247
    }
 
1248
 
 
1249
 
 
1250
    /* Create transaction instance. */
 
1251
    status = tsx_create( tsx_user, &tsx);
 
1252
    if (status != PJ_SUCCESS)
 
1253
        return status;
 
1254
 
 
1255
 
 
1256
    /* Lock transaction. */
 
1257
    lock_tsx(tsx, &lck);
 
1258
 
 
1259
    /* Role is UAC. */
 
1260
    tsx->role = PJSIP_ROLE_UAC;
 
1261
 
 
1262
    /* Save method. */
 
1263
    pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method);
 
1264
 
 
1265
    /* Save CSeq. */
 
1266
    tsx->cseq = cseq->cseq;
 
1267
 
 
1268
    /* Generate Via header if it doesn't exist. */
 
1269
    via = (pjsip_via_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_VIA, NULL);
 
1270
    if (via == NULL) {
 
1271
        via = pjsip_via_hdr_create(tdata->pool);
 
1272
        pjsip_msg_insert_first_hdr(msg, (pjsip_hdr*) via);
 
1273
    }
 
1274
 
 
1275
    /* Generate branch parameter if it doesn't exist. */
 
1276
    if (via->branch_param.slen == 0) {
 
1277
        pj_str_t tmp;
 
1278
        via->branch_param.ptr = (char*)
 
1279
                                pj_pool_alloc(tsx->pool, PJSIP_MAX_BRANCH_LEN);
 
1280
        via->branch_param.slen = PJSIP_MAX_BRANCH_LEN;
 
1281
        pj_memcpy(via->branch_param.ptr, PJSIP_RFC3261_BRANCH_ID,
 
1282
                  PJSIP_RFC3261_BRANCH_LEN);
 
1283
        tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;
 
1284
        *(tmp.ptr-2) = 80; *(tmp.ptr-1) = 106;
 
1285
        pj_generate_unique_string( &tmp );
 
1286
 
 
1287
        /* Save branch parameter. */
 
1288
        tsx->branch = via->branch_param;
 
1289
 
 
1290
    } else {
 
1291
        /* Copy branch parameter. */
 
1292
        pj_strdup(tsx->pool, &tsx->branch, &via->branch_param);
 
1293
    }
 
1294
 
 
1295
   /* Generate transaction key. */
 
1296
    create_tsx_key_3261( tsx->pool, &tsx->transaction_key,
 
1297
                         PJSIP_ROLE_UAC, &tsx->method,
 
1298
                         &via->branch_param);
 
1299
 
 
1300
    /* Calculate hashed key value. */
 
1301
#ifdef PRECALC_HASH
 
1302
    tsx->hashed_key = pj_hash_calc(0, tsx->transaction_key.ptr,
 
1303
                                   tsx->transaction_key.slen);
 
1304
#endif
 
1305
 
 
1306
    PJ_LOG(6, (tsx->obj_name, "tsx_key=%.*s", tsx->transaction_key.slen,
 
1307
               tsx->transaction_key.ptr));
 
1308
 
 
1309
    /* Begin with State_Null.
 
1310
     * Manually set-up the state becase we don't want to call the callback.
 
1311
     */
 
1312
    tsx->state = PJSIP_TSX_STATE_NULL;
 
1313
    tsx->state_handler = &tsx_on_state_null;
 
1314
 
 
1315
    /* Save the message. */
 
1316
    tsx->last_tx = tdata;
 
1317
    pjsip_tx_data_add_ref(tsx->last_tx);
 
1318
 
 
1319
    /* Determine whether reliable transport should be used initially.
 
1320
     * This will be updated whenever transport has changed.
 
1321
     */
 
1322
    status = pjsip_get_request_dest(tdata, &dst_info);
 
1323
    if (status != PJ_SUCCESS) {
 
1324
        unlock_tsx(tsx, &lck);
 
1325
        tsx_destroy(tsx);
 
1326
        return status;
 
1327
    }
 
1328
    tsx->is_reliable = (dst_info.flag & PJSIP_TRANSPORT_RELIABLE);
 
1329
 
 
1330
    /* Register transaction to hash table. */
 
1331
    status = mod_tsx_layer_register_tsx(tsx);
 
1332
    if (status != PJ_SUCCESS) {
 
1333
        /* The assertion is removed by #1090:
 
1334
        pj_assert(!"Bug in branch_param generator (i.e. not unique)");
 
1335
        */
 
1336
        unlock_tsx(tsx, &lck);
 
1337
        tsx_destroy(tsx);
 
1338
        return status;
 
1339
    }
 
1340
 
 
1341
 
 
1342
    /* Unlock transaction and return. */
 
1343
    unlock_tsx(tsx, &lck);
 
1344
 
 
1345
    pj_log_push_indent();
 
1346
    PJ_LOG(5,(tsx->obj_name, "Transaction created for %s",
 
1347
              pjsip_tx_data_get_info(tdata)));
 
1348
    pj_log_pop_indent();
 
1349
 
 
1350
    *p_tsx = tsx;
 
1351
    return PJ_SUCCESS;
 
1352
}
 
1353
 
 
1354
 
 
1355
/*
 
1356
 * Create, initialize, and register UAS transaction.
 
1357
 */
 
1358
PJ_DEF(pj_status_t) pjsip_tsx_create_uas( pjsip_module *tsx_user,
 
1359
                                          pjsip_rx_data *rdata,
 
1360
                                          pjsip_transaction **p_tsx)
 
1361
{
 
1362
    pjsip_transaction *tsx;
 
1363
    pjsip_msg *msg;
 
1364
    pj_str_t *branch;
 
1365
    pjsip_cseq_hdr *cseq;
 
1366
    pj_status_t status;
 
1367
    struct tsx_lock_data lck;
 
1368
 
 
1369
    /* Validate arguments. */
 
1370
    PJ_ASSERT_RETURN(rdata && rdata->msg_info.msg && p_tsx, PJ_EINVAL);
 
1371
 
 
1372
    /* Keep shortcut to message */
 
1373
    msg = rdata->msg_info.msg;
 
1374
 
 
1375
    /* Make sure this is a request message. */
 
1376
    PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG, PJSIP_ENOTREQUESTMSG);
 
1377
 
 
1378
    /* Make sure method is not ACK */
 
1379
    PJ_ASSERT_RETURN(msg->line.req.method.id != PJSIP_ACK_METHOD,
 
1380
                     PJ_EINVALIDOP);
 
1381
 
 
1382
    /* Make sure CSeq header is present. */
 
1383
    cseq = rdata->msg_info.cseq;
 
1384
    if (!cseq)
 
1385
        return PJSIP_EMISSINGHDR;
 
1386
 
 
1387
    /* Make sure Via header is present. */
 
1388
    if (rdata->msg_info.via == NULL)
 
1389
        return PJSIP_EMISSINGHDR;
 
1390
 
 
1391
    /* Check that method in CSeq header match request method.
 
1392
     * Reference: PROTOS #1922
 
1393
     */
 
1394
    if (pjsip_method_cmp(&msg->line.req.method,
 
1395
                         &rdata->msg_info.cseq->method) != 0)
 
1396
    {
 
1397
        PJ_LOG(4,(THIS_FILE, "Error: CSeq header contains different "
 
1398
                             "method than the request line"));
 
1399
        return PJSIP_EINVALIDHDR;
 
1400
    }
 
1401
 
 
1402
    /*
 
1403
     * Create transaction instance.
 
1404
     */
 
1405
    status = tsx_create( tsx_user, &tsx);
 
1406
    if (status != PJ_SUCCESS)
 
1407
        return status;
 
1408
 
 
1409
 
 
1410
    /* Lock transaction. */
 
1411
    lock_tsx(tsx, &lck);
 
1412
 
 
1413
    /* Role is UAS */
 
1414
    tsx->role = PJSIP_ROLE_UAS;
 
1415
 
 
1416
    /* Save method. */
 
1417
    pjsip_method_copy( tsx->pool, &tsx->method, &msg->line.req.method);
 
1418
 
 
1419
    /* Save CSeq */
 
1420
    tsx->cseq = cseq->cseq;
 
1421
 
 
1422
    /* Get transaction key either from branch for RFC3261 message, or
 
1423
     * create transaction key.
 
1424
     */
 
1425
    status = pjsip_tsx_create_key(tsx->pool, &tsx->transaction_key,
 
1426
                                  PJSIP_ROLE_UAS, &tsx->method, rdata);
 
1427
    if (status != PJ_SUCCESS) {
 
1428
        unlock_tsx(tsx, &lck);
 
1429
        tsx_destroy(tsx);
 
1430
        return status;
 
1431
    }
 
1432
 
 
1433
    /* Calculate hashed key value. */
 
1434
#ifdef PRECALC_HASH
 
1435
    tsx->hashed_key = pj_hash_calc(0, tsx->transaction_key.ptr,
 
1436
                                   tsx->transaction_key.slen);
 
1437
#endif
 
1438
 
 
1439
    /* Duplicate branch parameter for transaction. */
 
1440
    branch = &rdata->msg_info.via->branch_param;
 
1441
    pj_strdup(tsx->pool, &tsx->branch, branch);
 
1442
 
 
1443
    PJ_LOG(6, (tsx->obj_name, "tsx_key=%.*s", tsx->transaction_key.slen,
 
1444
               tsx->transaction_key.ptr));
 
1445
 
 
1446
 
 
1447
    /* Begin with state NULL.
 
1448
     * Manually set-up the state becase we don't want to call the callback.
 
1449
     */
 
1450
    tsx->state = PJSIP_TSX_STATE_NULL;
 
1451
    tsx->state_handler = &tsx_on_state_null;
 
1452
 
 
1453
    /* Get response address. */
 
1454
    status = pjsip_get_response_addr( tsx->pool, rdata, &tsx->res_addr );
 
1455
    if (status != PJ_SUCCESS) {
 
1456
        unlock_tsx(tsx, &lck);
 
1457
        tsx_destroy(tsx);
 
1458
        return status;
 
1459
    }
 
1460
 
 
1461
    /* If it's decided that we should use current transport, keep the
 
1462
     * transport.
 
1463
     */
 
1464
    if (tsx->res_addr.transport) {
 
1465
        tsx_update_transport(tsx, tsx->res_addr.transport);
 
1466
        pj_memcpy(&tsx->addr, &tsx->res_addr.addr, tsx->res_addr.addr_len);
 
1467
        tsx->addr_len = tsx->res_addr.addr_len;
 
1468
        tsx->is_reliable = PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport);
 
1469
    } else {
 
1470
        tsx->is_reliable =
 
1471
            (tsx->res_addr.dst_host.flag & PJSIP_TRANSPORT_RELIABLE);
 
1472
    }
 
1473
 
 
1474
 
 
1475
    /* Register the transaction. */
 
1476
    status = mod_tsx_layer_register_tsx(tsx);
 
1477
    if (status != PJ_SUCCESS) {
 
1478
        unlock_tsx(tsx, &lck);
 
1479
        tsx_destroy(tsx);
 
1480
        return status;
 
1481
    }
 
1482
 
 
1483
    /* Put this transaction in rdata's mod_data. */
 
1484
    rdata->endpt_info.mod_data[mod_tsx_layer.mod.id] = tsx;
 
1485
 
 
1486
    /* Unlock transaction and return. */
 
1487
    unlock_tsx(tsx, &lck);
 
1488
 
 
1489
    pj_log_push_indent();
 
1490
    PJ_LOG(5,(tsx->obj_name, "Transaction created for %s",
 
1491
              pjsip_rx_data_get_info(rdata)));
 
1492
    pj_log_pop_indent();
 
1493
 
 
1494
 
 
1495
    *p_tsx = tsx;
 
1496
    return PJ_SUCCESS;
 
1497
}
 
1498
 
 
1499
 
 
1500
/*
 
1501
 * Bind transaction to a specific transport/listener.
 
1502
 */
 
1503
PJ_DEF(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx,
 
1504
                                            const pjsip_tpselector *sel)
 
1505
{
 
1506
    struct tsx_lock_data lck;
 
1507
 
 
1508
    /* Must be UAC transaction */
 
1509
    PJ_ASSERT_RETURN(tsx && sel, PJ_EINVAL);
 
1510
 
 
1511
    /* Start locking the transaction. */
 
1512
    lock_tsx(tsx, &lck);
 
1513
 
 
1514
    /* Decrement reference counter of previous transport selector */
 
1515
    pjsip_tpselector_dec_ref(&tsx->tp_sel);
 
1516
 
 
1517
    /* Copy transport selector structure .*/
 
1518
    pj_memcpy(&tsx->tp_sel, sel, sizeof(*sel));
 
1519
 
 
1520
    /* Increment reference counter */
 
1521
    pjsip_tpselector_add_ref(&tsx->tp_sel);
 
1522
 
 
1523
    /* Unlock transaction. */
 
1524
    unlock_tsx(tsx, &lck);
 
1525
 
 
1526
    return PJ_SUCCESS;
 
1527
}
 
1528
 
 
1529
 
 
1530
/*
 
1531
 * Set transaction status code and reason.
 
1532
 */
 
1533
static void tsx_set_status_code(pjsip_transaction *tsx,
 
1534
                                int code, const pj_str_t *reason)
 
1535
{
 
1536
    tsx->status_code = code;
 
1537
    if (reason)
 
1538
        pj_strdup(tsx->pool, &tsx->status_text, reason);
 
1539
    else
 
1540
        tsx->status_text = *pjsip_get_status_text(code);
 
1541
}
 
1542
 
 
1543
 
 
1544
/*
 
1545
 * Forcely terminate transaction.
 
1546
 */
 
1547
PJ_DEF(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx, int code )
 
1548
{
 
1549
    struct tsx_lock_data lck;
 
1550
 
 
1551
    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);
 
1552
 
 
1553
    PJ_LOG(5,(tsx->obj_name, "Request to terminate transaction"));
 
1554
 
 
1555
    PJ_ASSERT_RETURN(code >= 200, PJ_EINVAL);
 
1556
 
 
1557
    if (tsx->state >= PJSIP_TSX_STATE_TERMINATED)
 
1558
        return PJ_SUCCESS;
 
1559
 
 
1560
    pj_log_push_indent();
 
1561
 
 
1562
    lock_tsx(tsx, &lck);
 
1563
    tsx_set_status_code(tsx, code, NULL);
 
1564
    tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, NULL);
 
1565
    unlock_tsx(tsx, &lck);
 
1566
 
 
1567
    pj_log_pop_indent();
 
1568
 
 
1569
    return PJ_SUCCESS;
 
1570
}
 
1571
 
 
1572
 
 
1573
/*
 
1574
 * Cease retransmission on the UAC transaction. The UAC transaction is
 
1575
 * still considered running, and it will complete when either final
 
1576
 * response is received or the transaction times out.
 
1577
 */
 
1578
PJ_DEF(pj_status_t) pjsip_tsx_stop_retransmit(pjsip_transaction *tsx)
 
1579
{
 
1580
    struct tsx_lock_data lck;
 
1581
 
 
1582
    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);
 
1583
    PJ_ASSERT_RETURN(tsx->role == PJSIP_ROLE_UAC &&
 
1584
                     tsx->method.id == PJSIP_INVITE_METHOD,
 
1585
                     PJ_EINVALIDOP);
 
1586
 
 
1587
    PJ_LOG(5,(tsx->obj_name, "Request to stop retransmission"));
 
1588
 
 
1589
    pj_log_push_indent();
 
1590
 
 
1591
    lock_tsx(tsx, &lck);
 
1592
    /* Cancel retransmission timer. */
 
1593
    if (tsx->retransmit_timer.id != 0) {
 
1594
        pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
1595
        tsx->retransmit_timer.id = 0;
 
1596
    }
 
1597
    unlock_tsx(tsx, &lck);
 
1598
 
 
1599
    pj_log_pop_indent();
 
1600
 
 
1601
    return PJ_SUCCESS;
 
1602
}
 
1603
 
 
1604
 
 
1605
/*
 
1606
 * Start a timer to terminate transaction after the specified time
 
1607
 * has elapsed.
 
1608
 */
 
1609
PJ_DEF(pj_status_t) pjsip_tsx_set_timeout( pjsip_transaction *tsx,
 
1610
                                           unsigned millisec)
 
1611
{
 
1612
    pj_time_val timeout;
 
1613
 
 
1614
    PJ_ASSERT_RETURN(tsx != NULL, PJ_EINVAL);
 
1615
    PJ_ASSERT_RETURN(tsx->role == PJSIP_ROLE_UAC &&
 
1616
                     tsx->method.id == PJSIP_INVITE_METHOD,
 
1617
                     PJ_EINVALIDOP);
 
1618
 
 
1619
    /* Note: must not call lock_tsx() as that would introduce deadlock.
 
1620
     * See #1121.
 
1621
     */
 
1622
    lock_timer(tsx);
 
1623
 
 
1624
    /* Transaction should normally not have final response, but as
 
1625
     * #1121 says there is a (tolerable) window of race condition
 
1626
     * where this might happen.
 
1627
     */
 
1628
    if (tsx->status_code >= 200 && tsx->timeout_timer.id != 0) {
 
1629
        /* Timeout is already set */
 
1630
        unlock_timer(tsx);
 
1631
        return PJ_EEXISTS;
 
1632
    }
 
1633
 
 
1634
    if (tsx->timeout_timer.id != 0) {
 
1635
        pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
 
1636
        tsx->timeout_timer.id = 0;
 
1637
    }
 
1638
 
 
1639
    timeout.sec = 0;
 
1640
    timeout.msec = millisec;
 
1641
    pj_time_val_normalize(&timeout);
 
1642
 
 
1643
    tsx->timeout_timer.id = TIMER_ACTIVE;
 
1644
    pjsip_endpt_schedule_timer(tsx->endpt, &tsx->timeout_timer,
 
1645
                               &timeout);
 
1646
 
 
1647
 
 
1648
    unlock_timer(tsx);
 
1649
 
 
1650
    return PJ_SUCCESS;
 
1651
}
 
1652
 
 
1653
 
 
1654
/*
 
1655
 * This function is called by TU to send a message.
 
1656
 */
 
1657
PJ_DEF(pj_status_t) pjsip_tsx_send_msg( pjsip_transaction *tsx,
 
1658
                                        pjsip_tx_data *tdata )
 
1659
{
 
1660
    pjsip_event event;
 
1661
    struct tsx_lock_data lck;
 
1662
    pj_status_t status;
 
1663
 
 
1664
    if (tdata == NULL)
 
1665
        tdata = tsx->last_tx;
 
1666
 
 
1667
    PJ_ASSERT_RETURN(tdata != NULL, PJ_EINVALIDOP);
 
1668
 
 
1669
    PJ_LOG(5,(tsx->obj_name, "Sending %s in state %s",
 
1670
                             pjsip_tx_data_get_info(tdata),
 
1671
                             state_str[tsx->state]));
 
1672
    pj_log_push_indent();
 
1673
 
 
1674
    PJSIP_EVENT_INIT_TX_MSG(event, tdata);
 
1675
 
 
1676
    /* Dispatch to transaction. */
 
1677
    lock_tsx(tsx, &lck);
 
1678
 
 
1679
    /* Set transport selector to tdata */
 
1680
    pjsip_tx_data_set_transport(tdata, &tsx->tp_sel);
 
1681
 
 
1682
    /* Dispatch to state handler */
 
1683
    status = (*tsx->state_handler)(tsx, &event);
 
1684
 
 
1685
    unlock_tsx(tsx, &lck);
 
1686
 
 
1687
    /* Only decrement reference counter when it returns success.
 
1688
     * (This is the specification from the .PDF design document).
 
1689
     */
 
1690
    if (status == PJ_SUCCESS) {
 
1691
        pjsip_tx_data_dec_ref(tdata);
 
1692
    }
 
1693
 
 
1694
    pj_log_pop_indent();
 
1695
 
 
1696
    return status;
 
1697
}
 
1698
 
 
1699
 
 
1700
/*
 
1701
 * This function is called by endpoint when incoming message for the
 
1702
 * transaction is received.
 
1703
 */
 
1704
PJ_DEF(void) pjsip_tsx_recv_msg( pjsip_transaction *tsx,
 
1705
                                 pjsip_rx_data *rdata)
 
1706
{
 
1707
    pjsip_event event;
 
1708
    struct tsx_lock_data lck;
 
1709
    pj_status_t status;
 
1710
 
 
1711
    PJ_LOG(5,(tsx->obj_name, "Incoming %s in state %s",
 
1712
              pjsip_rx_data_get_info(rdata), state_str[tsx->state]));
 
1713
    pj_log_push_indent();
 
1714
 
 
1715
    /* Put the transaction in the rdata's mod_data. */
 
1716
    rdata->endpt_info.mod_data[mod_tsx_layer.mod.id] = tsx;
 
1717
 
 
1718
    /* Init event. */
 
1719
    PJSIP_EVENT_INIT_RX_MSG(event, rdata);
 
1720
 
 
1721
    /* Dispatch to transaction. */
 
1722
    lock_tsx(tsx, &lck);
 
1723
    status = (*tsx->state_handler)(tsx, &event);
 
1724
    unlock_tsx(tsx, &lck);
 
1725
 
 
1726
    pj_log_pop_indent();
 
1727
}
 
1728
 
 
1729
 
 
1730
/* Callback called by send message framework */
 
1731
static void send_msg_callback( pjsip_send_state *send_state,
 
1732
                               pj_ssize_t sent, pj_bool_t *cont )
 
1733
{
 
1734
    pjsip_transaction *tsx = (pjsip_transaction*) send_state->token;
 
1735
    pjsip_tx_data *tdata = send_state->tdata;
 
1736
    struct tsx_lock_data lck;
 
1737
 
 
1738
    /* Check if transaction has cancelled itself from this transmit
 
1739
     * notification (https://trac.pjsip.org/repos/ticket/1033).
 
1740
     * Also check if the transaction layer itself may have been shutdown
 
1741
     * (https://trac.pjsip.org/repos/ticket/1535)
 
1742
     */
 
1743
    if (mod_tsx_layer.mod.id < 0 ||
 
1744
        tdata->mod_data[mod_tsx_layer.mod.id] == NULL)
 
1745
    {
 
1746
        *cont = PJ_FALSE;
 
1747
        return;
 
1748
    }
 
1749
 
 
1750
    /* Reset */
 
1751
    tdata->mod_data[mod_tsx_layer.mod.id] = NULL;
 
1752
    tsx->pending_tx = NULL;
 
1753
 
 
1754
    lock_tsx(tsx, &lck);
 
1755
 
 
1756
    if (sent > 0) {
 
1757
        /* Successfully sent! */
 
1758
        pj_assert(send_state->cur_transport != NULL);
 
1759
 
 
1760
        if (tsx->transport != send_state->cur_transport) {
 
1761
            /* Update transport. */
 
1762
            tsx_update_transport(tsx, send_state->cur_transport);
 
1763
 
 
1764
            /* Update remote address. */
 
1765
            tsx->addr_len = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr_len;
 
1766
            pj_memcpy(&tsx->addr,
 
1767
                      &tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr,
 
1768
                      tsx->addr_len);
 
1769
 
 
1770
            /* Update is_reliable flag. */
 
1771
            tsx->is_reliable = PJSIP_TRANSPORT_IS_RELIABLE(tsx->transport);
 
1772
        }
 
1773
 
 
1774
        /* Clear pending transport flag. */
 
1775
        tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);
 
1776
 
 
1777
        /* Mark that we have resolved the addresses. */
 
1778
        tsx->transport_flag |= TSX_HAS_RESOLVED_SERVER;
 
1779
 
 
1780
        /* Pending destroy? */
 
1781
        if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) {
 
1782
            tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED,
 
1783
                           PJSIP_EVENT_UNKNOWN, NULL );
 
1784
            unlock_tsx(tsx, &lck);
 
1785
            return;
 
1786
        }
 
1787
 
 
1788
        /* Need to transmit a message? */
 
1789
        if (tsx->transport_flag & TSX_HAS_PENDING_SEND) {
 
1790
            tsx->transport_flag &= ~(TSX_HAS_PENDING_SEND);
 
1791
            tsx_send_msg(tsx, tsx->last_tx);
 
1792
        }
 
1793
 
 
1794
        /* Need to reschedule retransmission? */
 
1795
        if (tsx->transport_flag & TSX_HAS_PENDING_RESCHED) {
 
1796
            tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
 
1797
 
 
1798
            /* Only update when transport turns out to be unreliable. */
 
1799
            if (!tsx->is_reliable) {
 
1800
                tsx_resched_retransmission(tsx);
 
1801
            }
 
1802
        }
 
1803
 
 
1804
    } else {
 
1805
        /* Failed to send! */
 
1806
        pj_assert(sent != 0);
 
1807
 
 
1808
        /* If transaction is using the same transport as the failed one,
 
1809
         * release the transport.
 
1810
         */
 
1811
        if (send_state->cur_transport==tsx->transport)
 
1812
            tsx_update_transport(tsx, NULL);
 
1813
 
 
1814
        /* Also stop processing if transaction has been flagged with
 
1815
         * pending destroy (http://trac.pjsip.org/repos/ticket/906)
 
1816
         */
 
1817
        if ((!*cont) || (tsx->transport_flag & TSX_HAS_PENDING_DESTROY)) {
 
1818
            char errmsg[PJ_ERR_MSG_SIZE];
 
1819
            pjsip_status_code sc;
 
1820
            pj_str_t err;
 
1821
 
 
1822
            tsx->transport_err = -sent;
 
1823
 
 
1824
            err =pj_strerror(-sent, errmsg, sizeof(errmsg));
 
1825
 
 
1826
            PJ_LOG(2,(tsx->obj_name,
 
1827
                      "Failed to send %s! err=%d (%s)",
 
1828
                      pjsip_tx_data_get_info(send_state->tdata), -sent,
 
1829
                      errmsg));
 
1830
 
 
1831
            /* Clear pending transport flag. */
 
1832
            tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);
 
1833
 
 
1834
            /* Mark that we have resolved the addresses. */
 
1835
            tsx->transport_flag |= TSX_HAS_RESOLVED_SERVER;
 
1836
 
 
1837
            /* Server resolution error is now mapped to 502 instead of 503,
 
1838
             * since with 503 normally client should try again.
 
1839
             * See http://trac.pjsip.org/repos/ticket/870
 
1840
             */
 
1841
            if (-sent==PJ_ERESOLVE || -sent==PJLIB_UTIL_EDNS_NXDOMAIN)
 
1842
                sc = PJSIP_SC_BAD_GATEWAY;
 
1843
            else
 
1844
                sc = PJSIP_SC_TSX_TRANSPORT_ERROR;
 
1845
 
 
1846
            /* Terminate transaction, if it's not already terminated. */
 
1847
            tsx_set_status_code(tsx, sc, &err);
 
1848
            if (tsx->state != PJSIP_TSX_STATE_TERMINATED &&
 
1849
                tsx->state != PJSIP_TSX_STATE_DESTROYED)
 
1850
            {
 
1851
                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
1852
                               PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata);
 
1853
            }
 
1854
            /* Don't forget to destroy if we have pending destroy flag
 
1855
             * (http://trac.pjsip.org/repos/ticket/906)
 
1856
             */
 
1857
            else if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY)
 
1858
            {
 
1859
                tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED,
 
1860
                               PJSIP_EVENT_TRANSPORT_ERROR, send_state->tdata);
 
1861
            }
 
1862
 
 
1863
        } else {
 
1864
            char errmsg[PJ_ERR_MSG_SIZE];
 
1865
 
 
1866
            PJ_LOG(2,(tsx->obj_name,
 
1867
                      "Temporary failure in sending %s, "
 
1868
                      "will try next server. Err=%d (%s)",
 
1869
                      pjsip_tx_data_get_info(send_state->tdata), -sent,
 
1870
                      pj_strerror(-sent, errmsg, sizeof(errmsg)).ptr));
 
1871
 
 
1872
            /* Reset retransmission count */
 
1873
            tsx->retransmit_count = 0;
 
1874
 
 
1875
            /* And reset timeout timer */
 
1876
            if (tsx->timeout_timer.id) {
 
1877
                lock_timer(tsx);
 
1878
 
 
1879
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
 
1880
                tsx->timeout_timer.id = TIMER_INACTIVE;
 
1881
 
 
1882
                tsx->timeout_timer.id = TIMER_ACTIVE;
 
1883
                pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
 
1884
                                            &timeout_timer_val);
 
1885
 
 
1886
                unlock_timer(tsx);
 
1887
            }
 
1888
 
 
1889
            /* Put again pending tdata */
 
1890
            tdata->mod_data[mod_tsx_layer.mod.id] = tsx;
 
1891
            tsx->pending_tx = tdata;
 
1892
        }
 
1893
    }
 
1894
 
 
1895
    unlock_tsx(tsx, &lck);
 
1896
}
 
1897
 
 
1898
 
 
1899
/* Transport callback. */
 
1900
static void transport_callback(void *token, pjsip_tx_data *tdata,
 
1901
                               pj_ssize_t sent)
 
1902
{
 
1903
    if (sent < 0) {
 
1904
        pjsip_transaction *tsx = (pjsip_transaction*) token;
 
1905
        struct tsx_lock_data lck;
 
1906
        char errmsg[PJ_ERR_MSG_SIZE];
 
1907
        pj_str_t err;
 
1908
 
 
1909
        tsx->transport_err = -sent;
 
1910
 
 
1911
        err = pj_strerror(-sent, errmsg, sizeof(errmsg));
 
1912
 
 
1913
        PJ_LOG(2,(tsx->obj_name, "Transport failed to send %s! Err=%d (%s)",
 
1914
                  pjsip_tx_data_get_info(tdata), -sent, errmsg));
 
1915
 
 
1916
        lock_tsx(tsx, &lck);
 
1917
 
 
1918
        /* Release transport. */
 
1919
        tsx_update_transport(tsx, NULL);
 
1920
 
 
1921
        /* Terminate transaction. */
 
1922
        tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);
 
1923
        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
1924
                       PJSIP_EVENT_TRANSPORT_ERROR, tdata );
 
1925
 
 
1926
        unlock_tsx(tsx, &lck);
 
1927
   }
 
1928
}
 
1929
 
 
1930
 
 
1931
/*
 
1932
 * Callback when transport state changes.
 
1933
 */
 
1934
static void tsx_tp_state_callback( pjsip_transport *tp,
 
1935
                                   pjsip_transport_state state,
 
1936
                                   const pjsip_transport_state_info *info)
 
1937
{
 
1938
    PJ_UNUSED_ARG(tp);
 
1939
 
 
1940
    if (state == PJSIP_TP_STATE_DISCONNECTED) {
 
1941
        pjsip_transaction *tsx;
 
1942
        struct tsx_lock_data lck;
 
1943
 
 
1944
        pj_assert(tp && info && info->user_data);
 
1945
 
 
1946
        tsx = (pjsip_transaction*)info->user_data;
 
1947
 
 
1948
        lock_tsx(tsx, &lck);
 
1949
 
 
1950
        /* Terminate transaction when transport disconnected */
 
1951
        if (tsx->state < PJSIP_TSX_STATE_TERMINATED) {
 
1952
            pj_str_t err;
 
1953
            char errmsg[PJ_ERR_MSG_SIZE];
 
1954
 
 
1955
            err = pj_strerror(info->status, errmsg, sizeof(errmsg));
 
1956
            tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);
 
1957
            tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
1958
                           PJSIP_EVENT_TRANSPORT_ERROR, NULL);
 
1959
        }
 
1960
 
 
1961
        unlock_tsx(tsx, &lck);
 
1962
    }
 
1963
}
 
1964
 
 
1965
 
 
1966
/*
 
1967
 * Send message to the transport.
 
1968
 */
 
1969
static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
 
1970
                                 pjsip_tx_data *tdata)
 
1971
{
 
1972
    pj_status_t status = PJ_SUCCESS;
 
1973
 
 
1974
    PJ_ASSERT_RETURN(tsx && tdata, PJ_EINVAL);
 
1975
 
 
1976
    /* Send later if transport is still pending. */
 
1977
    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
1978
        tsx->transport_flag |= TSX_HAS_PENDING_SEND;
 
1979
        return PJ_SUCCESS;
 
1980
    }
 
1981
 
 
1982
    /* If we have the transport, send the message using that transport.
 
1983
     * Otherwise perform full transport resolution.
 
1984
     */
 
1985
    if (tsx->transport) {
 
1986
        status = pjsip_transport_send( tsx->transport, tdata, &tsx->addr,
 
1987
                                       tsx->addr_len, tsx,
 
1988
                                       &transport_callback);
 
1989
        if (status == PJ_EPENDING)
 
1990
            status = PJ_SUCCESS;
 
1991
 
 
1992
        if (status != PJ_SUCCESS) {
 
1993
            char errmsg[PJ_ERR_MSG_SIZE];
 
1994
 
 
1995
            PJ_LOG(2,(tsx->obj_name,
 
1996
                      "Error sending %s: Err=%d (%s)",
 
1997
                      pjsip_tx_data_get_info(tdata), status,
 
1998
                      pj_strerror(status, errmsg, sizeof(errmsg)).ptr));
 
1999
 
 
2000
            /* On error, release transport to force using full transport
 
2001
             * resolution procedure.
 
2002
             */
 
2003
            tsx_update_transport(tsx, NULL);
 
2004
 
 
2005
            tsx->addr_len = 0;
 
2006
            tsx->res_addr.transport = NULL;
 
2007
            tsx->res_addr.addr_len = 0;
 
2008
        } else {
 
2009
            return PJ_SUCCESS;
 
2010
        }
 
2011
    }
 
2012
 
 
2013
    /* We are here because we don't have transport, or we failed to send
 
2014
     * the message using existing transport. If we haven't resolved the
 
2015
     * server before, then begin the long process of resolving the server
 
2016
     * and send the message with possibly new server.
 
2017
     */
 
2018
    pj_assert(status != PJ_SUCCESS || tsx->transport == NULL);
 
2019
 
 
2020
    /* If we have resolved the server, we treat the error as permanent error.
 
2021
     * Terminate transaction with transport error failure.
 
2022
     */
 
2023
    if (tsx->transport_flag & TSX_HAS_RESOLVED_SERVER) {
 
2024
 
 
2025
        char errmsg[PJ_ERR_MSG_SIZE];
 
2026
        pj_str_t err;
 
2027
 
 
2028
        if (status == PJ_SUCCESS) {
 
2029
            pj_assert(!"Unexpected status!");
 
2030
            status = PJ_EUNKNOWN;
 
2031
        }
 
2032
 
 
2033
        /* We have resolved the server!.
 
2034
         * Treat this as permanent transport error.
 
2035
         */
 
2036
        err = pj_strerror(status, errmsg, sizeof(errmsg));
 
2037
 
 
2038
        PJ_LOG(2,(tsx->obj_name,
 
2039
                  "Transport error, terminating transaction. "
 
2040
                  "Err=%d (%s)",
 
2041
                  status, errmsg));
 
2042
 
 
2043
        tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);
 
2044
        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
2045
                       PJSIP_EVENT_TRANSPORT_ERROR, NULL );
 
2046
 
 
2047
        return status;
 
2048
    }
 
2049
 
 
2050
    /* Must add reference counter because the send request functions
 
2051
     * decrement the reference counter.
 
2052
     */
 
2053
    pjsip_tx_data_add_ref(tdata);
 
2054
 
 
2055
    /* Also attach ourselves to the transmit data so that we'll be able
 
2056
     * to unregister ourselves from the send notification of this
 
2057
     * transmit data.
 
2058
     */
 
2059
    tdata->mod_data[mod_tsx_layer.mod.id] = tsx;
 
2060
    tsx->pending_tx = tdata;
 
2061
 
 
2062
    /* Begin resolving destination etc to send the message. */
 
2063
    if (tdata->msg->type == PJSIP_REQUEST_MSG) {
 
2064
 
 
2065
        tsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT;
 
2066
        status = pjsip_endpt_send_request_stateless(tsx->endpt, tdata, tsx,
 
2067
                                                    &send_msg_callback);
 
2068
        if (status == PJ_EPENDING)
 
2069
            status = PJ_SUCCESS;
 
2070
        if (status != PJ_SUCCESS) {
 
2071
            pjsip_tx_data_dec_ref(tdata);
 
2072
            tdata->mod_data[mod_tsx_layer.mod.id] = NULL;
 
2073
            tsx->pending_tx = NULL;
 
2074
        }
 
2075
 
 
2076
        /* Check if transaction is terminated. */
 
2077
        if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TERMINATED)
 
2078
            status = tsx->transport_err;
 
2079
 
 
2080
    } else {
 
2081
 
 
2082
        tsx->transport_flag |= TSX_HAS_PENDING_TRANSPORT;
 
2083
        status = pjsip_endpt_send_response( tsx->endpt, &tsx->res_addr,
 
2084
                                            tdata, tsx,
 
2085
                                            &send_msg_callback);
 
2086
        if (status == PJ_EPENDING)
 
2087
            status = PJ_SUCCESS;
 
2088
        if (status != PJ_SUCCESS) {
 
2089
            pjsip_tx_data_dec_ref(tdata);
 
2090
            tdata->mod_data[mod_tsx_layer.mod.id] = NULL;
 
2091
            tsx->pending_tx = NULL;
 
2092
        }
 
2093
 
 
2094
        /* Check if transaction is terminated. */
 
2095
        if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TERMINATED)
 
2096
            status = tsx->transport_err;
 
2097
 
 
2098
    }
 
2099
 
 
2100
 
 
2101
    return status;
 
2102
}
 
2103
 
 
2104
 
 
2105
/*
 
2106
 * Manually retransmit the last messagewithout updating the transaction state.
 
2107
 */
 
2108
PJ_DEF(pj_status_t) pjsip_tsx_retransmit_no_state(pjsip_transaction *tsx,
 
2109
                                                  pjsip_tx_data *tdata)
 
2110
{
 
2111
    struct tsx_lock_data lck;
 
2112
    pj_status_t status;
 
2113
 
 
2114
    lock_tsx(tsx, &lck);
 
2115
    if (tdata == NULL) {
 
2116
        tdata = tsx->last_tx;
 
2117
    }
 
2118
    status = tsx_send_msg(tsx, tdata);
 
2119
    unlock_tsx(tsx, &lck);
 
2120
 
 
2121
    /* Only decrement reference counter when it returns success.
 
2122
     * (This is the specification from the .PDF design document).
 
2123
     */
 
2124
    if (status == PJ_SUCCESS) {
 
2125
        pjsip_tx_data_dec_ref(tdata);
 
2126
    }
 
2127
 
 
2128
    return status;
 
2129
}
 
2130
 
 
2131
 
 
2132
/*
 
2133
 * Retransmit last message sent.
 
2134
 */
 
2135
static void tsx_resched_retransmission( pjsip_transaction *tsx )
 
2136
{
 
2137
    pj_uint32_t msec_time;
 
2138
 
 
2139
    pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0);
 
2140
 
 
2141
    if (tsx->role==PJSIP_ROLE_UAC && tsx->status_code >= 100)
 
2142
        msec_time = pjsip_cfg()->tsx.t2;
 
2143
    else
 
2144
        msec_time = (1 << (tsx->retransmit_count)) * pjsip_cfg()->tsx.t1;
 
2145
 
 
2146
    if (tsx->role == PJSIP_ROLE_UAC) {
 
2147
        pj_assert(tsx->status_code < 200);
 
2148
        /* Retransmission for non-INVITE transaction caps-off at T2 */
 
2149
        if (msec_time > pjsip_cfg()->tsx.t2 &&
 
2150
            tsx->method.id != PJSIP_INVITE_METHOD)
 
2151
        {
 
2152
            msec_time = pjsip_cfg()->tsx.t2;
 
2153
        }
 
2154
    } else {
 
2155
        /* For UAS, this can be retransmission of 2xx response for INVITE
 
2156
         * or non-100 1xx response.
 
2157
         */
 
2158
        if (tsx->status_code < 200) {
 
2159
            /* non-100 1xx retransmission is at 60 seconds */
 
2160
            msec_time = PJSIP_TSX_1XX_RETRANS_DELAY * 1000;
 
2161
        } else {
 
2162
            /* Retransmission of INVITE final response also caps-off at T2 */
 
2163
            pj_assert(tsx->status_code >= 200);
 
2164
            if (msec_time > pjsip_cfg()->tsx.t2)
 
2165
                msec_time = pjsip_cfg()->tsx.t2;
 
2166
        }
 
2167
    }
 
2168
 
 
2169
    if (msec_time != 0) {
 
2170
        pj_time_val timeout;
 
2171
 
 
2172
        timeout.sec = msec_time / 1000;
 
2173
        timeout.msec = msec_time % 1000;
 
2174
        tsx->retransmit_timer.id = TIMER_ACTIVE;
 
2175
        pjsip_endpt_schedule_timer( tsx->endpt, &tsx->retransmit_timer,
 
2176
                                    &timeout);
 
2177
    }
 
2178
}
 
2179
 
 
2180
/*
 
2181
 * Retransmit last message sent.
 
2182
 */
 
2183
static pj_status_t tsx_retransmit( pjsip_transaction *tsx, int resched)
 
2184
{
 
2185
    pj_status_t status;
 
2186
 
 
2187
    PJ_ASSERT_RETURN(tsx->last_tx!=NULL, PJ_EBUG);
 
2188
 
 
2189
    PJ_LOG(5,(tsx->obj_name, "Retransmiting %s, count=%d, restart?=%d",
 
2190
              pjsip_tx_data_get_info(tsx->last_tx),
 
2191
              tsx->retransmit_count, resched));
 
2192
 
 
2193
    ++tsx->retransmit_count;
 
2194
 
 
2195
    /* Restart timer T1 first before sending the message to ensure that
 
2196
     * retransmission timer is not engaged when loop transport is used.
 
2197
     */
 
2198
    if (resched) {
 
2199
        pj_assert(tsx->state != PJSIP_TSX_STATE_CONFIRMED);
 
2200
        if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
2201
            tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;
 
2202
        } else {
 
2203
            tsx_resched_retransmission(tsx);
 
2204
        }
 
2205
    }
 
2206
 
 
2207
    status = tsx_send_msg( tsx, tsx->last_tx);
 
2208
    if (status != PJ_SUCCESS) {
 
2209
        return status;
 
2210
    }
 
2211
 
 
2212
    return PJ_SUCCESS;
 
2213
}
 
2214
 
 
2215
static void tsx_update_transport( pjsip_transaction *tsx,
 
2216
                                  pjsip_transport *tp)
 
2217
{
 
2218
    pj_assert(tsx);
 
2219
 
 
2220
    if (tsx->transport) {
 
2221
        pjsip_transport_remove_state_listener(tsx->transport,
 
2222
                                               tsx->tp_st_key, tsx);
 
2223
        pjsip_transport_dec_ref( tsx->transport );
 
2224
        tsx->transport = NULL;
 
2225
    }
 
2226
 
 
2227
    if (tp) {
 
2228
        tsx->transport = tp;
 
2229
        pjsip_transport_add_ref(tp);
 
2230
        pjsip_transport_add_state_listener(tp, &tsx_tp_state_callback, tsx,
 
2231
                                            &tsx->tp_st_key);
 
2232
    }
 
2233
}
 
2234
 
 
2235
 
 
2236
/*
 
2237
 * Handler for events in state Null.
 
2238
 */
 
2239
static pj_status_t tsx_on_state_null( pjsip_transaction *tsx,
 
2240
                                      pjsip_event *event )
 
2241
{
 
2242
    pj_status_t status;
 
2243
 
 
2244
    pj_assert(tsx->state == PJSIP_TSX_STATE_NULL);
 
2245
 
 
2246
    if (tsx->role == PJSIP_ROLE_UAS) {
 
2247
 
 
2248
        /* Set state to Trying. */
 
2249
        pj_assert(event->type == PJSIP_EVENT_RX_MSG &&
 
2250
                  event->body.rx_msg.rdata->msg_info.msg->type ==
 
2251
                    PJSIP_REQUEST_MSG);
 
2252
        tsx_set_state( tsx, PJSIP_TSX_STATE_TRYING, PJSIP_EVENT_RX_MSG,
 
2253
                       event->body.rx_msg.rdata);
 
2254
 
 
2255
    } else {
 
2256
        pjsip_tx_data *tdata;
 
2257
 
 
2258
        /* Must be transmit event.
 
2259
         * You may got this assertion when using loop transport with delay
 
2260
         * set to zero. That would cause on_rx_response() callback to be
 
2261
         * called before tsx_send_msg() has completed.
 
2262
         */
 
2263
        PJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG, PJ_EBUG);
 
2264
 
 
2265
        /* Get the txdata */
 
2266
        tdata = event->body.tx_msg.tdata;
 
2267
 
 
2268
        /* Save the message for retransmission. */
 
2269
        if (tsx->last_tx && tsx->last_tx != tdata) {
 
2270
            pjsip_tx_data_dec_ref(tsx->last_tx);
 
2271
            tsx->last_tx = NULL;
 
2272
        }
 
2273
        if (tsx->last_tx != tdata) {
 
2274
            tsx->last_tx = tdata;
 
2275
            pjsip_tx_data_add_ref(tdata);
 
2276
        }
 
2277
 
 
2278
        /* Send the message. */
 
2279
        status = tsx_send_msg( tsx, tdata);
 
2280
        if (status != PJ_SUCCESS) {
 
2281
            return status;
 
2282
        }
 
2283
 
 
2284
        /* Start Timer B (or called timer F for non-INVITE) for transaction
 
2285
         * timeout.
 
2286
         */
 
2287
        lock_timer(tsx);
 
2288
        tsx->timeout_timer.id = TIMER_ACTIVE;
 
2289
        pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
 
2290
                                    &timeout_timer_val);
 
2291
        unlock_timer(tsx);
 
2292
 
 
2293
        /* Start Timer A (or timer E) for retransmission only if unreliable
 
2294
         * transport is being used.
 
2295
         */
 
2296
        if (!tsx->is_reliable)  {
 
2297
            tsx->retransmit_count = 0;
 
2298
            if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
2299
                tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;
 
2300
            } else {
 
2301
                tsx->retransmit_timer.id = TIMER_ACTIVE;
 
2302
                pjsip_endpt_schedule_timer(tsx->endpt, &tsx->retransmit_timer,
 
2303
                                           &t1_timer_val);
 
2304
            }
 
2305
        }
 
2306
 
 
2307
        /* Move state. */
 
2308
        tsx_set_state( tsx, PJSIP_TSX_STATE_CALLING,
 
2309
                       PJSIP_EVENT_TX_MSG, tdata);
 
2310
    }
 
2311
 
 
2312
    return PJ_SUCCESS;
 
2313
}
 
2314
 
 
2315
 
 
2316
/*
 
2317
 * State Calling is for UAC after it sends request but before any responses
 
2318
 * is received.
 
2319
 */
 
2320
static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx,
 
2321
                                         pjsip_event *event )
 
2322
{
 
2323
    pj_assert(tsx->state == PJSIP_TSX_STATE_CALLING);
 
2324
    pj_assert(tsx->role == PJSIP_ROLE_UAC);
 
2325
 
 
2326
    if (event->type == PJSIP_EVENT_TIMER &&
 
2327
        event->body.timer.entry == &tsx->retransmit_timer)
 
2328
    {
 
2329
        pj_status_t status;
 
2330
 
 
2331
        /* Retransmit the request. */
 
2332
        status = tsx_retransmit( tsx, 1 );
 
2333
        if (status != PJ_SUCCESS) {
 
2334
            return status;
 
2335
        }
 
2336
 
 
2337
    } else if (event->type == PJSIP_EVENT_TIMER &&
 
2338
               event->body.timer.entry == &tsx->timeout_timer)
 
2339
    {
 
2340
 
 
2341
        /* Cancel retransmission timer. */
 
2342
        if (tsx->retransmit_timer.id != 0) {
 
2343
            pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
2344
            tsx->retransmit_timer.id = 0;
 
2345
        }
 
2346
        tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
 
2347
 
 
2348
        /* Set status code */
 
2349
        tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
 
2350
 
 
2351
        /* Inform TU. */
 
2352
        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
2353
                       PJSIP_EVENT_TIMER, &tsx->timeout_timer);
 
2354
 
 
2355
        /* Transaction is destroyed */
 
2356
        //return PJSIP_ETSXDESTROYED;
 
2357
 
 
2358
    } else if (event->type == PJSIP_EVENT_RX_MSG) {
 
2359
        pjsip_msg *msg;
 
2360
        int code;
 
2361
 
 
2362
        /* Get message instance */
 
2363
        msg = event->body.rx_msg.rdata->msg_info.msg;
 
2364
 
 
2365
        /* Better be a response message. */
 
2366
        if (msg->type != PJSIP_RESPONSE_MSG)
 
2367
            return PJSIP_ENOTRESPONSEMSG;
 
2368
 
 
2369
        code = msg->line.status.code;
 
2370
 
 
2371
        /* If the response is final, cancel both retransmission and timeout
 
2372
         * timer.
 
2373
         */
 
2374
        if (code >= 200) {
 
2375
            if (tsx->retransmit_timer.id != 0) {
 
2376
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
2377
                tsx->retransmit_timer.id = 0;
 
2378
            }
 
2379
 
 
2380
            if (tsx->timeout_timer.id != 0) {
 
2381
                lock_timer(tsx);
 
2382
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
 
2383
                tsx->timeout_timer.id = 0;
 
2384
                unlock_timer(tsx);
 
2385
            }
 
2386
 
 
2387
        } else {
 
2388
            /* Cancel retransmit timer (for non-INVITE transaction, the
 
2389
             * retransmit timer will be rescheduled at T2.
 
2390
             */
 
2391
            if (tsx->retransmit_timer.id != 0) {
 
2392
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
2393
                tsx->retransmit_timer.id = 0;
 
2394
            }
 
2395
 
 
2396
            /* For provisional response, only cancel retransmit when this
 
2397
             * is an INVITE transaction. For non-INVITE, section 17.1.2.1
 
2398
             * of RFC 3261 says that:
 
2399
             *  - retransmit timer is set to T2
 
2400
             *  - timeout timer F is not deleted.
 
2401
             */
 
2402
            if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2403
 
 
2404
                /* Cancel timeout timer */
 
2405
                lock_timer(tsx);
 
2406
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
 
2407
                unlock_timer(tsx);
 
2408
 
 
2409
            } else {
 
2410
                if (!tsx->is_reliable) {
 
2411
                    tsx->retransmit_timer.id = TIMER_ACTIVE;
 
2412
                    pjsip_endpt_schedule_timer(tsx->endpt,
 
2413
                                               &tsx->retransmit_timer,
 
2414
                                               &t2_timer_val);
 
2415
                }
 
2416
            }
 
2417
        }
 
2418
 
 
2419
        tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
 
2420
 
 
2421
 
 
2422
        /* Discard retransmission message if it is not INVITE.
 
2423
         * The INVITE tdata is needed in case we have to generate ACK for
 
2424
         * the final response.
 
2425
         */
 
2426
        /* Keep last_tx for authorization. */
 
2427
        //blp: always keep last_tx until transaction is destroyed
 
2428
        //code = msg->line.status.code;
 
2429
        //if (tsx->method.id != PJSIP_INVITE_METHOD && code!=401 && code!=407) {
 
2430
        //    pjsip_tx_data_dec_ref(tsx->last_tx);
 
2431
        //    tsx->last_tx = NULL;
 
2432
        //}
 
2433
 
 
2434
        /* Processing is similar to state Proceeding. */
 
2435
        tsx_on_state_proceeding_uac( tsx, event);
 
2436
 
 
2437
    } else {
 
2438
        pj_assert(!"Unexpected event");
 
2439
        return PJ_EBUG;
 
2440
    }
 
2441
 
 
2442
    return PJ_SUCCESS;
 
2443
}
 
2444
 
 
2445
 
 
2446
/*
 
2447
 * State Trying is for UAS after it received request but before any responses
 
2448
 * is sent.
 
2449
 * Note: this is different than RFC3261, which can use Trying state for
 
2450
 *       non-INVITE client transaction (bug in RFC?).
 
2451
 */
 
2452
static pj_status_t tsx_on_state_trying( pjsip_transaction *tsx,
 
2453
                                        pjsip_event *event)
 
2454
{
 
2455
    pj_status_t status;
 
2456
 
 
2457
    pj_assert(tsx->state == PJSIP_TSX_STATE_TRYING);
 
2458
 
 
2459
    /* This state is only for UAS */
 
2460
    pj_assert(tsx->role == PJSIP_ROLE_UAS);
 
2461
 
 
2462
    /* Better be transmission of response message.
 
2463
     * If we've got request retransmission, this means that the TU hasn't
 
2464
     * transmitted any responses within 500 ms, which is not allowed. If
 
2465
     * this happens, just ignore the event (we couldn't retransmit last
 
2466
     * response because we haven't sent any!).
 
2467
     */
 
2468
    if (event->type != PJSIP_EVENT_TX_MSG) {
 
2469
        return PJ_SUCCESS;
 
2470
    }
 
2471
 
 
2472
    /* The rest of the processing of the event is exactly the same as in
 
2473
     * "Proceeding" state.
 
2474
     */
 
2475
    status = tsx_on_state_proceeding_uas( tsx, event);
 
2476
 
 
2477
    /* Inform the TU of the state transision if state is still State_Trying */
 
2478
    if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TRYING) {
 
2479
 
 
2480
        tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING,
 
2481
                       PJSIP_EVENT_TX_MSG, event->body.tx_msg.tdata);
 
2482
 
 
2483
    }
 
2484
 
 
2485
    return status;
 
2486
}
 
2487
 
 
2488
 
 
2489
/*
 
2490
 * Handler for events in Proceeding for UAS
 
2491
 * This state happens after the TU sends provisional response.
 
2492
 */
 
2493
static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
 
2494
                                                pjsip_event *event)
 
2495
{
 
2496
    pj_assert(tsx->state == PJSIP_TSX_STATE_PROCEEDING ||
 
2497
              tsx->state == PJSIP_TSX_STATE_TRYING);
 
2498
 
 
2499
    /* This state is only for UAS. */
 
2500
    pj_assert(tsx->role == PJSIP_ROLE_UAS);
 
2501
 
 
2502
    /* Receive request retransmission. */
 
2503
    if (event->type == PJSIP_EVENT_RX_MSG) {
 
2504
 
 
2505
        pj_status_t status;
 
2506
 
 
2507
        /* Must have last response sent. */
 
2508
        PJ_ASSERT_RETURN(tsx->last_tx != NULL, PJ_EBUG);
 
2509
 
 
2510
        /* Send last response */
 
2511
        if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
2512
            tsx->transport_flag |= TSX_HAS_PENDING_SEND;
 
2513
        } else {
 
2514
            status = tsx_send_msg(tsx, tsx->last_tx);
 
2515
            if (status != PJ_SUCCESS)
 
2516
                return status;
 
2517
        }
 
2518
 
 
2519
    } else if (event->type == PJSIP_EVENT_TX_MSG ) {
 
2520
        pjsip_tx_data *tdata = event->body.tx_msg.tdata;
 
2521
        pj_status_t status;
 
2522
 
 
2523
        /* The TU sends response message to the request. Save this message so
 
2524
         * that we can retransmit the last response in case we receive request
 
2525
         * retransmission.
 
2526
         */
 
2527
        pjsip_msg *msg = tdata->msg;
 
2528
 
 
2529
        /* This can only be a response message. */
 
2530
        PJ_ASSERT_RETURN(msg->type==PJSIP_RESPONSE_MSG, PJSIP_ENOTRESPONSEMSG);
 
2531
 
 
2532
        /* Update last status */
 
2533
        tsx_set_status_code(tsx, msg->line.status.code,
 
2534
                            &msg->line.status.reason);
 
2535
 
 
2536
        /* Discard the saved last response (it will be updated later as
 
2537
         * necessary).
 
2538
         */
 
2539
        if (tsx->last_tx && tsx->last_tx != tdata) {
 
2540
            pjsip_tx_data_dec_ref( tsx->last_tx );
 
2541
            tsx->last_tx = NULL;
 
2542
        }
 
2543
 
 
2544
        /* Send the message. */
 
2545
        status = tsx_send_msg(tsx, tdata);
 
2546
        if (status != PJ_SUCCESS) {
 
2547
            return status;
 
2548
        }
 
2549
 
 
2550
        // Update To tag header for RFC2543 transaction.
 
2551
        // TODO:
 
2552
 
 
2553
        /* Update transaction state */
 
2554
        if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 100)) {
 
2555
 
 
2556
            if (tsx->last_tx != tdata) {
 
2557
                tsx->last_tx = tdata;
 
2558
                pjsip_tx_data_add_ref( tdata );
 
2559
            }
 
2560
 
 
2561
            tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING,
 
2562
                           PJSIP_EVENT_TX_MSG, tdata );
 
2563
 
 
2564
            /* Retransmit provisional response every 1 minute if this is
 
2565
             * an INVITE provisional response greater than 100.
 
2566
             */
 
2567
            if (PJSIP_TSX_1XX_RETRANS_DELAY > 0 &&
 
2568
                tsx->method.id==PJSIP_INVITE_METHOD && tsx->status_code>100)
 
2569
            {
 
2570
 
 
2571
                /* Stop 1xx retransmission timer, if any */
 
2572
                if (tsx->retransmit_timer.id) {
 
2573
                    pjsip_endpt_cancel_timer(tsx->endpt,
 
2574
                                             &tsx->retransmit_timer);
 
2575
                    tsx->retransmit_timer.id = 0;
 
2576
                }
 
2577
 
 
2578
                /* Schedule retransmission */
 
2579
                tsx->retransmit_count = 0;
 
2580
                if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
2581
                    tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;
 
2582
                } else {
 
2583
                    pj_time_val delay = {PJSIP_TSX_1XX_RETRANS_DELAY, 0};
 
2584
 
 
2585
                    tsx->retransmit_timer.id = TIMER_ACTIVE;
 
2586
                    pjsip_endpt_schedule_timer( tsx->endpt,
 
2587
                                                &tsx->retransmit_timer,
 
2588
                                                &delay);
 
2589
                }
 
2590
            }
 
2591
 
 
2592
        } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 200)) {
 
2593
 
 
2594
            /* Stop 1xx retransmission timer, if any */
 
2595
            if (tsx->retransmit_timer.id) {
 
2596
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
2597
                tsx->retransmit_timer.id = 0;
 
2598
            }
 
2599
 
 
2600
            if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->handle_200resp==0) {
 
2601
 
 
2602
                /* 2xx class message is not saved, because retransmission
 
2603
                 * is handled by TU.
 
2604
                 */
 
2605
                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
2606
                               PJSIP_EVENT_TX_MSG, tdata );
 
2607
 
 
2608
                /* Transaction is destroyed. */
 
2609
                //return PJSIP_ETSXDESTROYED;
 
2610
 
 
2611
            } else {
 
2612
                pj_time_val timeout;
 
2613
 
 
2614
                if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2615
                    tsx->retransmit_count = 0;
 
2616
                    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
2617
                        tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;
 
2618
                    } else {
 
2619
                        tsx->retransmit_timer.id = TIMER_ACTIVE;
 
2620
                        pjsip_endpt_schedule_timer( tsx->endpt,
 
2621
                                                    &tsx->retransmit_timer,
 
2622
                                                    &t1_timer_val);
 
2623
                    }
 
2624
                }
 
2625
 
 
2626
                /* Save last response sent for retransmission when request
 
2627
                 * retransmission is received.
 
2628
                 */
 
2629
                if (tsx->last_tx != tdata) {
 
2630
                    tsx->last_tx = tdata;
 
2631
                    pjsip_tx_data_add_ref(tdata);
 
2632
                }
 
2633
 
 
2634
                /* Setup timeout timer: */
 
2635
 
 
2636
                if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2637
 
 
2638
                    /* Start Timer H at 64*T1 for INVITE server transaction,
 
2639
                     * regardless of transport.
 
2640
                     */
 
2641
                    timeout = timeout_timer_val;
 
2642
 
 
2643
                } else if (!tsx->is_reliable) {
 
2644
 
 
2645
                    /* For non-INVITE, start timer J at 64*T1 for unreliable
 
2646
                     * transport.
 
2647
                     */
 
2648
                    timeout = timeout_timer_val;
 
2649
 
 
2650
                } else {
 
2651
 
 
2652
                    /* Transaction terminates immediately for non-INVITE when
 
2653
                     * reliable transport is used.
 
2654
                     */
 
2655
                    timeout.sec = timeout.msec = 0;
 
2656
                }
 
2657
 
 
2658
                lock_timer(tsx);
 
2659
                tsx->timeout_timer.id = TIMER_ACTIVE;
 
2660
                pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
 
2661
                                            &timeout);
 
2662
                unlock_timer(tsx);
 
2663
 
 
2664
                /* Set state to "Completed" */
 
2665
                tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,
 
2666
                               PJSIP_EVENT_TX_MSG, tdata );
 
2667
            }
 
2668
 
 
2669
        } else if (tsx->status_code >= 300) {
 
2670
 
 
2671
            /* Stop 1xx retransmission timer, if any */
 
2672
            if (tsx->retransmit_timer.id) {
 
2673
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
2674
                tsx->retransmit_timer.id = 0;
 
2675
            }
 
2676
 
 
2677
            /* 3xx-6xx class message causes transaction to move to
 
2678
             * "Completed" state.
 
2679
             */
 
2680
            if (tsx->last_tx != tdata) {
 
2681
                tsx->last_tx = tdata;
 
2682
                pjsip_tx_data_add_ref( tdata );
 
2683
            }
 
2684
 
 
2685
            /* For INVITE, start timer H for transaction termination
 
2686
             * regardless whether transport is reliable or not.
 
2687
             * For non-INVITE, start timer J with the value of 64*T1 for
 
2688
             * non-reliable transports, and zero for reliable transports.
 
2689
             */
 
2690
            lock_timer(tsx);
 
2691
            if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2692
                /* Start timer H for INVITE */
 
2693
                tsx->timeout_timer.id = TIMER_ACTIVE;
 
2694
                pjsip_endpt_schedule_timer(tsx->endpt,&tsx->timeout_timer,
 
2695
                                           &timeout_timer_val);
 
2696
            } else if (!tsx->is_reliable) {
 
2697
                /* Start timer J on 64*T1 seconds for non-INVITE */
 
2698
                tsx->timeout_timer.id = TIMER_ACTIVE;
 
2699
                pjsip_endpt_schedule_timer(tsx->endpt,&tsx->timeout_timer,
 
2700
                                           &timeout_timer_val);
 
2701
            } else {
 
2702
                /* Start timer J on zero seconds for non-INVITE */
 
2703
                pj_time_val zero_time = { 0, 0 };
 
2704
                tsx->timeout_timer.id = TIMER_ACTIVE;
 
2705
                pjsip_endpt_schedule_timer(tsx->endpt,&tsx->timeout_timer,
 
2706
                                           &zero_time);
 
2707
            }
 
2708
            unlock_timer(tsx);
 
2709
 
 
2710
            /* For INVITE, if unreliable transport is used, retransmission
 
2711
             * timer G will be scheduled (retransmission).
 
2712
             */
 
2713
            if (!tsx->is_reliable) {
 
2714
                pjsip_cseq_hdr *cseq = (pjsip_cseq_hdr*)
 
2715
                                       pjsip_msg_find_hdr( msg, PJSIP_H_CSEQ,
 
2716
                                                           NULL);
 
2717
                if (cseq->method.id == PJSIP_INVITE_METHOD) {
 
2718
                    tsx->retransmit_count = 0;
 
2719
                    if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
 
2720
                        tsx->transport_flag |= TSX_HAS_PENDING_RESCHED;
 
2721
                    } else {
 
2722
                        tsx->retransmit_timer.id = TIMER_ACTIVE;
 
2723
                        pjsip_endpt_schedule_timer(tsx->endpt,
 
2724
                                                   &tsx->retransmit_timer,
 
2725
                                                   &t1_timer_val);
 
2726
                    }
 
2727
                }
 
2728
            }
 
2729
 
 
2730
            /* Inform TU */
 
2731
            tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,
 
2732
                           PJSIP_EVENT_TX_MSG, tdata );
 
2733
 
 
2734
        } else {
 
2735
            pj_assert(0);
 
2736
        }
 
2737
 
 
2738
 
 
2739
    } else if (event->type == PJSIP_EVENT_TIMER &&
 
2740
               event->body.timer.entry == &tsx->retransmit_timer) {
 
2741
 
 
2742
        /* Retransmission timer elapsed. */
 
2743
        pj_status_t status;
 
2744
 
 
2745
        /* Must not be triggered while transport is pending. */
 
2746
        pj_assert((tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) == 0);
 
2747
 
 
2748
        /* Must have last response to retransmit. */
 
2749
        pj_assert(tsx->last_tx != NULL);
 
2750
 
 
2751
        /* Retransmit the last response. */
 
2752
        status = tsx_retransmit( tsx, 1 );
 
2753
        if (status != PJ_SUCCESS) {
 
2754
            return status;
 
2755
        }
 
2756
 
 
2757
    } else if (event->type == PJSIP_EVENT_TIMER &&
 
2758
               event->body.timer.entry == &tsx->timeout_timer) {
 
2759
 
 
2760
        /* Timeout timer. should not happen? */
 
2761
        pj_assert(!"Should not happen(?)");
 
2762
 
 
2763
        tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
 
2764
 
 
2765
        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
2766
                       PJSIP_EVENT_TIMER, &tsx->timeout_timer);
 
2767
 
 
2768
        return PJ_EBUG;
 
2769
 
 
2770
    } else {
 
2771
        pj_assert(!"Unexpected event");
 
2772
        return PJ_EBUG;
 
2773
    }
 
2774
 
 
2775
    return PJ_SUCCESS;
 
2776
}
 
2777
 
 
2778
 
 
2779
/*
 
2780
 * Handler for events in Proceeding for UAC
 
2781
 * This state happens after provisional response(s) has been received from
 
2782
 * UAS.
 
2783
 */
 
2784
static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx,
 
2785
                                               pjsip_event *event)
 
2786
{
 
2787
 
 
2788
    pj_assert(tsx->state == PJSIP_TSX_STATE_PROCEEDING ||
 
2789
              tsx->state == PJSIP_TSX_STATE_CALLING);
 
2790
 
 
2791
    if (event->type != PJSIP_EVENT_TIMER) {
 
2792
        pjsip_msg *msg;
 
2793
 
 
2794
        /* Must be incoming response, because we should not retransmit
 
2795
         * request once response has been received.
 
2796
         */
 
2797
        pj_assert(event->type == PJSIP_EVENT_RX_MSG);
 
2798
        if (event->type != PJSIP_EVENT_RX_MSG) {
 
2799
            return PJ_EINVALIDOP;
 
2800
        }
 
2801
 
 
2802
        msg = event->body.rx_msg.rdata->msg_info.msg;
 
2803
 
 
2804
        /* Must be a response message. */
 
2805
        if (msg->type != PJSIP_RESPONSE_MSG) {
 
2806
            pj_assert(!"Expecting response message!");
 
2807
            return PJSIP_ENOTRESPONSEMSG;
 
2808
        }
 
2809
 
 
2810
        tsx_set_status_code(tsx, msg->line.status.code,
 
2811
                            &msg->line.status.reason);
 
2812
 
 
2813
    } else {
 
2814
        if (event->body.timer.entry == &tsx->retransmit_timer) {
 
2815
            /* Retransmit message. */
 
2816
            pj_status_t status;
 
2817
 
 
2818
            status = tsx_retransmit( tsx, 1 );
 
2819
 
 
2820
            return status;
 
2821
 
 
2822
        } else {
 
2823
            tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
 
2824
        }
 
2825
    }
 
2826
 
 
2827
    if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 100)) {
 
2828
 
 
2829
        /* Inform the message to TU. */
 
2830
        tsx_set_state( tsx, PJSIP_TSX_STATE_PROCEEDING,
 
2831
                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 
2832
 
 
2833
    } else if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code,200)) {
 
2834
 
 
2835
        /* Stop timeout timer B/F. */
 
2836
        lock_timer(tsx);
 
2837
        pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer );
 
2838
        unlock_timer(tsx);
 
2839
 
 
2840
        /* For INVITE, the state moves to Terminated state (because ACK is
 
2841
         * handled in TU). For non-INVITE, state moves to Completed.
 
2842
         */
 
2843
        if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2844
            tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
2845
                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 
2846
            //return PJSIP_ETSXDESTROYED;
 
2847
 
 
2848
        } else {
 
2849
            pj_time_val timeout;
 
2850
 
 
2851
            /* For unreliable transport, start timer D (for INVITE) or
 
2852
             * timer K for non-INVITE. */
 
2853
            if (!tsx->is_reliable) {
 
2854
                if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2855
                    timeout = td_timer_val;
 
2856
                } else {
 
2857
                    timeout = t4_timer_val;
 
2858
                }
 
2859
            } else {
 
2860
                timeout.sec = timeout.msec = 0;
 
2861
            }
 
2862
            lock_timer(tsx);
 
2863
            tsx->timeout_timer.id = TIMER_ACTIVE;
 
2864
            pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
 
2865
                                        &timeout);
 
2866
            unlock_timer(tsx);
 
2867
 
 
2868
            /* Cancel retransmission timer */
 
2869
            if (tsx->retransmit_timer.id != 0) {
 
2870
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
2871
                tsx->retransmit_timer.id = 0;
 
2872
            }
 
2873
 
 
2874
            /* Move state to Completed, inform TU. */
 
2875
            tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,
 
2876
                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 
2877
        }
 
2878
 
 
2879
    } else if (event->type == PJSIP_EVENT_TIMER &&
 
2880
               event->body.timer.entry == &tsx->timeout_timer) {
 
2881
 
 
2882
        /* Inform TU. */
 
2883
        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
2884
                       PJSIP_EVENT_TIMER, &tsx->timeout_timer);
 
2885
 
 
2886
 
 
2887
    } else if (tsx->status_code >= 300 && tsx->status_code <= 699) {
 
2888
 
 
2889
 
 
2890
#if 0
 
2891
        /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 
2892
        /*
 
2893
         * This is the old code; it's broken for authentication.
 
2894
         */
 
2895
        pj_time_val timeout;
 
2896
        pj_status_t status;
 
2897
 
 
2898
        /* Stop timer B. */
 
2899
        pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer );
 
2900
 
 
2901
        /* Generate and send ACK for INVITE. */
 
2902
        if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2903
            pjsip_tx_data *ack;
 
2904
 
 
2905
            status = pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx,
 
2906
                                             event->body.rx_msg.rdata,
 
2907
                                             &ack);
 
2908
            if (status != PJ_SUCCESS)
 
2909
                return status;
 
2910
 
 
2911
            if (ack != tsx->last_tx) {
 
2912
                pjsip_tx_data_dec_ref(tsx->last_tx);
 
2913
                tsx->last_tx = ack;
 
2914
            }
 
2915
 
 
2916
            status = tsx_send_msg( tsx, tsx->last_tx);
 
2917
            if (status != PJ_SUCCESS) {
 
2918
                return status;
 
2919
            }
 
2920
        }
 
2921
 
 
2922
        /* Start Timer D with TD/T4 timer if unreliable transport is used. */
 
2923
        if (!tsx->is_reliable) {
 
2924
            if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2925
                timeout = td_timer_val;
 
2926
            } else {
 
2927
                timeout = t4_timer_val;
 
2928
            }
 
2929
        } else {
 
2930
            timeout.sec = timeout.msec = 0;
 
2931
        }
 
2932
        tsx->timeout->timer.id = TSX_TIMER_TIMEOUT;
 
2933
        pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout);
 
2934
 
 
2935
        /* Inform TU.
 
2936
         * blp: You might be tempted to move this notification before
 
2937
         *      sending ACK, but I think you shouldn't. Better set-up
 
2938
         *      everything before calling tsx_user's callback to avoid
 
2939
         *      mess up.
 
2940
         */
 
2941
        tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,
 
2942
                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 
2943
 
 
2944
        /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 
2945
#endif
 
2946
 
 
2947
        /* New code, taken from 0.2.9.x branch */
 
2948
        pj_time_val timeout;
 
2949
        pjsip_tx_data *ack_tdata = NULL;
 
2950
 
 
2951
        /* Cancel retransmission timer */
 
2952
        if (tsx->retransmit_timer.id != 0) {
 
2953
            pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
2954
            tsx->retransmit_timer.id = 0;
 
2955
        }
 
2956
 
 
2957
        /* Stop timer B. */
 
2958
        lock_timer(tsx);
 
2959
        tsx->timeout_timer.id = 0;
 
2960
        pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer );
 
2961
        unlock_timer(tsx);
 
2962
 
 
2963
        /* Generate and send ACK (for INVITE) */
 
2964
        if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2965
            pj_status_t status;
 
2966
 
 
2967
            status = pjsip_endpt_create_ack( tsx->endpt, tsx->last_tx,
 
2968
                                             event->body.rx_msg.rdata,
 
2969
                                             &ack_tdata);
 
2970
            if (status != PJ_SUCCESS)
 
2971
                return status;
 
2972
 
 
2973
            status = tsx_send_msg( tsx, ack_tdata);
 
2974
            if (status != PJ_SUCCESS)
 
2975
                return status;
 
2976
        }
 
2977
 
 
2978
        /* Inform TU. */
 
2979
        tsx_set_state( tsx, PJSIP_TSX_STATE_COMPLETED,
 
2980
                       PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata);
 
2981
 
 
2982
        /* Generate and send ACK for INVITE. */
 
2983
        if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
2984
            if (ack_tdata != tsx->last_tx) {
 
2985
                pjsip_tx_data_dec_ref(tsx->last_tx);
 
2986
                tsx->last_tx = ack_tdata;
 
2987
 
 
2988
                /* This is a bug.
 
2989
                   tsx_send_msg() does NOT decrement tdata's reference counter,
 
2990
                   so if we add the reference counter here, tdata will have
 
2991
                   reference counter 2, causing it to leak.
 
2992
                pjsip_tx_data_add_ref(ack_tdata);
 
2993
                */
 
2994
            }
 
2995
        }
 
2996
 
 
2997
        /* Start Timer D with TD/T4 timer if unreliable transport is used. */
 
2998
        /* Note: tsx->transport may be NULL! */
 
2999
        if (!tsx->is_reliable) {
 
3000
            if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
3001
                timeout = td_timer_val;
 
3002
            } else {
 
3003
                timeout = t4_timer_val;
 
3004
            }
 
3005
        } else {
 
3006
            timeout.sec = timeout.msec = 0;
 
3007
        }
 
3008
        lock_timer(tsx);
 
3009
        /* In the short period above timer may have been inserted
 
3010
         * by set_timeout() (by CANCEL). Cancel it if necessary. See:
 
3011
         *  https://trac.pjsip.org/repos/ticket/1374
 
3012
         */
 
3013
        if (tsx->timeout_timer.id)
 
3014
            pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer );
 
3015
        tsx->timeout_timer.id = TIMER_ACTIVE;
 
3016
        pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer, &timeout);
 
3017
        unlock_timer(tsx);
 
3018
 
 
3019
    } else {
 
3020
        // Shouldn't happen because there's no timer for this state.
 
3021
        pj_assert(!"Unexpected event");
 
3022
        return PJ_EBUG;
 
3023
    }
 
3024
 
 
3025
    return PJ_SUCCESS;
 
3026
}
 
3027
 
 
3028
 
 
3029
/*
 
3030
 * Handler for events in Completed state for UAS
 
3031
 */
 
3032
static pj_status_t tsx_on_state_completed_uas( pjsip_transaction *tsx,
 
3033
                                               pjsip_event *event)
 
3034
{
 
3035
    pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED);
 
3036
 
 
3037
    if (event->type == PJSIP_EVENT_RX_MSG) {
 
3038
        pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg;
 
3039
 
 
3040
        /* This must be a request message retransmission. */
 
3041
        if (msg->type != PJSIP_REQUEST_MSG)
 
3042
            return PJSIP_ENOTREQUESTMSG;
 
3043
 
 
3044
        /* On receive request retransmission, retransmit last response. */
 
3045
        if (msg->line.req.method.id != PJSIP_ACK_METHOD) {
 
3046
            pj_status_t status;
 
3047
 
 
3048
            status = tsx_retransmit( tsx, 0 );
 
3049
            if (status != PJ_SUCCESS) {
 
3050
                return status;
 
3051
            }
 
3052
 
 
3053
        } else {
 
3054
            pj_time_val timeout;
 
3055
 
 
3056
            /* Process incoming ACK request. */
 
3057
 
 
3058
            /* Verify that this is an INVITE transaction */
 
3059
            if (tsx->method.id != PJSIP_INVITE_METHOD) {
 
3060
                PJ_LOG(2, (tsx->obj_name,
 
3061
                           "Received illegal ACK for %.*s transaction",
 
3062
                           (int)tsx->method.name.slen,
 
3063
                           tsx->method.name.ptr));
 
3064
                return PJSIP_EINVALIDMETHOD;
 
3065
            }
 
3066
 
 
3067
            /* Cease retransmission. */
 
3068
            if (tsx->retransmit_timer.id != 0) {
 
3069
                pjsip_endpt_cancel_timer(tsx->endpt, &tsx->retransmit_timer);
 
3070
                tsx->retransmit_timer.id = 0;
 
3071
            }
 
3072
            tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
 
3073
 
 
3074
            /* Reschedule timeout timer. */
 
3075
            lock_timer(tsx);
 
3076
            pjsip_endpt_cancel_timer( tsx->endpt, &tsx->timeout_timer );
 
3077
            tsx->timeout_timer.id = TIMER_ACTIVE;
 
3078
 
 
3079
            /* Timer I is T4 timer for unreliable transports, and
 
3080
             * zero seconds for reliable transports.
 
3081
             */
 
3082
            if (!tsx->is_reliable) {
 
3083
                timeout.sec = 0;
 
3084
                timeout.msec = 0;
 
3085
            } else {
 
3086
                timeout.sec = t4_timer_val.sec;
 
3087
                timeout.msec = t4_timer_val.msec;
 
3088
            }
 
3089
            pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
 
3090
                                        &timeout);
 
3091
            unlock_timer(tsx);
 
3092
 
 
3093
            /* Move state to "Confirmed" */
 
3094
            tsx_set_state( tsx, PJSIP_TSX_STATE_CONFIRMED,
 
3095
                           PJSIP_EVENT_RX_MSG, event->body.rx_msg.rdata );
 
3096
        }
 
3097
 
 
3098
    } else if (event->type == PJSIP_EVENT_TIMER) {
 
3099
 
 
3100
        if (event->body.timer.entry == &tsx->retransmit_timer) {
 
3101
            /* Retransmit message. */
 
3102
            pj_status_t status;
 
3103
 
 
3104
            status = tsx_retransmit( tsx, 1 );
 
3105
            if (status != PJ_SUCCESS) {
 
3106
                return status;
 
3107
            }
 
3108
 
 
3109
        } else {
 
3110
            if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
3111
 
 
3112
                /* For INVITE, this means that ACK was never received.
 
3113
                 * Set state to Terminated, and inform TU.
 
3114
                 */
 
3115
 
 
3116
                tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
 
3117
 
 
3118
                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
3119
                               PJSIP_EVENT_TIMER, &tsx->timeout_timer );
 
3120
 
 
3121
                //return PJSIP_ETSXDESTROYED;
 
3122
 
 
3123
            } else {
 
3124
                /* Transaction terminated, it can now be deleted. */
 
3125
                tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
3126
                               PJSIP_EVENT_TIMER, &tsx->timeout_timer );
 
3127
                //return PJSIP_ETSXDESTROYED;
 
3128
            }
 
3129
        }
 
3130
 
 
3131
    } else {
 
3132
        /* Ignore request to transmit. */
 
3133
        PJ_ASSERT_RETURN(event->type == PJSIP_EVENT_TX_MSG &&
 
3134
                         event->body.tx_msg.tdata == tsx->last_tx,
 
3135
                         PJ_EINVALIDOP);
 
3136
    }
 
3137
 
 
3138
    return PJ_SUCCESS;
 
3139
}
 
3140
 
 
3141
 
 
3142
/*
 
3143
 * Handler for events in Completed state for UAC transaction.
 
3144
 */
 
3145
static pj_status_t tsx_on_state_completed_uac( pjsip_transaction *tsx,
 
3146
                                               pjsip_event *event)
 
3147
{
 
3148
    pj_assert(tsx->state == PJSIP_TSX_STATE_COMPLETED);
 
3149
 
 
3150
    if (event->type == PJSIP_EVENT_TIMER) {
 
3151
        /* Must be the timeout timer. */
 
3152
        pj_assert(event->body.timer.entry == &tsx->timeout_timer);
 
3153
 
 
3154
        /* Move to Terminated state. */
 
3155
        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
3156
                       PJSIP_EVENT_TIMER, event->body.timer.entry );
 
3157
 
 
3158
        /* Transaction has been destroyed. */
 
3159
        //return PJSIP_ETSXDESTROYED;
 
3160
 
 
3161
    } else if (event->type == PJSIP_EVENT_RX_MSG) {
 
3162
        if (tsx->method.id == PJSIP_INVITE_METHOD) {
 
3163
            /* On received of final response retransmission, retransmit the ACK.
 
3164
             * TU doesn't need to be informed.
 
3165
             */
 
3166
            pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg;
 
3167
            pj_assert(msg->type == PJSIP_RESPONSE_MSG);
 
3168
            if (msg->type==PJSIP_RESPONSE_MSG &&
 
3169
                msg->line.status.code >= 200)
 
3170
            {
 
3171
                pj_status_t status;
 
3172
 
 
3173
                status = tsx_retransmit( tsx, 0 );
 
3174
                if (status != PJ_SUCCESS) {
 
3175
                    return status;
 
3176
                }
 
3177
            } else {
 
3178
                /* Very late retransmission of privisional response. */
 
3179
                pj_assert( msg->type == PJSIP_RESPONSE_MSG );
 
3180
            }
 
3181
        } else {
 
3182
            /* Just drop the response. */
 
3183
        }
 
3184
 
 
3185
    } else {
 
3186
        pj_assert(!"Unexpected event");
 
3187
        return PJ_EINVALIDOP;
 
3188
    }
 
3189
 
 
3190
    return PJ_SUCCESS;
 
3191
}
 
3192
 
 
3193
 
 
3194
/*
 
3195
 * Handler for events in state Confirmed.
 
3196
 */
 
3197
static pj_status_t tsx_on_state_confirmed( pjsip_transaction *tsx,
 
3198
                                           pjsip_event *event)
 
3199
{
 
3200
    pj_assert(tsx->state == PJSIP_TSX_STATE_CONFIRMED);
 
3201
 
 
3202
    /* This state is only for UAS for INVITE. */
 
3203
    pj_assert(tsx->role == PJSIP_ROLE_UAS);
 
3204
    pj_assert(tsx->method.id == PJSIP_INVITE_METHOD);
 
3205
 
 
3206
    /* Absorb any ACK received. */
 
3207
    if (event->type == PJSIP_EVENT_RX_MSG) {
 
3208
 
 
3209
        pjsip_msg *msg = event->body.rx_msg.rdata->msg_info.msg;
 
3210
 
 
3211
        /* Only expecting request message. */
 
3212
        if (msg->type != PJSIP_REQUEST_MSG)
 
3213
            return PJSIP_ENOTREQUESTMSG;
 
3214
 
 
3215
        /* Must be an ACK request or a late INVITE retransmission. */
 
3216
        pj_assert(msg->line.req.method.id == PJSIP_ACK_METHOD ||
 
3217
                  msg->line.req.method.id == PJSIP_INVITE_METHOD);
 
3218
 
 
3219
    } else if (event->type == PJSIP_EVENT_TIMER) {
 
3220
        /* Must be from timeout_timer_. */
 
3221
        pj_assert(event->body.timer.entry == &tsx->timeout_timer);
 
3222
 
 
3223
        /* Move to Terminated state. */
 
3224
        tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
 
3225
                       PJSIP_EVENT_TIMER, &tsx->timeout_timer );
 
3226
 
 
3227
        /* Transaction has been destroyed. */
 
3228
        //return PJSIP_ETSXDESTROYED;
 
3229
 
 
3230
    } else {
 
3231
        pj_assert(!"Unexpected event");
 
3232
        return PJ_EBUG;
 
3233
    }
 
3234
 
 
3235
    return PJ_SUCCESS;
 
3236
}
 
3237
 
 
3238
 
 
3239
/*
 
3240
 * Handler for events in state Terminated.
 
3241
 */
 
3242
static pj_status_t tsx_on_state_terminated( pjsip_transaction *tsx,
 
3243
                                            pjsip_event *event)
 
3244
{
 
3245
    pj_assert(tsx->state == PJSIP_TSX_STATE_TERMINATED);
 
3246
 
 
3247
    /* Ignore events other than timer. This used to be an assertion but
 
3248
     * events may genuinely arrive at this state.
 
3249
     */
 
3250
    if (event->type != PJSIP_EVENT_TIMER) {
 
3251
        return PJ_EIGNORED;
 
3252
    }
 
3253
 
 
3254
    /* Destroy this transaction */
 
3255
    tsx_set_state(tsx, PJSIP_TSX_STATE_DESTROYED,
 
3256
                  event->type, event->body.user.user1 );
 
3257
 
 
3258
    return PJ_SUCCESS;
 
3259
}
 
3260
 
 
3261
 
 
3262
/*
 
3263
 * Handler for events in state Destroyed.
 
3264
 * Shouldn't happen!
 
3265
 */
 
3266
static pj_status_t tsx_on_state_destroyed(pjsip_transaction *tsx,
 
3267
                                          pjsip_event *event)
 
3268
{
 
3269
    PJ_UNUSED_ARG(tsx);
 
3270
    PJ_UNUSED_ARG(event);
 
3271
 
 
3272
    // See https://trac.pjsip.org/repos/ticket/1432
 
3273
    //pj_assert(!"Not expecting any events!!");
 
3274
 
 
3275
    return PJ_EIGNORED;
 
3276
}