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

« back to all changes in this revision

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

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

Show diffs side-by-side

added added

removed removed

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