~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: sip_transport.c 4094 2012-04-26 09:31:00Z bennylp $ */
2
 
/*
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
#include <pjsip/sip_transport.h>
21
 
#include <pjsip/sip_endpoint.h>
22
 
#include <pjsip/sip_parser.h>
23
 
#include <pjsip/sip_msg.h>
24
 
#include <pjsip/sip_private.h>
25
 
#include <pjsip/sip_errno.h>
26
 
#include <pjsip/sip_module.h>
27
 
#include <pj/except.h>
28
 
#include <pj/os.h>
29
 
#include <pj/log.h>
30
 
#include <pj/ioqueue.h>
31
 
#include <pj/hash.h>
32
 
#include <pj/string.h>
33
 
#include <pj/pool.h>
34
 
#include <pj/assert.h>
35
 
#include <pj/lock.h>
36
 
#include <pj/list.h>
37
 
 
38
 
 
39
 
#define THIS_FILE    "sip_transport.c"
40
 
 
41
 
#if 0
42
 
#   define TRACE_(x)    PJ_LOG(5,x)
43
 
 
44
 
static const char *addr_string(const pj_sockaddr_t *addr)
45
 
{
46
 
    static char str[PJ_INET6_ADDRSTRLEN];
47
 
    pj_inet_ntop(((const pj_sockaddr*)addr)->addr.sa_family,
48
 
                 pj_sockaddr_get_addr(addr),
49
 
                 str, sizeof(str));
50
 
    return str;
51
 
}
52
 
#else
53
 
#   define TRACE_(x)
54
 
#endif
55
 
 
56
 
/* Prototype. */
57
 
static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata);
58
 
 
59
 
/* This module has sole purpose to print transmit data to contigous buffer
60
 
 * before actually transmitted to the wire.
61
 
 */
62
 
static pjsip_module mod_msg_print =
63
 
{
64
 
    NULL, NULL,                         /* prev and next                    */
65
 
    { "mod-msg-print", 13},             /* Name.                            */
66
 
    -1,                                 /* Id                               */
67
 
    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER, /* Priority                         */
68
 
    NULL,                               /* load()                           */
69
 
    NULL,                               /* start()                          */
70
 
    NULL,                               /* stop()                           */
71
 
    NULL,                               /* unload()                         */
72
 
    NULL,                               /* on_rx_request()                  */
73
 
    NULL,                               /* on_rx_response()                 */
74
 
    &mod_on_tx_msg,                     /* on_tx_request()                  */
75
 
    &mod_on_tx_msg,                     /* on_tx_response()                 */
76
 
    NULL,                               /* on_tsx_state()                   */
77
 
};
78
 
 
79
 
/*
80
 
 * Transport manager.
81
 
 */
82
 
struct pjsip_tpmgr
83
 
{
84
 
    pj_hash_table_t *table;
85
 
    pj_lock_t       *lock;
86
 
    pjsip_endpoint  *endpt;
87
 
    pjsip_tpfactory  factory_list;
88
 
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
89
 
    pj_atomic_t     *tdata_counter;
90
 
#endif
91
 
    void           (*on_rx_msg)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*);
92
 
    pj_status_t    (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*);
93
 
    pjsip_tp_state_callback tp_state_cb;
94
 
};
95
 
 
96
 
 
97
 
/* Transport state listener list type */
98
 
typedef struct tp_state_listener
99
 
{
100
 
    PJ_DECL_LIST_MEMBER(struct tp_state_listener);
101
 
 
102
 
    pjsip_tp_state_callback  cb;
103
 
    void *user_data;
104
 
} tp_state_listener;
105
 
 
106
 
 
107
 
/*
108
 
 * Transport data.
109
 
 */
110
 
typedef struct transport_data
111
 
{
112
 
    /* Transport listeners */
113
 
    tp_state_listener       st_listeners;
114
 
    tp_state_listener       st_listeners_empty;
115
 
} transport_data;
116
 
 
117
 
 
118
 
/*****************************************************************************
119
 
 *
120
 
 * GENERAL TRANSPORT (NAMES, TYPES, ETC.)
121
 
 *
122
 
 *****************************************************************************/
123
 
 
124
 
/*
125
 
 * Transport names.
126
 
 */
127
 
struct transport_names_t
128
 
{
129
 
    pjsip_transport_type_e type;            /* Transport type       */
130
 
    pj_uint16_t            port;            /* Default port number  */
131
 
    pj_str_t               name;            /* Id tag               */
132
 
    const char            *description;     /* Longer description   */
133
 
    unsigned               flag;            /* Flags                */
134
 
    char                   name_buf[16];    /* For user's transport */
135
 
} transport_names[16] =
136
 
{
137
 
    {
138
 
        PJSIP_TRANSPORT_UNSPECIFIED,
139
 
        0,
140
 
        {"Unspecified", 11},
141
 
        "Unspecified",
142
 
        0
143
 
    },
144
 
    {
145
 
        PJSIP_TRANSPORT_UDP,
146
 
        5060,
147
 
        {"UDP", 3},
148
 
        "UDP transport",
149
 
        PJSIP_TRANSPORT_DATAGRAM
150
 
    },
151
 
    {
152
 
        PJSIP_TRANSPORT_TCP,
153
 
        5060,
154
 
        {"TCP", 3},
155
 
        "TCP transport",
156
 
        PJSIP_TRANSPORT_RELIABLE
157
 
    },
158
 
    {
159
 
        PJSIP_TRANSPORT_TLS,
160
 
        5061,
161
 
        {"TLS", 3},
162
 
        "TLS transport",
163
 
        PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE
164
 
    },
165
 
    {
166
 
        PJSIP_TRANSPORT_SCTP,
167
 
        5060,
168
 
        {"SCTP", 4},
169
 
        "SCTP transport",
170
 
        PJSIP_TRANSPORT_RELIABLE
171
 
    },
172
 
    {
173
 
        PJSIP_TRANSPORT_LOOP,
174
 
        15060,
175
 
        {"LOOP", 4},
176
 
        "Loopback transport",
177
 
        PJSIP_TRANSPORT_RELIABLE
178
 
    },
179
 
    {
180
 
        PJSIP_TRANSPORT_LOOP_DGRAM,
181
 
        15060,
182
 
        {"LOOP-DGRAM", 10},
183
 
        "Loopback datagram transport",
184
 
        PJSIP_TRANSPORT_DATAGRAM
185
 
    },
186
 
    {
187
 
        PJSIP_TRANSPORT_UDP6,
188
 
        5060,
189
 
        {"UDP", 3},
190
 
        "UDP IPv6 transport",
191
 
        PJSIP_TRANSPORT_DATAGRAM
192
 
    },
193
 
    {
194
 
        PJSIP_TRANSPORT_TCP6,
195
 
        5060,
196
 
        {"TCP", 3},
197
 
        "TCP IPv6 transport",
198
 
        PJSIP_TRANSPORT_RELIABLE
199
 
    },
200
 
};
201
 
 
202
 
static void tp_state_callback(pjsip_transport *tp,
203
 
                              pjsip_transport_state state,
204
 
                              const pjsip_transport_state_info *info);
205
 
 
206
 
 
207
 
struct transport_names_t *get_tpname(pjsip_transport_type_e type)
208
 
{
209
 
    unsigned i;
210
 
    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
211
 
        if (transport_names[i].type == type)
212
 
            return &transport_names[i];
213
 
    }
214
 
    pj_assert(!"Invalid transport type!");
215
 
    return NULL;
216
 
}
217
 
 
218
 
 
219
 
 
220
 
/*
221
 
 * Register new transport type to PJSIP.
222
 
 */
223
 
PJ_DEF(pj_status_t) pjsip_transport_register_type( unsigned tp_flag,
224
 
                                                   const char *tp_name,
225
 
                                                   int def_port,
226
 
                                                   int *p_tp_type)
227
 
{
228
 
    unsigned i;
229
 
 
230
 
    PJ_ASSERT_RETURN(tp_flag && tp_name && def_port, PJ_EINVAL);
231
 
    PJ_ASSERT_RETURN(pj_ansi_strlen(tp_name) <
232
 
                        PJ_ARRAY_SIZE(transport_names[0].name_buf),
233
 
                     PJ_ENAMETOOLONG);
234
 
 
235
 
    for (i=1; i<PJ_ARRAY_SIZE(transport_names); ++i) {
236
 
        if (transport_names[i].type == 0)
237
 
            break;
238
 
    }
239
 
 
240
 
    if (i == PJ_ARRAY_SIZE(transport_names))
241
 
        return PJ_ETOOMANY;
242
 
 
243
 
    transport_names[i].type = (pjsip_transport_type_e)i;
244
 
    transport_names[i].port = (pj_uint16_t)def_port;
245
 
    pj_ansi_strcpy(transport_names[i].name_buf, tp_name);
246
 
    transport_names[i].name = pj_str(transport_names[i].name_buf);
247
 
    transport_names[i].flag = tp_flag;
248
 
 
249
 
    if (p_tp_type)
250
 
        *p_tp_type = i;
251
 
 
252
 
    return PJ_SUCCESS;
253
 
}
254
 
 
255
 
 
256
 
/*
257
 
 * Get transport type from name.
258
 
 */
259
 
PJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_name(const pj_str_t *name)
260
 
{
261
 
    unsigned i;
262
 
 
263
 
    if (name->slen == 0)
264
 
        return PJSIP_TRANSPORT_UNSPECIFIED;
265
 
 
266
 
    /* Get transport type from name. */
267
 
    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
268
 
        if (pj_stricmp(name, &transport_names[i].name) == 0) {
269
 
            return transport_names[i].type;
270
 
        }
271
 
    }
272
 
 
273
 
    pj_assert(!"Invalid transport name");
274
 
    return PJSIP_TRANSPORT_UNSPECIFIED;
275
 
}
276
 
 
277
 
 
278
 
/*
279
 
 * Get the transport type for the specified flags.
280
 
 */
281
 
PJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_flag(unsigned flag)
282
 
{
283
 
    unsigned i;
284
 
 
285
 
    /* Get the transport type for the specified flags. */
286
 
    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
287
 
        if (transport_names[i].flag == flag) {
288
 
            return transport_names[i].type;
289
 
        }
290
 
    }
291
 
 
292
 
    pj_assert(!"Invalid transport type");
293
 
    return PJSIP_TRANSPORT_UNSPECIFIED;
294
 
}
295
 
 
296
 
/*
297
 
 * Get the socket address family of a given transport type.
298
 
 */
299
 
PJ_DEF(int) pjsip_transport_type_get_af(pjsip_transport_type_e type)
300
 
{
301
 
    if (type & PJSIP_TRANSPORT_IPV6)
302
 
        return pj_AF_INET6();
303
 
    else
304
 
        return pj_AF_INET();
305
 
}
306
 
 
307
 
PJ_DEF(unsigned) pjsip_transport_get_flag_from_type(pjsip_transport_type_e type)
308
 
{
309
 
    /* Return transport flag. */
310
 
    return get_tpname(type)->flag;
311
 
}
312
 
 
313
 
/*
314
 
 * Get the default SIP port number for the specified type.
315
 
 */
316
 
PJ_DEF(int) pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type)
317
 
{
318
 
    /* Return the port. */
319
 
    return get_tpname(type)->port;
320
 
}
321
 
 
322
 
/*
323
 
 * Get transport name.
324
 
 */
325
 
PJ_DEF(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e type)
326
 
{
327
 
    /* Return the name. */
328
 
    return get_tpname(type)->name.ptr;
329
 
}
330
 
 
331
 
/*
332
 
 * Get transport description.
333
 
 */
334
 
PJ_DEF(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e type)
335
 
{
336
 
    /* Return the description. */
337
 
    return get_tpname(type)->description;
338
 
}
339
 
 
340
 
 
341
 
/*****************************************************************************
342
 
 *
343
 
 * TRANSPORT SELECTOR
344
 
 *
345
 
 *****************************************************************************/
346
 
 
347
 
/*
348
 
 * Add transport/listener reference in the selector.
349
 
 */
350
 
PJ_DEF(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel)
351
 
{
352
 
    if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)
353
 
        pjsip_transport_add_ref(sel->u.transport);
354
 
    else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)
355
 
        ; /* Hmm.. looks like we don't have reference counter for listener */
356
 
}
357
 
 
358
 
 
359
 
/*
360
 
 * Decrement transport/listener reference in the selector.
361
 
 */
362
 
PJ_DEF(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel)
363
 
{
364
 
    if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)
365
 
        pjsip_transport_dec_ref(sel->u.transport);
366
 
    else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)
367
 
        ; /* Hmm.. looks like we don't have reference counter for listener */
368
 
}
369
 
 
370
 
 
371
 
/*****************************************************************************
372
 
 *
373
 
 * TRANSMIT DATA BUFFER MANIPULATION.
374
 
 *
375
 
 *****************************************************************************/
376
 
 
377
 
/*
378
 
 * Create new transmit buffer.
379
 
 */
380
 
PJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,
381
 
                                          pjsip_tx_data **p_tdata )
382
 
{
383
 
    pj_pool_t *pool;
384
 
    pjsip_tx_data *tdata;
385
 
    pj_status_t status;
386
 
 
387
 
    PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL);
388
 
 
389
 
    pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p",
390
 
                                    PJSIP_POOL_LEN_TDATA,
391
 
                                    PJSIP_POOL_INC_TDATA );
392
 
    if (!pool)
393
 
        return PJ_ENOMEM;
394
 
 
395
 
    tdata = PJ_POOL_ZALLOC_T(pool, pjsip_tx_data);
396
 
    tdata->pool = pool;
397
 
    tdata->mgr = mgr;
398
 
    pj_memcpy(tdata->obj_name, pool->obj_name, PJ_MAX_OBJ_NAME);
399
 
 
400
 
    status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt);
401
 
    if (status != PJ_SUCCESS) {
402
 
        pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
403
 
        return status;
404
 
    }
405
 
 
406
 
    //status = pj_lock_create_simple_mutex(pool, "tdta%p", &tdata->lock);
407
 
    status = pj_lock_create_null_mutex(pool, "tdta%p", &tdata->lock);
408
 
    if (status != PJ_SUCCESS) {
409
 
        pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
410
 
        return status;
411
 
    }
412
 
 
413
 
    pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key.key));
414
 
 
415
 
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
416
 
    pj_atomic_inc( tdata->mgr->tdata_counter );
417
 
#endif
418
 
 
419
 
    *p_tdata = tdata;
420
 
    return PJ_SUCCESS;
421
 
}
422
 
 
423
 
 
424
 
/*
425
 
 * Add reference to tx buffer.
426
 
 */
427
 
PJ_DEF(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata )
428
 
{
429
 
    pj_atomic_inc(tdata->ref_cnt);
430
 
}
431
 
 
432
 
/*
433
 
 * Decrease transport data reference, destroy it when the reference count
434
 
 * reaches zero.
435
 
 */
436
 
PJ_DEF(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata )
437
 
{
438
 
    pj_assert( pj_atomic_get(tdata->ref_cnt) > 0);
439
 
    if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) {
440
 
        PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s",
441
 
                  pjsip_tx_data_get_info(tdata)));
442
 
        pjsip_tpselector_dec_ref(&tdata->tp_sel);
443
 
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
444
 
        pj_atomic_dec( tdata->mgr->tdata_counter );
445
 
#endif
446
 
        pj_atomic_destroy( tdata->ref_cnt );
447
 
        pj_lock_destroy( tdata->lock );
448
 
        pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool );
449
 
        return PJSIP_EBUFDESTROYED;
450
 
    } else {
451
 
        return PJ_SUCCESS;
452
 
    }
453
 
}
454
 
 
455
 
/*
456
 
 * Invalidate the content of the print buffer to force the message to be
457
 
 * re-printed when sent.
458
 
 */
459
 
PJ_DEF(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata )
460
 
{
461
 
    tdata->buf.cur = tdata->buf.start;
462
 
    tdata->info = NULL;
463
 
}
464
 
 
465
 
/*
466
 
 * Print the SIP message to transmit data buffer's internal buffer.
467
 
 */
468
 
PJ_DEF(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata)
469
 
{
470
 
    /* Allocate buffer if necessary. */
471
 
    if (tdata->buf.start == NULL) {
472
 
        PJ_USE_EXCEPTION;
473
 
 
474
 
        PJ_TRY {
475
 
            tdata->buf.start = (char*)
476
 
                               pj_pool_alloc(tdata->pool, PJSIP_MAX_PKT_LEN);
477
 
        }
478
 
        PJ_CATCH_ANY {
479
 
            return PJ_ENOMEM;
480
 
        }
481
 
        PJ_END
482
 
 
483
 
        tdata->buf.cur = tdata->buf.start;
484
 
        tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN;
485
 
    }
486
 
 
487
 
    /* Do we need to reprint? */
488
 
    if (!pjsip_tx_data_is_valid(tdata)) {
489
 
        pj_ssize_t size;
490
 
 
491
 
        size = pjsip_msg_print( tdata->msg, tdata->buf.start,
492
 
                                tdata->buf.end - tdata->buf.start);
493
 
        if (size < 0) {
494
 
            return PJSIP_EMSGTOOLONG;
495
 
        }
496
 
        pj_assert(size != 0);
497
 
        tdata->buf.cur[size] = '\0';
498
 
        tdata->buf.cur += size;
499
 
    }
500
 
 
501
 
    return PJ_SUCCESS;
502
 
}
503
 
 
504
 
PJ_DEF(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata )
505
 
{
506
 
    return tdata->buf.cur != tdata->buf.start;
507
 
}
508
 
 
509
 
static char *get_msg_info(pj_pool_t *pool, const char *obj_name,
510
 
                          const pjsip_msg *msg)
511
 
{
512
 
    char info_buf[128], *info;
513
 
    const pjsip_cseq_hdr *cseq;
514
 
    int len;
515
 
 
516
 
    cseq = (const pjsip_cseq_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);
517
 
    PJ_ASSERT_RETURN(cseq != NULL, "INVALID MSG");
518
 
 
519
 
    if (msg->type == PJSIP_REQUEST_MSG) {
520
 
        len = pj_ansi_snprintf(info_buf, sizeof(info_buf),
521
 
                               "Request msg %.*s/cseq=%d (%s)",
522
 
                               (int)msg->line.req.method.name.slen,
523
 
                               msg->line.req.method.name.ptr,
524
 
                               cseq->cseq, obj_name);
525
 
    } else {
526
 
        len = pj_ansi_snprintf(info_buf, sizeof(info_buf),
527
 
                               "Response msg %d/%.*s/cseq=%d (%s)",
528
 
                               msg->line.status.code,
529
 
                               (int)cseq->method.name.slen,
530
 
                               cseq->method.name.ptr,
531
 
                               cseq->cseq, obj_name);
532
 
    }
533
 
 
534
 
    if (len < 1 || len >= (int)sizeof(info_buf)) {
535
 
        return (char*)obj_name;
536
 
    }
537
 
 
538
 
    info = (char*) pj_pool_alloc(pool, len+1);
539
 
    pj_memcpy(info, info_buf, len+1);
540
 
 
541
 
    return info;
542
 
}
543
 
 
544
 
PJ_DEF(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata )
545
 
{
546
 
    /* tdata->info may be assigned by application so if it exists
547
 
     * just return it.
548
 
     */
549
 
    if (tdata->info)
550
 
        return tdata->info;
551
 
 
552
 
    if (tdata==NULL || tdata->msg==NULL)
553
 
        return "NULL";
554
 
 
555
 
    pj_lock_acquire(tdata->lock);
556
 
    tdata->info = get_msg_info(tdata->pool, tdata->obj_name, tdata->msg);
557
 
    pj_lock_release(tdata->lock);
558
 
 
559
 
    return tdata->info;
560
 
}
561
 
 
562
 
PJ_DEF(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,
563
 
                                                const pjsip_tpselector *sel)
564
 
{
565
 
    PJ_ASSERT_RETURN(tdata && sel, PJ_EINVAL);
566
 
 
567
 
    pj_lock_acquire(tdata->lock);
568
 
 
569
 
    pjsip_tpselector_dec_ref(&tdata->tp_sel);
570
 
 
571
 
    pj_memcpy(&tdata->tp_sel, sel, sizeof(*sel));
572
 
    pjsip_tpselector_add_ref(&tdata->tp_sel);
573
 
 
574
 
    pj_lock_release(tdata->lock);
575
 
 
576
 
    return PJ_SUCCESS;
577
 
}
578
 
 
579
 
 
580
 
PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata)
581
 
{
582
 
    char obj_name[PJ_MAX_OBJ_NAME];
583
 
 
584
 
    PJ_ASSERT_RETURN(rdata->msg_info.msg, "INVALID MSG");
585
 
 
586
 
    if (rdata->msg_info.info)
587
 
        return rdata->msg_info.info;
588
 
 
589
 
    pj_ansi_strcpy(obj_name, "rdata");
590
 
    pj_ansi_snprintf(obj_name+5, sizeof(obj_name)-5, "%p", rdata);
591
 
 
592
 
    rdata->msg_info.info = get_msg_info(rdata->tp_info.pool, obj_name,
593
 
                                        rdata->msg_info.msg);
594
 
    return rdata->msg_info.info;
595
 
}
596
 
 
597
 
/*****************************************************************************
598
 
 *
599
 
 * TRANSPORT KEY
600
 
 *
601
 
 *****************************************************************************/
602
 
 
603
 
 
604
 
/*****************************************************************************
605
 
 *
606
 
 * TRANSPORT
607
 
 *
608
 
 *****************************************************************************/
609
 
 
610
 
static void transport_send_callback(pjsip_transport *transport,
611
 
                                    void *token,
612
 
                                    pj_ssize_t size)
613
 
{
614
 
    pjsip_tx_data *tdata = (pjsip_tx_data*) token;
615
 
 
616
 
    PJ_UNUSED_ARG(transport);
617
 
 
618
 
    /* Mark pending off so that app can resend/reuse txdata from inside
619
 
     * the callback.
620
 
     */
621
 
    tdata->is_pending = 0;
622
 
 
623
 
    /* Call callback, if any. */
624
 
    if (tdata->cb) {
625
 
        (*tdata->cb)(tdata->token, tdata, size);
626
 
    }
627
 
 
628
 
    /* Decrement reference count. */
629
 
    pjsip_tx_data_dec_ref(tdata);
630
 
}
631
 
 
632
 
/* This function is called by endpoint for on_tx_request() and on_tx_response()
633
 
 * notification.
634
 
 */
635
 
static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata)
636
 
{
637
 
    return pjsip_tx_data_encode(tdata);
638
 
}
639
 
 
640
 
/*
641
 
 * Send a SIP message using the specified transport.
642
 
 */
643
 
PJ_DEF(pj_status_t) pjsip_transport_send(  pjsip_transport *tr,
644
 
                                           pjsip_tx_data *tdata,
645
 
                                           const pj_sockaddr_t *addr,
646
 
                                           int addr_len,
647
 
                                           void *token,
648
 
                                           pjsip_tp_send_callback cb)
649
 
{
650
 
    pj_status_t status;
651
 
 
652
 
    PJ_ASSERT_RETURN(tr && tdata && addr, PJ_EINVAL);
653
 
 
654
 
    /* Is it currently being sent? */
655
 
    if (tdata->is_pending) {
656
 
        pj_assert(!"Invalid operation step!");
657
 
        PJ_LOG(2,(THIS_FILE, "Unable to send %s: message is pending",
658
 
                             pjsip_tx_data_get_info(tdata)));
659
 
        return PJSIP_EPENDINGTX;
660
 
    }
661
 
 
662
 
    /* Add reference to prevent deletion, and to cancel idle timer if
663
 
     * it's running.
664
 
     */
665
 
    pjsip_transport_add_ref(tr);
666
 
 
667
 
    /* Fill in tp_info. */
668
 
    tdata->tp_info.transport = tr;
669
 
    pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len);
670
 
    tdata->tp_info.dst_addr_len = addr_len;
671
 
 
672
 
    pj_inet_ntop(((pj_sockaddr*)addr)->addr.sa_family,
673
 
                 pj_sockaddr_get_addr(addr),
674
 
                 tdata->tp_info.dst_name,
675
 
                 sizeof(tdata->tp_info.dst_name));
676
 
    tdata->tp_info.dst_port = pj_sockaddr_get_port(addr);
677
 
 
678
 
    /* Distribute to modules.
679
 
     * When the message reach mod_msg_print, the contents of the message will
680
 
     * be "printed" to contiguous buffer.
681
 
     */
682
 
    if (tr->tpmgr->on_tx_msg) {
683
 
        status = (*tr->tpmgr->on_tx_msg)(tr->endpt, tdata);
684
 
        if (status != PJ_SUCCESS) {
685
 
            pjsip_transport_dec_ref(tr);
686
 
            return status;
687
 
        }
688
 
    }
689
 
 
690
 
    /* Save callback data. */
691
 
    tdata->token = token;
692
 
    tdata->cb = cb;
693
 
 
694
 
    /* Add reference counter. */
695
 
    pjsip_tx_data_add_ref(tdata);
696
 
 
697
 
    /* Mark as pending. */
698
 
    tdata->is_pending = 1;
699
 
 
700
 
    /* Send to transport. */
701
 
    status = (*tr->send_msg)(tr, tdata,  addr, addr_len, (void*)tdata,
702
 
                             &transport_send_callback);
703
 
 
704
 
    if (status != PJ_EPENDING) {
705
 
        tdata->is_pending = 0;
706
 
        pjsip_tx_data_dec_ref(tdata);
707
 
    }
708
 
 
709
 
    pjsip_transport_dec_ref(tr);
710
 
    return status;
711
 
}
712
 
 
713
 
 
714
 
/* send_raw() callback */
715
 
static void send_raw_callback(pjsip_transport *transport,
716
 
                              void *token,
717
 
                              pj_ssize_t size)
718
 
{
719
 
    pjsip_tx_data *tdata = (pjsip_tx_data*) token;
720
 
 
721
 
    /* Mark pending off so that app can resend/reuse txdata from inside
722
 
     * the callback.
723
 
     */
724
 
    tdata->is_pending = 0;
725
 
 
726
 
    /* Call callback, if any. */
727
 
    if (tdata->cb) {
728
 
        (*tdata->cb)(tdata->token, tdata, size);
729
 
    }
730
 
 
731
 
    /* Decrement tdata reference count. */
732
 
    pjsip_tx_data_dec_ref(tdata);
733
 
 
734
 
    /* Decrement transport reference count */
735
 
    pjsip_transport_dec_ref(transport);
736
 
}
737
 
 
738
 
 
739
 
/* Send raw data */
740
 
PJ_DEF(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,
741
 
                                         pjsip_transport_type_e tp_type,
742
 
                                         const pjsip_tpselector *sel,
743
 
                                         pjsip_tx_data *tdata,
744
 
                                         const void *raw_data,
745
 
                                         pj_size_t data_len,
746
 
                                         const pj_sockaddr_t *addr,
747
 
                                         int addr_len,
748
 
                                         void *token,
749
 
                                         pjsip_tp_send_callback cb)
750
 
{
751
 
    pjsip_transport *tr;
752
 
    pj_status_t status;
753
 
 
754
 
    /* Acquire the transport */
755
 
    status = pjsip_tpmgr_acquire_transport(mgr, tp_type, addr, addr_len,
756
 
                                           sel, &tr);
757
 
    if (status != PJ_SUCCESS)
758
 
        return status;
759
 
 
760
 
    /* Create transmit data buffer if one is not specified */
761
 
    if (tdata == NULL) {
762
 
        status = pjsip_endpt_create_tdata(tr->endpt, &tdata);
763
 
        if (status != PJ_SUCCESS) {
764
 
            pjsip_transport_dec_ref(tr);
765
 
            return status;
766
 
        }
767
 
 
768
 
        tdata->info = "raw";
769
 
 
770
 
        /* Add reference counter. */
771
 
        pjsip_tx_data_add_ref(tdata);
772
 
    }
773
 
 
774
 
    /* Allocate buffer */
775
 
    if (tdata->buf.start == NULL ||
776
 
        (tdata->buf.end - tdata->buf.start) < (int)data_len)
777
 
    {
778
 
        /* Note: data_len may be zero, so allocate +1 */
779
 
        tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);
780
 
        tdata->buf.end = tdata->buf.start + data_len + 1;
781
 
    }
782
 
 
783
 
    /* Copy data, if any! (application may send zero len packet) */
784
 
    if (data_len) {
785
 
        pj_memcpy(tdata->buf.start, raw_data, data_len);
786
 
    }
787
 
    tdata->buf.cur = tdata->buf.start + data_len;
788
 
 
789
 
    /* Save callback data. */
790
 
    tdata->token = token;
791
 
    tdata->cb = cb;
792
 
 
793
 
    /* Mark as pending. */
794
 
    tdata->is_pending = 1;
795
 
 
796
 
    /* Send to transport */
797
 
    status = tr->send_msg(tr, tdata, addr, addr_len,
798
 
                          tdata, &send_raw_callback);
799
 
 
800
 
    if (status != PJ_EPENDING) {
801
 
        /* callback will not be called, so destroy tdata now. */
802
 
        pjsip_tx_data_dec_ref(tdata);
803
 
        pjsip_transport_dec_ref(tr);
804
 
    }
805
 
 
806
 
    return status;
807
 
}
808
 
 
809
 
 
810
 
static void transport_idle_callback(pj_timer_heap_t *timer_heap,
811
 
                                    struct pj_timer_entry *entry)
812
 
{
813
 
    pjsip_transport *tp = (pjsip_transport*) entry->user_data;
814
 
    pj_assert(tp != NULL);
815
 
 
816
 
    PJ_UNUSED_ARG(timer_heap);
817
 
 
818
 
    entry->id = PJ_FALSE;
819
 
    pjsip_transport_destroy(tp);
820
 
}
821
 
 
822
 
/*
823
 
 * Add ref.
824
 
 */
825
 
PJ_DEF(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp )
826
 
{
827
 
    PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL);
828
 
 
829
 
    if (pj_atomic_inc_and_get(tp->ref_cnt) == 1) {
830
 
        pj_lock_acquire(tp->tpmgr->lock);
831
 
        /* Verify again. */
832
 
        if (pj_atomic_get(tp->ref_cnt) == 1) {
833
 
            if (tp->idle_timer.id != PJ_FALSE) {
834
 
                pjsip_endpt_cancel_timer(tp->tpmgr->endpt, &tp->idle_timer);
835
 
                tp->idle_timer.id = PJ_FALSE;
836
 
            }
837
 
        }
838
 
        pj_lock_release(tp->tpmgr->lock);
839
 
    }
840
 
 
841
 
    return PJ_SUCCESS;
842
 
}
843
 
 
844
 
/*
845
 
 * Dec ref.
846
 
 */
847
 
PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp )
848
 
{
849
 
    PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL);
850
 
 
851
 
    pj_assert(pj_atomic_get(tp->ref_cnt) > 0);
852
 
 
853
 
    if (pj_atomic_dec_and_get(tp->ref_cnt) == 0) {
854
 
        pj_lock_acquire(tp->tpmgr->lock);
855
 
        /* Verify again. Do not register timer if the transport is
856
 
         * being destroyed.
857
 
         */
858
 
        if (pj_atomic_get(tp->ref_cnt) == 0 && !tp->is_destroying) {
859
 
            pj_time_val delay;
860
 
 
861
 
            /* If transport is in graceful shutdown, then this is the
862
 
             * last user who uses the transport. Schedule to destroy the
863
 
             * transport immediately. Otherwise schedule idle timer.
864
 
             */
865
 
            if (tp->is_shutdown) {
866
 
                delay.sec = delay.msec = 0;
867
 
            } else {
868
 
                delay.sec = (tp->dir==PJSIP_TP_DIR_OUTGOING) ?
869
 
                                PJSIP_TRANSPORT_IDLE_TIME :
870
 
                                PJSIP_TRANSPORT_SERVER_IDLE_TIME;
871
 
                delay.msec = 0;
872
 
            }
873
 
 
874
 
            pj_assert(tp->idle_timer.id == 0);
875
 
            tp->idle_timer.id = PJ_TRUE;
876
 
            pjsip_endpt_schedule_timer(tp->tpmgr->endpt, &tp->idle_timer,
877
 
                                       &delay);
878
 
        }
879
 
        pj_lock_release(tp->tpmgr->lock);
880
 
    }
881
 
 
882
 
    return PJ_SUCCESS;
883
 
}
884
 
 
885
 
 
886
 
/**
887
 
 * Register a transport.
888
 
 */
889
 
PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
890
 
                                              pjsip_transport *tp )
891
 
{
892
 
    int key_len;
893
 
    pj_uint32_t hval;
894
 
    void *entry;
895
 
 
896
 
    /* Init. */
897
 
    tp->tpmgr = mgr;
898
 
    pj_bzero(&tp->idle_timer, sizeof(tp->idle_timer));
899
 
    tp->idle_timer.user_data = tp;
900
 
    tp->idle_timer.cb = &transport_idle_callback;
901
 
 
902
 
    /*
903
 
     * Register to hash table (see Trac ticket #42).
904
 
     */
905
 
    key_len = sizeof(tp->key.type) + tp->addr_len;
906
 
    pj_lock_acquire(mgr->lock);
907
 
 
908
 
    /* If entry already occupied, unregister previous entry */
909
 
    hval = 0;
910
 
    entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);
911
 
    if (entry != NULL)
912
 
        pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL);
913
 
 
914
 
    /* Register new entry */
915
 
    pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, hval, tp);
916
 
 
917
 
    pj_lock_release(mgr->lock);
918
 
 
919
 
    TRACE_((THIS_FILE,"Transport %s registered: type=%s, remote=%s:%d",
920
 
                       tp->obj_name,
921
 
                       pjsip_transport_get_type_name(tp->key.type),
922
 
                       addr_string(&tp->key.rem_addr),
923
 
                       pj_sockaddr_get_port(&tp->key.rem_addr)));
924
 
 
925
 
    return PJ_SUCCESS;
926
 
}
927
 
 
928
 
/* Force destroy transport (e.g. during transport manager shutdown. */
929
 
static pj_status_t destroy_transport( pjsip_tpmgr *mgr,
930
 
                                      pjsip_transport *tp )
931
 
{
932
 
    int key_len;
933
 
    pj_uint32_t hval;
934
 
    void *entry;
935
 
 
936
 
    TRACE_((THIS_FILE, "Transport %s is being destroyed", tp->obj_name));
937
 
 
938
 
    pj_lock_acquire(tp->lock);
939
 
    pj_lock_acquire(mgr->lock);
940
 
 
941
 
    tp->is_destroying = PJ_TRUE;
942
 
 
943
 
    /*
944
 
     * Unregister timer, if any.
945
 
     */
946
 
    //pj_assert(tp->idle_timer.id == PJ_FALSE);
947
 
    if (tp->idle_timer.id != PJ_FALSE) {
948
 
        pjsip_endpt_cancel_timer(mgr->endpt, &tp->idle_timer);
949
 
        tp->idle_timer.id = PJ_FALSE;
950
 
    }
951
 
 
952
 
    /*
953
 
     * Unregister from hash table (see Trac ticket #42).
954
 
     */
955
 
    key_len = sizeof(tp->key.type) + tp->addr_len;
956
 
    hval = 0;
957
 
    entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);
958
 
    if (entry == (void*)tp)
959
 
        pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL);
960
 
 
961
 
    pj_lock_release(mgr->lock);
962
 
 
963
 
    /* Destroy. */
964
 
    return tp->destroy(tp);
965
 
}
966
 
 
967
 
 
968
 
/*
969
 
 * Start graceful shutdown procedure for this transport.
970
 
 */
971
 
PJ_DEF(pj_status_t) pjsip_transport_shutdown(pjsip_transport *tp)
972
 
{
973
 
    pjsip_tpmgr *mgr;
974
 
    pj_status_t status;
975
 
 
976
 
    TRACE_((THIS_FILE, "Transport %s shutting down", tp->obj_name));
977
 
 
978
 
    pj_lock_acquire(tp->lock);
979
 
 
980
 
    mgr = tp->tpmgr;
981
 
    pj_lock_acquire(mgr->lock);
982
 
 
983
 
    /* Do nothing if transport is being shutdown already */
984
 
    if (tp->is_shutdown) {
985
 
        pj_lock_release(tp->lock);
986
 
        pj_lock_release(mgr->lock);
987
 
        return PJ_SUCCESS;
988
 
    }
989
 
 
990
 
    status = PJ_SUCCESS;
991
 
 
992
 
    /* Instruct transport to shutdown itself */
993
 
    if (tp->do_shutdown)
994
 
        status = tp->do_shutdown(tp);
995
 
 
996
 
    if (status == PJ_SUCCESS)
997
 
        tp->is_shutdown = PJ_TRUE;
998
 
 
999
 
    /* If transport reference count is zero, start timer count-down */
1000
 
    if (pj_atomic_get(tp->ref_cnt) == 0) {
1001
 
        pjsip_transport_add_ref(tp);
1002
 
        pjsip_transport_dec_ref(tp);
1003
 
    }
1004
 
 
1005
 
    pj_lock_release(tp->lock);
1006
 
    pj_lock_release(mgr->lock);
1007
 
 
1008
 
    return status;
1009
 
}
1010
 
 
1011
 
 
1012
 
/**
1013
 
 * Unregister transport.
1014
 
 */
1015
 
PJ_DEF(pj_status_t) pjsip_transport_destroy( pjsip_transport *tp)
1016
 
{
1017
 
    /* Must have no user. */
1018
 
    PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY);
1019
 
 
1020
 
    /* Destroy. */
1021
 
    return destroy_transport(tp->tpmgr, tp);
1022
 
}
1023
 
 
1024
 
 
1025
 
 
1026
 
/*****************************************************************************
1027
 
 *
1028
 
 * TRANSPORT FACTORY
1029
 
 *
1030
 
 *****************************************************************************/
1031
 
 
1032
 
 
1033
 
PJ_DEF(pj_status_t) pjsip_tpmgr_register_tpfactory( pjsip_tpmgr *mgr,
1034
 
                                                    pjsip_tpfactory *tpf)
1035
 
{
1036
 
    pjsip_tpfactory *p;
1037
 
    pj_status_t status;
1038
 
 
1039
 
    pj_lock_acquire(mgr->lock);
1040
 
 
1041
 
    /* Check that no factory with the same type has been registered. */
1042
 
    status = PJ_SUCCESS;
1043
 
    for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {
1044
 
        if (p->type == tpf->type) {
1045
 
            status = PJSIP_ETYPEEXISTS;
1046
 
            break;
1047
 
        }
1048
 
        if (p == tpf) {
1049
 
            status = PJ_EEXISTS;
1050
 
            break;
1051
 
        }
1052
 
    }
1053
 
 
1054
 
    if (status != PJ_SUCCESS) {
1055
 
        pj_lock_release(mgr->lock);
1056
 
        return status;
1057
 
    }
1058
 
 
1059
 
    pj_list_insert_before(&mgr->factory_list, tpf);
1060
 
 
1061
 
    pj_lock_release(mgr->lock);
1062
 
 
1063
 
    return PJ_SUCCESS;
1064
 
}
1065
 
 
1066
 
 
1067
 
/**
1068
 
 * Unregister factory.
1069
 
 */
1070
 
PJ_DEF(pj_status_t) pjsip_tpmgr_unregister_tpfactory( pjsip_tpmgr *mgr,
1071
 
                                                      pjsip_tpfactory *tpf)
1072
 
{
1073
 
    pj_lock_acquire(mgr->lock);
1074
 
 
1075
 
    pj_assert(pj_list_find_node(&mgr->factory_list, tpf) == tpf);
1076
 
    pj_list_erase(tpf);
1077
 
 
1078
 
    pj_lock_release(mgr->lock);
1079
 
 
1080
 
    return PJ_SUCCESS;
1081
 
}
1082
 
 
1083
 
 
1084
 
/*****************************************************************************
1085
 
 *
1086
 
 * TRANSPORT MANAGER
1087
 
 *
1088
 
 *****************************************************************************/
1089
 
 
1090
 
/*
1091
 
 * Create a new transport manager.
1092
 
 */
1093
 
PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,
1094
 
                                        pjsip_endpoint *endpt,
1095
 
                                        pjsip_rx_callback rx_cb,
1096
 
                                        pjsip_tx_callback tx_cb,
1097
 
                                        pjsip_tpmgr **p_mgr)
1098
 
{
1099
 
    pjsip_tpmgr *mgr;
1100
 
    pj_status_t status;
1101
 
 
1102
 
    PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL);
1103
 
 
1104
 
    /* Register mod_msg_print module. */
1105
 
    status = pjsip_endpt_register_module(endpt, &mod_msg_print);
1106
 
    if (status != PJ_SUCCESS)
1107
 
        return status;
1108
 
 
1109
 
    /* Create and initialize transport manager. */
1110
 
    mgr = PJ_POOL_ZALLOC_T(pool, pjsip_tpmgr);
1111
 
    mgr->endpt = endpt;
1112
 
    mgr->on_rx_msg = rx_cb;
1113
 
    mgr->on_tx_msg = tx_cb;
1114
 
    pj_list_init(&mgr->factory_list);
1115
 
 
1116
 
    mgr->table = pj_hash_create(pool, PJSIP_TPMGR_HTABLE_SIZE);
1117
 
    if (!mgr->table)
1118
 
        return PJ_ENOMEM;
1119
 
 
1120
 
    status = pj_lock_create_recursive_mutex(pool, "tmgr%p", &mgr->lock);
1121
 
    if (status != PJ_SUCCESS)
1122
 
        return status;
1123
 
 
1124
 
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
1125
 
    status = pj_atomic_create(pool, 0, &mgr->tdata_counter);
1126
 
    if (status != PJ_SUCCESS)
1127
 
        return status;
1128
 
#endif
1129
 
 
1130
 
    /* Set transport state callback */
1131
 
    status = pjsip_tpmgr_set_state_cb(mgr, &tp_state_callback);
1132
 
    if (status != PJ_SUCCESS)
1133
 
        return status;
1134
 
 
1135
 
    PJ_LOG(5, (THIS_FILE, "Transport manager created."));
1136
 
 
1137
 
    *p_mgr = mgr;
1138
 
    return PJ_SUCCESS;
1139
 
}
1140
 
 
1141
 
 
1142
 
 
1143
 
/*
1144
 
 * Find out the appropriate local address info (IP address and port) to
1145
 
 * advertise in Contact header based on the remote address to be
1146
 
 * contacted. The local address info would be the address name of the
1147
 
 * transport or listener which will be used to send the request.
1148
 
 *
1149
 
 * In this implementation, it will only select the transport based on
1150
 
 * the transport type in the request.
1151
 
 */
1152
 
PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr,
1153
 
                                                 pj_pool_t *pool,
1154
 
                                                 pjsip_transport_type_e type,
1155
 
                                                 const pjsip_tpselector *sel,
1156
 
                                                 pj_str_t *ip_addr,
1157
 
                                                 int *port)
1158
 
{
1159
 
    pj_status_t status = PJSIP_EUNSUPTRANSPORT;
1160
 
    unsigned flag;
1161
 
 
1162
 
    /* Sanity checks */
1163
 
    PJ_ASSERT_RETURN(tpmgr && pool && ip_addr && port, PJ_EINVAL);
1164
 
 
1165
 
    ip_addr->slen = 0;
1166
 
    *port = 0;
1167
 
 
1168
 
    flag = pjsip_transport_get_flag_from_type(type);
1169
 
 
1170
 
    if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT &&
1171
 
        sel->u.transport)
1172
 
    {
1173
 
        pj_strdup(pool, ip_addr, &sel->u.transport->local_name.host);
1174
 
        *port = sel->u.transport->local_name.port;
1175
 
        status = PJ_SUCCESS;
1176
 
 
1177
 
    } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
1178
 
               sel->u.listener)
1179
 
    {
1180
 
        pj_strdup(pool, ip_addr, &sel->u.listener->addr_name.host);
1181
 
        *port = sel->u.listener->addr_name.port;
1182
 
        status = PJ_SUCCESS;
1183
 
 
1184
 
    } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) {
1185
 
 
1186
 
        pj_sockaddr remote;
1187
 
        int addr_len;
1188
 
        pjsip_transport *tp;
1189
 
 
1190
 
        pj_bzero(&remote, sizeof(remote));
1191
 
        if (type & PJSIP_TRANSPORT_IPV6) {
1192
 
            addr_len = sizeof(pj_sockaddr_in6);
1193
 
            remote.addr.sa_family = pj_AF_INET6();
1194
 
        } else {
1195
 
            addr_len = sizeof(pj_sockaddr_in);
1196
 
            remote.addr.sa_family = pj_AF_INET();
1197
 
        }
1198
 
 
1199
 
        status = pjsip_tpmgr_acquire_transport(tpmgr, type, &remote,
1200
 
                                               addr_len, NULL, &tp);
1201
 
 
1202
 
        if (status == PJ_SUCCESS) {
1203
 
            pj_strdup(pool, ip_addr, &tp->local_name.host);
1204
 
            *port = tp->local_name.port;
1205
 
            status = PJ_SUCCESS;
1206
 
 
1207
 
            pjsip_transport_dec_ref(tp);
1208
 
        }
1209
 
 
1210
 
    } else {
1211
 
        /* For connection oriented transport, enum the factories */
1212
 
        pjsip_tpfactory *f;
1213
 
 
1214
 
        pj_lock_acquire(tpmgr->lock);
1215
 
 
1216
 
        f = tpmgr->factory_list.next;
1217
 
        while (f != &tpmgr->factory_list) {
1218
 
            if (f->type == type)
1219
 
                break;
1220
 
            f = f->next;
1221
 
        }
1222
 
 
1223
 
        if (f != &tpmgr->factory_list) {
1224
 
            pj_strdup(pool, ip_addr, &f->addr_name.host);
1225
 
            *port = f->addr_name.port;
1226
 
            status = PJ_SUCCESS;
1227
 
        }
1228
 
        pj_lock_release(tpmgr->lock);
1229
 
    }
1230
 
 
1231
 
    return status;
1232
 
}
1233
 
 
1234
 
/*
1235
 
 * Return number of transports currently registered to the transport
1236
 
 * manager.
1237
 
 */
1238
 
PJ_DEF(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr)
1239
 
{
1240
 
    pj_hash_iterator_t itr_val;
1241
 
    pj_hash_iterator_t *itr;
1242
 
    int nr_of_transports = 0;
1243
 
 
1244
 
    pj_lock_acquire(mgr->lock);
1245
 
 
1246
 
    itr = pj_hash_first(mgr->table, &itr_val);
1247
 
    while (itr) {
1248
 
        nr_of_transports++;
1249
 
        itr = pj_hash_next(mgr->table, itr);
1250
 
    }
1251
 
 
1252
 
    pj_lock_release(mgr->lock);
1253
 
 
1254
 
    return nr_of_transports;
1255
 
}
1256
 
 
1257
 
/*
1258
 
 * pjsip_tpmgr_destroy()
1259
 
 *
1260
 
 * Destroy transport manager.
1261
 
 */
1262
 
PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr )
1263
 
{
1264
 
    pj_hash_iterator_t itr_val;
1265
 
    pj_hash_iterator_t *itr;
1266
 
    pjsip_tpfactory *factory;
1267
 
    pjsip_endpoint *endpt = mgr->endpt;
1268
 
 
1269
 
    PJ_LOG(5, (THIS_FILE, "Destroying transport manager"));
1270
 
 
1271
 
    pj_lock_acquire(mgr->lock);
1272
 
 
1273
 
    /*
1274
 
     * Destroy all transports.
1275
 
     */
1276
 
    itr = pj_hash_first(mgr->table, &itr_val);
1277
 
    while (itr != NULL) {
1278
 
        pj_hash_iterator_t *next;
1279
 
        pjsip_transport *transport;
1280
 
 
1281
 
        transport = (pjsip_transport*) pj_hash_this(mgr->table, itr);
1282
 
 
1283
 
        next = pj_hash_next(mgr->table, itr);
1284
 
 
1285
 
        destroy_transport(mgr, transport);
1286
 
 
1287
 
        itr = next;
1288
 
    }
1289
 
 
1290
 
    /*
1291
 
     * Destroy all factories/listeners.
1292
 
     */
1293
 
    factory = mgr->factory_list.next;
1294
 
    while (factory != &mgr->factory_list) {
1295
 
        pjsip_tpfactory *next = factory->next;
1296
 
 
1297
 
        factory->destroy(factory);
1298
 
 
1299
 
        factory = next;
1300
 
    }
1301
 
 
1302
 
    pj_lock_release(mgr->lock);
1303
 
    pj_lock_destroy(mgr->lock);
1304
 
 
1305
 
    /* Unregister mod_msg_print. */
1306
 
    if (mod_msg_print.id != -1) {
1307
 
        pjsip_endpt_unregister_module(endpt, &mod_msg_print);
1308
 
    }
1309
 
 
1310
 
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
1311
 
    /* If you encounter assert error on this line, it means there are
1312
 
     * leakings in transmit data (i.e. some transmit data have not been
1313
 
     * destroyed).
1314
 
     */
1315
 
    //pj_assert(pj_atomic_get(mgr->tdata_counter) == 0);
1316
 
    if (pj_atomic_get(mgr->tdata_counter) != 0) {
1317
 
        PJ_LOG(3,(THIS_FILE, "Warning: %d transmit buffer(s) not freed!",
1318
 
                  pj_atomic_get(mgr->tdata_counter)));
1319
 
    }
1320
 
#endif
1321
 
 
1322
 
    return PJ_SUCCESS;
1323
 
}
1324
 
 
1325
 
 
1326
 
/*
1327
 
 * pjsip_tpmgr_receive_packet()
1328
 
 *
1329
 
 * Called by tranports when they receive a new packet.
1330
 
 */
1331
 
PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
1332
 
                                               pjsip_rx_data *rdata)
1333
 
{
1334
 
    pjsip_transport *tr = rdata->tp_info.transport;
1335
 
 
1336
 
    char *current_pkt;
1337
 
    pj_size_t remaining_len;
1338
 
    pj_size_t total_processed = 0;
1339
 
 
1340
 
    /* Check size. */
1341
 
    pj_assert(rdata->pkt_info.len > 0);
1342
 
    if (rdata->pkt_info.len <= 0)
1343
 
        return -1;
1344
 
 
1345
 
    current_pkt = rdata->pkt_info.packet;
1346
 
    remaining_len = rdata->pkt_info.len;
1347
 
 
1348
 
    /* Must NULL terminate buffer. This is the requirement of the
1349
 
     * parser etc.
1350
 
     */
1351
 
    current_pkt[remaining_len] = '\0';
1352
 
 
1353
 
    /* Process all message fragments. */
1354
 
    while (remaining_len > 0) {
1355
 
 
1356
 
        pjsip_msg *msg;
1357
 
        char *p, *end;
1358
 
        char saved;
1359
 
        pj_size_t msg_fragment_size;
1360
 
 
1361
 
        /* Skip leading newlines as pjsip_find_msg() currently can't
1362
 
         * handle leading newlines.
1363
 
         */
1364
 
        for (p=current_pkt, end=p+remaining_len; p!=end; ++p) {
1365
 
            if (*p != '\r' && *p != '\n')
1366
 
                break;
1367
 
        }
1368
 
        if (p!=current_pkt) {
1369
 
            remaining_len -= (p - current_pkt);
1370
 
            total_processed += (p - current_pkt);
1371
 
            current_pkt = p;
1372
 
            if (remaining_len == 0) {
1373
 
                return total_processed;
1374
 
            }
1375
 
        }
1376
 
 
1377
 
        /* Initialize default fragment size. */
1378
 
        msg_fragment_size = remaining_len;
1379
 
 
1380
 
        /* Clear and init msg_info in rdata.
1381
 
         * Endpoint might inspect the values there when we call the callback
1382
 
         * to report some errors.
1383
 
         */
1384
 
        pj_bzero(&rdata->msg_info, sizeof(rdata->msg_info));
1385
 
        pj_list_init(&rdata->msg_info.parse_err);
1386
 
        rdata->msg_info.msg_buf = current_pkt;
1387
 
        rdata->msg_info.len = remaining_len;
1388
 
 
1389
 
        /* For TCP transport, check if the whole message has been received. */
1390
 
        if ((tr->flag & PJSIP_TRANSPORT_DATAGRAM) == 0) {
1391
 
            pj_status_t msg_status;
1392
 
            msg_status = pjsip_find_msg(current_pkt, remaining_len, PJ_FALSE,
1393
 
                                        &msg_fragment_size);
1394
 
            if (msg_status != PJ_SUCCESS) {
1395
 
                if (remaining_len == PJSIP_MAX_PKT_LEN) {
1396
 
                    mgr->on_rx_msg(mgr->endpt, PJSIP_ERXOVERFLOW, rdata);
1397
 
                    /* Exhaust all data. */
1398
 
                    return rdata->pkt_info.len;
1399
 
                } else {
1400
 
                    /* Not enough data in packet. */
1401
 
                    return total_processed;
1402
 
                }
1403
 
            }
1404
 
        }
1405
 
 
1406
 
        /* Update msg_info. */
1407
 
        rdata->msg_info.len = msg_fragment_size;
1408
 
 
1409
 
        /* Null terminate packet */
1410
 
        saved = current_pkt[msg_fragment_size];
1411
 
        current_pkt[msg_fragment_size] = '\0';
1412
 
 
1413
 
        /* Parse the message. */
1414
 
        rdata->msg_info.msg = msg =
1415
 
            pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata);
1416
 
 
1417
 
        /* Restore null termination */
1418
 
        current_pkt[msg_fragment_size] = saved;
1419
 
 
1420
 
        /* Check for parsing syntax error */
1421
 
        if (msg==NULL || !pj_list_empty(&rdata->msg_info.parse_err)) {
1422
 
            pjsip_parser_err_report *err;
1423
 
            char buf[128];
1424
 
            pj_str_t tmp;
1425
 
 
1426
 
            /* Gather syntax error information */
1427
 
            tmp.ptr = buf; tmp.slen = 0;
1428
 
            err = rdata->msg_info.parse_err.next;
1429
 
            while (err != &rdata->msg_info.parse_err) {
1430
 
                int len;
1431
 
                len = pj_ansi_snprintf(tmp.ptr+tmp.slen, sizeof(buf)-tmp.slen,
1432
 
                                       ": %s exception when parsing '%.*s' "
1433
 
                                       "header on line %d col %d",
1434
 
                                       pj_exception_id_name(err->except_code),
1435
 
                                       (int)err->hname.slen, err->hname.ptr,
1436
 
                                       err->line, err->col);
1437
 
                if (len > 0 && len < (int) (sizeof(buf)-tmp.slen)) {
1438
 
                    tmp.slen += len;
1439
 
                }
1440
 
                err = err->next;
1441
 
            }
1442
 
 
1443
 
            /* Only print error message if there's error.
1444
 
             * Sometimes we receive blank packets (packets with only CRLF)
1445
 
             * which were sent to keep NAT bindings.
1446
 
             */
1447
 
            if (tmp.slen) {
1448
 
                PJ_LOG(1, (THIS_FILE,
1449
 
                      "Error processing %d bytes packet from %s %s:%d %.*s:\n"
1450
 
                      "%.*s\n"
1451
 
                      "-- end of packet.",
1452
 
                      msg_fragment_size,
1453
 
                      rdata->tp_info.transport->type_name,
1454
 
                      rdata->pkt_info.src_name,
1455
 
                      rdata->pkt_info.src_port,
1456
 
                      (int)tmp.slen, tmp.ptr,
1457
 
                      (int)msg_fragment_size,
1458
 
                      rdata->msg_info.msg_buf));
1459
 
            }
1460
 
 
1461
 
            goto finish_process_fragment;
1462
 
        }
1463
 
 
1464
 
        /* Perform basic header checking. */
1465
 
        if (rdata->msg_info.cid == NULL ||
1466
 
            rdata->msg_info.cid->id.slen == 0 ||
1467
 
            rdata->msg_info.from == NULL ||
1468
 
            rdata->msg_info.to == NULL ||
1469
 
            rdata->msg_info.via == NULL ||
1470
 
            rdata->msg_info.cseq == NULL)
1471
 
        {
1472
 
            mgr->on_rx_msg(mgr->endpt, PJSIP_EMISSINGHDR, rdata);
1473
 
            goto finish_process_fragment;
1474
 
        }
1475
 
 
1476
 
        /* For request: */
1477
 
        if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
1478
 
            /* always add received parameter to the via. */
1479
 
            pj_strdup2(rdata->tp_info.pool,
1480
 
                       &rdata->msg_info.via->recvd_param,
1481
 
                       rdata->pkt_info.src_name);
1482
 
 
1483
 
            /* RFC 3581:
1484
 
             * If message contains "rport" param, put the received port there.
1485
 
             */
1486
 
            if (rdata->msg_info.via->rport_param == 0) {
1487
 
                rdata->msg_info.via->rport_param = rdata->pkt_info.src_port;
1488
 
            }
1489
 
        } else {
1490
 
            /* Drop malformed responses */
1491
 
            if (rdata->msg_info.msg->line.status.code < 100 ||
1492
 
                rdata->msg_info.msg->line.status.code >= 700)
1493
 
            {
1494
 
                mgr->on_rx_msg(mgr->endpt, PJSIP_EINVALIDSTATUS, rdata);
1495
 
                goto finish_process_fragment;
1496
 
            }
1497
 
        }
1498
 
 
1499
 
        /* Drop response message if it has more than one Via.
1500
 
        */
1501
 
        /* This is wrong. Proxy DOES receive responses with multiple
1502
 
         * Via headers! Thanks Aldo <acampi at deis.unibo.it> for pointing
1503
 
         * this out.
1504
 
 
1505
 
        if (msg->type == PJSIP_RESPONSE_MSG) {
1506
 
            pjsip_hdr *hdr;
1507
 
            hdr = (pjsip_hdr*)rdata->msg_info.via->next;
1508
 
            if (hdr != &msg->hdr) {
1509
 
                hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr);
1510
 
                if (hdr) {
1511
 
                    mgr->on_rx_msg(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata);
1512
 
                    goto finish_process_fragment;
1513
 
                }
1514
 
            }
1515
 
        }
1516
 
        */
1517
 
 
1518
 
        /* Call the transport manager's upstream message callback.
1519
 
         */
1520
 
        mgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata);
1521
 
 
1522
 
 
1523
 
finish_process_fragment:
1524
 
        total_processed += msg_fragment_size;
1525
 
        current_pkt += msg_fragment_size;
1526
 
        remaining_len -= msg_fragment_size;
1527
 
 
1528
 
    }   /* while (rdata->pkt_info.len > 0) */
1529
 
 
1530
 
 
1531
 
    return total_processed;
1532
 
}
1533
 
 
1534
 
 
1535
 
/*
1536
 
 * pjsip_tpmgr_acquire_transport()
1537
 
 *
1538
 
 * Get transport suitable to communicate to remote. Create a new one
1539
 
 * if necessary.
1540
 
 */
1541
 
PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,
1542
 
                                                  pjsip_transport_type_e type,
1543
 
                                                  const pj_sockaddr_t *remote,
1544
 
                                                  int addr_len,
1545
 
                                                  const pjsip_tpselector *sel,
1546
 
                                                  pjsip_transport **tp)
1547
 
{
1548
 
    return pjsip_tpmgr_acquire_transport2(mgr, type, remote, addr_len, sel,
1549
 
                                          NULL, tp);
1550
 
}
1551
 
 
1552
 
/*
1553
 
 * pjsip_tpmgr_acquire_transport2()
1554
 
 *
1555
 
 * Get transport suitable to communicate to remote. Create a new one
1556
 
 * if necessary.
1557
 
 */
1558
 
PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
1559
 
                                                   pjsip_transport_type_e type,
1560
 
                                                   const pj_sockaddr_t *remote,
1561
 
                                                   int addr_len,
1562
 
                                                   const pjsip_tpselector *sel,
1563
 
                                                   pjsip_tx_data *tdata,
1564
 
                                                   pjsip_transport **tp)
1565
 
{
1566
 
    pjsip_tpfactory *factory;
1567
 
    pj_status_t status;
1568
 
 
1569
 
    TRACE_((THIS_FILE,"Acquiring transport type=%s, remote=%s:%d",
1570
 
                       pjsip_transport_get_type_name(type),
1571
 
                       addr_string(remote),
1572
 
                       pj_sockaddr_get_port(remote)));
1573
 
 
1574
 
    pj_lock_acquire(mgr->lock);
1575
 
 
1576
 
    /* If transport is specified, then just use it if it is suitable
1577
 
     * for the destination.
1578
 
     */
1579
 
    if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT &&
1580
 
        sel->u.transport)
1581
 
    {
1582
 
        pjsip_transport *seltp = sel->u.transport;
1583
 
 
1584
 
        /* See if the transport is (not) suitable */
1585
 
        if (seltp->key.type != type) {
1586
 
            pj_lock_release(mgr->lock);
1587
 
            return PJSIP_ETPNOTSUITABLE;
1588
 
        }
1589
 
 
1590
 
        /* We could also verify that the destination address is reachable
1591
 
         * from this transport (i.e. both are equal), but if application
1592
 
         * has requested a specific transport to be used, assume that
1593
 
         * it knows what to do.
1594
 
         *
1595
 
         * In other words, I don't think destination verification is a good
1596
 
         * idea for now.
1597
 
         */
1598
 
 
1599
 
        /* Transport looks to be suitable to use, so just use it. */
1600
 
        pjsip_transport_add_ref(seltp);
1601
 
        pj_lock_release(mgr->lock);
1602
 
        *tp = seltp;
1603
 
 
1604
 
        TRACE_((THIS_FILE, "Transport %s acquired", seltp->obj_name));
1605
 
        return PJ_SUCCESS;
1606
 
 
1607
 
 
1608
 
    } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
1609
 
               sel->u.listener)
1610
 
    {
1611
 
        /* Application has requested that a specific listener is to
1612
 
         * be used. In this case, skip transport hash table lookup.
1613
 
         */
1614
 
 
1615
 
        /* Verify that the listener type matches the destination type */
1616
 
        if (sel->u.listener->type != type) {
1617
 
            pj_lock_release(mgr->lock);
1618
 
            return PJSIP_ETPNOTSUITABLE;
1619
 
        }
1620
 
 
1621
 
        /* We'll use this listener to create transport */
1622
 
        factory = sel->u.listener;
1623
 
 
1624
 
    } else {
1625
 
 
1626
 
        /*
1627
 
         * This is the "normal" flow, where application doesn't specify
1628
 
         * specific transport/listener to be used to send message to.
1629
 
         * In this case, lookup the transport from the hash table.
1630
 
         */
1631
 
        pjsip_transport_key key;
1632
 
        int key_len;
1633
 
        pjsip_transport *transport;
1634
 
 
1635
 
        pj_bzero(&key, sizeof(key));
1636
 
        key_len = sizeof(key.type) + addr_len;
1637
 
 
1638
 
        /* First try to get exact destination. */
1639
 
        key.type = type;
1640
 
        pj_memcpy(&key.rem_addr, remote, addr_len);
1641
 
 
1642
 
        transport = (pjsip_transport*)
1643
 
                    pj_hash_get(mgr->table, &key, key_len, NULL);
1644
 
 
1645
 
        if (transport == NULL) {
1646
 
            unsigned flag = pjsip_transport_get_flag_from_type(type);
1647
 
            const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote;
1648
 
 
1649
 
 
1650
 
            /* Ignore address for loop transports. */
1651
 
            if (type == PJSIP_TRANSPORT_LOOP ||
1652
 
                     type == PJSIP_TRANSPORT_LOOP_DGRAM)
1653
 
            {
1654
 
                pj_sockaddr *addr = &key.rem_addr;
1655
 
 
1656
 
                pj_bzero(addr, addr_len);
1657
 
                key_len = sizeof(key.type) + addr_len;
1658
 
                transport = (pjsip_transport*)
1659
 
                            pj_hash_get(mgr->table, &key, key_len, NULL);
1660
 
            }
1661
 
            /* For datagram transports, try lookup with zero address.
1662
 
             */
1663
 
            else if (flag & PJSIP_TRANSPORT_DATAGRAM)
1664
 
            {
1665
 
                pj_sockaddr *addr = &key.rem_addr;
1666
 
 
1667
 
                pj_bzero(addr, addr_len);
1668
 
                addr->addr.sa_family = remote_addr->addr.sa_family;
1669
 
 
1670
 
                key_len = sizeof(key.type) + addr_len;
1671
 
                transport = (pjsip_transport*)
1672
 
                            pj_hash_get(mgr->table, &key, key_len, NULL);
1673
 
            }
1674
 
        }
1675
 
 
1676
 
        if (transport!=NULL && !transport->is_shutdown) {
1677
 
            /*
1678
 
             * Transport found!
1679
 
             */
1680
 
            pjsip_transport_add_ref(transport);
1681
 
            pj_lock_release(mgr->lock);
1682
 
            *tp = transport;
1683
 
 
1684
 
            TRACE_((THIS_FILE, "Transport %s acquired", transport->obj_name));
1685
 
            return PJ_SUCCESS;
1686
 
        }
1687
 
 
1688
 
        /*
1689
 
         * Transport not found!
1690
 
         * Find factory that can create such transport.
1691
 
         */
1692
 
        factory = mgr->factory_list.next;
1693
 
        while (factory != &mgr->factory_list) {
1694
 
            if (factory->type == type)
1695
 
                break;
1696
 
            factory = factory->next;
1697
 
        }
1698
 
 
1699
 
        if (factory == &mgr->factory_list) {
1700
 
            /* No factory can create the transport! */
1701
 
            pj_lock_release(mgr->lock);
1702
 
            TRACE_((THIS_FILE, "No suitable factory was found either"));
1703
 
            return PJSIP_EUNSUPTRANSPORT;
1704
 
        }
1705
 
    }
1706
 
 
1707
 
    TRACE_((THIS_FILE, "Creating new transport from factory"));
1708
 
 
1709
 
    /* Request factory to create transport. */
1710
 
    if (factory->create_transport2) {
1711
 
        status = factory->create_transport2(factory, mgr, mgr->endpt,
1712
 
                                            (const pj_sockaddr*) remote,
1713
 
                                            addr_len, tdata, tp);
1714
 
    } else {
1715
 
        status = factory->create_transport(factory, mgr, mgr->endpt,
1716
 
                                           (const pj_sockaddr*) remote,
1717
 
                                           addr_len, tp);
1718
 
    }
1719
 
    if (status == PJ_SUCCESS) {
1720
 
        PJ_ASSERT_ON_FAIL(tp!=NULL,
1721
 
            {pj_lock_release(mgr->lock); return PJ_EBUG;});
1722
 
        pjsip_transport_add_ref(*tp);
1723
 
    }
1724
 
    pj_lock_release(mgr->lock);
1725
 
    return status;
1726
 
}
1727
 
 
1728
 
/**
1729
 
 * Dump transport info.
1730
 
 */
1731
 
PJ_DEF(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr)
1732
 
{
1733
 
#if PJ_LOG_MAX_LEVEL >= 3
1734
 
    pj_hash_iterator_t itr_val;
1735
 
    pj_hash_iterator_t *itr;
1736
 
    pjsip_tpfactory *factory;
1737
 
 
1738
 
    pj_lock_acquire(mgr->lock);
1739
 
 
1740
 
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
1741
 
    PJ_LOG(3,(THIS_FILE, " Outstanding transmit buffers: %d",
1742
 
              pj_atomic_get(mgr->tdata_counter)));
1743
 
#endif
1744
 
 
1745
 
    PJ_LOG(3, (THIS_FILE, " Dumping listeners:"));
1746
 
    factory = mgr->factory_list.next;
1747
 
    while (factory != &mgr->factory_list) {
1748
 
        PJ_LOG(3, (THIS_FILE, "  %s %s:%.*s:%d",
1749
 
                   factory->obj_name,
1750
 
                   factory->type_name,
1751
 
                   (int)factory->addr_name.host.slen,
1752
 
                   factory->addr_name.host.ptr,
1753
 
                   (int)factory->addr_name.port));
1754
 
        factory = factory->next;
1755
 
    }
1756
 
 
1757
 
    itr = pj_hash_first(mgr->table, &itr_val);
1758
 
    if (itr) {
1759
 
        PJ_LOG(3, (THIS_FILE, " Dumping transports:"));
1760
 
 
1761
 
        do {
1762
 
            pjsip_transport *t = (pjsip_transport*)
1763
 
                                 pj_hash_this(mgr->table, itr);
1764
 
 
1765
 
            PJ_LOG(3, (THIS_FILE, "  %s %s (refcnt=%d%s)",
1766
 
                       t->obj_name,
1767
 
                       t->info,
1768
 
                       pj_atomic_get(t->ref_cnt),
1769
 
                       (t->idle_timer.id ? " [idle]" : "")));
1770
 
 
1771
 
            itr = pj_hash_next(mgr->table, itr);
1772
 
        } while (itr);
1773
 
    }
1774
 
 
1775
 
    pj_lock_release(mgr->lock);
1776
 
#else
1777
 
    PJ_UNUSED_ARG(mgr);
1778
 
#endif
1779
 
}
1780
 
 
1781
 
/**
1782
 
 * Set callback of global transport state notification.
1783
 
 */
1784
 
PJ_DEF(pj_status_t) pjsip_tpmgr_set_state_cb(pjsip_tpmgr *mgr,
1785
 
                                             pjsip_tp_state_callback cb)
1786
 
{
1787
 
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
1788
 
 
1789
 
    mgr->tp_state_cb = cb;
1790
 
 
1791
 
    return PJ_SUCCESS;
1792
 
}
1793
 
 
1794
 
/**
1795
 
 * Get callback of global transport state notification.
1796
 
 */
1797
 
PJ_DEF(pjsip_tp_state_callback) pjsip_tpmgr_get_state_cb(
1798
 
                                             const pjsip_tpmgr *mgr)
1799
 
{
1800
 
    PJ_ASSERT_RETURN(mgr, NULL);
1801
 
 
1802
 
    return mgr->tp_state_cb;
1803
 
}
1804
 
 
1805
 
 
1806
 
/**
1807
 
 * Allocate and init transport data.
1808
 
 */
1809
 
static void init_tp_data(pjsip_transport *tp)
1810
 
{
1811
 
    transport_data *tp_data;
1812
 
 
1813
 
    pj_assert(tp && !tp->data);
1814
 
 
1815
 
    tp_data = PJ_POOL_ZALLOC_T(tp->pool, transport_data);
1816
 
    pj_list_init(&tp_data->st_listeners);
1817
 
    pj_list_init(&tp_data->st_listeners_empty);
1818
 
    tp->data = tp_data;
1819
 
}
1820
 
 
1821
 
 
1822
 
static void tp_state_callback(pjsip_transport *tp,
1823
 
                              pjsip_transport_state state,
1824
 
                              const pjsip_transport_state_info *info)
1825
 
{
1826
 
    transport_data *tp_data;
1827
 
 
1828
 
    pj_lock_acquire(tp->lock);
1829
 
 
1830
 
    tp_data = (transport_data*)tp->data;
1831
 
 
1832
 
    /* Notify the transport state listeners, if any. */
1833
 
    if (!tp_data || pj_list_empty(&tp_data->st_listeners)) {
1834
 
        goto on_return;
1835
 
    } else {
1836
 
        pjsip_transport_state_info st_info;
1837
 
        tp_state_listener *st_listener = tp_data->st_listeners.next;
1838
 
 
1839
 
        /* As we need to put the user data into the transport state info,
1840
 
         * let's use a copy of transport state info.
1841
 
         */
1842
 
        pj_memcpy(&st_info, info, sizeof(st_info));
1843
 
        while (st_listener != &tp_data->st_listeners) {
1844
 
            st_info.user_data = st_listener->user_data;
1845
 
            (*st_listener->cb)(tp, state, &st_info);
1846
 
 
1847
 
            st_listener = st_listener->next;
1848
 
        }
1849
 
    }
1850
 
 
1851
 
on_return:
1852
 
    pj_lock_release(tp->lock);
1853
 
}
1854
 
 
1855
 
 
1856
 
/**
1857
 
 * Add a listener to the specified transport for transport state notification.
1858
 
 */
1859
 
PJ_DEF(pj_status_t) pjsip_transport_add_state_listener (
1860
 
                                            pjsip_transport *tp,
1861
 
                                            pjsip_tp_state_callback cb,
1862
 
                                            void *user_data,
1863
 
                                            pjsip_tp_state_listener_key **key)
1864
 
{
1865
 
    transport_data *tp_data;
1866
 
    tp_state_listener *entry;
1867
 
 
1868
 
    PJ_ASSERT_RETURN(tp && cb && key, PJ_EINVAL);
1869
 
 
1870
 
    pj_lock_acquire(tp->lock);
1871
 
 
1872
 
    /* Init transport data, if it hasn't */
1873
 
    if (!tp->data)
1874
 
        init_tp_data(tp);
1875
 
 
1876
 
    tp_data = (transport_data*)tp->data;
1877
 
 
1878
 
    /* Init the new listener entry. Use available empty slot, if any,
1879
 
     * otherwise allocate it using the transport pool.
1880
 
     */
1881
 
    if (!pj_list_empty(&tp_data->st_listeners_empty)) {
1882
 
        entry = tp_data->st_listeners_empty.next;
1883
 
        pj_list_erase(entry);
1884
 
    } else {
1885
 
        entry = PJ_POOL_ZALLOC_T(tp->pool, tp_state_listener);
1886
 
    }
1887
 
    entry->cb = cb;
1888
 
    entry->user_data = user_data;
1889
 
 
1890
 
    /* Add the new listener entry to the listeners list */
1891
 
    pj_list_push_back(&tp_data->st_listeners, entry);
1892
 
 
1893
 
    *key = entry;
1894
 
 
1895
 
    pj_lock_release(tp->lock);
1896
 
 
1897
 
    return PJ_SUCCESS;
1898
 
}
1899
 
 
1900
 
/**
1901
 
 * Remove a listener from the specified transport for transport state
1902
 
 * notification.
1903
 
 */
1904
 
PJ_DEF(pj_status_t) pjsip_transport_remove_state_listener (
1905
 
                                    pjsip_transport *tp,
1906
 
                                    pjsip_tp_state_listener_key *key,
1907
 
                                    const void *user_data)
1908
 
{
1909
 
    transport_data *tp_data;
1910
 
    tp_state_listener *entry;
1911
 
 
1912
 
    PJ_ASSERT_RETURN(tp && key, PJ_EINVAL);
1913
 
 
1914
 
    pj_lock_acquire(tp->lock);
1915
 
 
1916
 
    tp_data = (transport_data*)tp->data;
1917
 
 
1918
 
    /* Transport data is NULL or no registered listener? */
1919
 
    if (!tp_data || pj_list_empty(&tp_data->st_listeners)) {
1920
 
        pj_lock_release(tp->lock);
1921
 
        return PJ_ENOTFOUND;
1922
 
    }
1923
 
 
1924
 
    entry = (tp_state_listener*)key;
1925
 
 
1926
 
    /* Validate the user data */
1927
 
    if (entry->user_data != user_data) {
1928
 
        pj_assert(!"Invalid transport state listener key");
1929
 
        pj_lock_release(tp->lock);
1930
 
        return PJ_EBUG;
1931
 
    }
1932
 
 
1933
 
    /* Reset the entry and move it to the empty list */
1934
 
    entry->cb = NULL;
1935
 
    entry->user_data = NULL;
1936
 
    pj_list_erase(entry);
1937
 
    pj_list_push_back(&tp_data->st_listeners_empty, entry);
1938
 
 
1939
 
    pj_lock_release(tp->lock);
1940
 
 
1941
 
    return PJ_SUCCESS;
1942
 
}