Coverage Report

Created: 2025-10-12 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pjsip/pjmedia/include/pjmedia/transport.h
Line
Count
Source
1
/* 
2
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
3
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
 */
19
#ifndef __PJMEDIA_TRANSPORT_H__
20
#define __PJMEDIA_TRANSPORT_H__
21
22
23
/**
24
 * @file transport.h Media Transport Interface
25
 * @brief Transport interface.
26
 */
27
28
#include <pjmedia/types.h>
29
#include <pjmedia/errno.h>
30
#include <pj/string.h>
31
32
/**
33
 * @defgroup PJMEDIA_TRANSPORT Media Transport
34
 * @brief Transports.
35
 * @{
36
 * The media transport (#pjmedia_transport) is the object to send and
37
 * receive media packets over the network. The media transport interface
38
 * allows the library to be extended to support different types of 
39
 * transports to send and receive packets.
40
 *
41
 * The media transport is declared as #pjmedia_transport "class", which
42
 * declares "interfaces" to use the class in #pjmedia_transport_op
43
 * structure. For the user of the media transport (normally the user of
44
 * media transport is media stream, see \ref PJMED_STRM), these transport
45
 * "methods" are wrapped with API such as #pjmedia_transport_attach(),
46
 * so it should not need to call the function pointer inside 
47
 * #pjmedia_transport_op directly.
48
 *
49
 * The connection between \ref PJMED_STRM and media transport is shown in
50
 * the diagram below:
51
52
   \img{pjmedia/docs/media-transport.PNG}
53
54
55
 * \section PJMEDIA_TRANSPORT_H_USING Basic Media Transport Usage
56
 *
57
 * The media transport's life-cycle normally follows the following stages.
58
 *
59
 * \subsection PJMEDIA_TRANSPORT_H_CREATE Creating the Media Transport
60
 *
61
 *  Application creates the media transport when it needs to establish
62
 *    media session to remote peer. The media transport is created using
63
 *    specific function to create that particular transport; for example,
64
 *    for UDP media transport, it is created with #pjmedia_transport_udp_create()
65
 *    or #pjmedia_transport_udp_create2() functions. Different media
66
 *    transports will provide different API to create those transports.
67
 *
68
 *  Alternatively, application may create pool of media transports when
69
 *    it is first started up. Using this approach probably is better, since
70
 *    application has to specify the RTP port when sending the initial
71
 *    session establishment request (e.g. SIP INVITE request), thus if
72
 *    application only creates the media transport later when media is to be
73
 *    established (normally when 200/OK is received, or when 18x is received
74
 *    for early media), there is a possibility that the particular RTP
75
 *    port might have been occupied by other programs. Also it is more
76
 *    efficient since sockets don't need to be closed and re-opened between
77
 *    calls.
78
 *
79
 *
80
 * \subsection PJMEDIA_TRANSPORT_H_ATTACH Attaching and Using the Media Transport.
81
 *
82
 *  Application specifies the media transport instance when creating
83
 *    the media session (#pjmedia_session_create()). Alternatively, it
84
 *    may create the media stream directly with #pjmedia_stream_create()
85
 *    and specify the transport instance in the argument. (Note: media
86
 *    session is a high-level abstraction for media communications between
87
 *    two endpoints, and it may contain more than one media streams, for
88
 *    example, an audio stream and a video stream).
89
 *
90
 *  When stream is created, it will "attach" itself to the media 
91
 *    transport by calling #pjmedia_transport_attach(), which is a thin
92
 *    wrapper which calls "attach()" method of the media transport's 
93
 *    "virtual function pointer" (#pjmedia_transport_op). Among other things,
94
 *    the stream specifies two callback functions to the transport: one
95
 *    callback function will be called by transport when it receives RTP
96
 *    packet, and another callback for incoming RTCP packet. The 
97
 *    #pjmedia_transport_attach() function also establish the destination
98
 *    of the outgoing RTP and RTCP packets.
99
 *
100
 *  When the stream needs to send outgoing RTP/RTCP packets, it will
101
 *    call #pjmedia_transport_send_rtp() and #pjmedia_transport_send_rtcp()
102
 *    of the media transport API, which is a thin wrapper to call send_rtp() 
103
 *    and send_rtcp() methods in the media transport's "virtual function 
104
 *    pointer"  (#pjmedia_transport_op).
105
 *
106
 *  When the stream is destroyed, it will "detach" itself from
107
 *    the media transport by calling #pjmedia_transport_detach(), which is
108
 *    a thin wrapper which calls "detach()" method of the media transport's 
109
 *    "virtual function pointer" (#pjmedia_transport_op). After the transport
110
 *    is detached from its user (the stream), it will no longer report 
111
 *    incoming RTP/RTCP packets to the stream, and it will refuse to send
112
 *    outgoing packets since the destination has been cleared.
113
 *
114
 *
115
 * \subsection PJMEDIA_TRANSPORT_H_REUSE Reusing the Media Transport.
116
 *
117
 *  After transport has been detached, application may re-attach the
118
 *    transport to another stream if it wants to. Detaching and re-attaching
119
 *    media transport may be preferable than closing and re-opening the
120
 *    transport, since it is more efficient (sockets don't need to be
121
 *    closed and re-opened). However it is up to the application to choose
122
 *    which method is most suitable for its uses.
123
 *
124
 * 
125
 * \subsection PJMEDIA_TRANSPORT_H_DESTROY Destroying the Media Transport.
126
 *
127
 *  Finally if application no longer needs the media transport, it will
128
 *    call #pjmedia_transport_close() function, which is thin wrapper which 
129
 *    calls "destroy()" method of the media transport's  "virtual function 
130
 *    pointer" (#pjmedia_transport_op). This function releases
131
 *    all resources used by the transport, such as sockets and memory.
132
 *
133
 *
134
 * \section offer_answer Interaction with SDP Offer/Answer
135
 
136
   For basic UDP transport, the \ref PJMEDIA_TRANSPORT_H_USING above is
137
   sufficient to use the media transport. However, more complex media
138
   transports such as \ref PJMEDIA_TRANSPORT_SRTP and \ref
139
   PJMEDIA_TRANSPORT_ICE requires closer interactions with SDP offer and
140
   answer negotiation.
141
142
   The media transports can interact with the SDP offer/answer via
143
   these APIs:
144
     - #pjmedia_transport_media_create(), to initialize the media transport
145
       for new media session,
146
     - #pjmedia_transport_encode_sdp(), to encode SDP offer or answer,
147
     - #pjmedia_transport_media_start(), to activate the settings that
148
       have been negotiated by SDP offer answer, and
149
     - #pjmedia_transport_media_stop(), to deinitialize the media transport
150
       and reset the transport to its idle state.
151
   
152
   The usage of these API in the context of SDP offer answer will be 
153
   described below.
154
155
   \subsection media_create Initializing Transport for New Session
156
157
   Application must call #pjmedia_transport_media_create() before using
158
   the transport for a new session.
159
160
   \subsection creat_oa Creating SDP Offer and Answer
161
162
   The #pjmedia_transport_encode_sdp() is used to put additional information
163
   from the transport to the local SDP, before the SDP is sent and negotiated
164
   with remote SDP.
165
166
   When creating an offer, call #pjmedia_transport_encode_sdp() with
167
   local SDP (and NULL as \a rem_sdp). The media transport will add the
168
   relevant attributes in the local SDP. Application then gives the local
169
   SDP to the invite session to be sent to remote agent.
170
171
   When creating an answer, also call #pjmedia_transport_encode_sdp(),
172
   but this time specify both local and remote SDP to the function. The 
173
   media transport will once again modify the local SDP and add relevant
174
   attributes to the local SDP, if the appropriate attributes related to
175
   the transport functionality are present in remote offer. The remote
176
   SDP does not contain the relevant attributes, then the specific transport
177
   functionality will not be activated for the session.
178
179
   The #pjmedia_transport_encode_sdp() should also be called when application
180
   sends subsequent SDP offer or answer. The media transport will encode
181
   the appropriate attributes based on the state of the session.
182
183
   \subsection media_start Offer/Answer Completion
184
185
   Once both local and remote SDP have been negotiated by the 
186
   \ref PJMEDIA_SDP_NEG (normally this is part of PJSIP invite session),
187
   application should give both local and remote SDP to 
188
   #pjmedia_transport_media_start() so that the settings are activated
189
   for the session. This function should be called for both initial and
190
   subsequent SDP negotiation.
191
192
   \subsection media_stop Stopping Transport
193
194
   Once session is stop application must call #pjmedia_transport_media_stop()
195
   to deactivate the transport feature. Application may reuse the transport
196
   for subsequent media session by repeating the #pjmedia_transport_media_create(),
197
   #pjmedia_transport_encode_sdp(), #pjmedia_transport_media_start(), and
198
   #pjmedia_transport_media_stop() above.
199
200
 * \section PJMEDIA_TRANSPORT_H_IMPL Implementing Media Transport
201
 *
202
 * To implement a new type of media transport, one needs to "subclass" the
203
 * media transport "class" (#pjmedia_transport) by providing the "methods"
204
 * in the media transport "interface" (#pjmedia_transport_op), and provides
205
 * a function to create this new type of transport (similar to 
206
 * #pjmedia_transport_udp_create() function).
207
 *
208
 * The media transport is expected to run indepently, that is there should
209
 * be no polling like function to poll the transport for incoming RTP/RTCP
210
 * packets. This normally can be done by registering the media sockets to
211
 * the media endpoint's IOQueue, which allows the transport to be notified
212
 * when incoming packet has arrived.
213
 *
214
 * Alternatively, media transport may utilize thread(s) internally to wait
215
 * for incoming packets. The thread then will call the appropriate RTP or
216
 * RTCP callback provided by its user (stream) whenever packet is received.
217
 * If the transport's user is a stream, then the callbacks provided by the
218
 * stream will be thread-safe, so the transport may call these callbacks
219
 * without having to serialize the access with some mutex protection. But
220
 * the media transport may still have to protect its internal data with
221
 * mutex protection, since it may be called by application's thread (for
222
 * example, to send RTP/RTCP packets).
223
 *
224
 */
225
226
227
#include <pjmedia/sdp.h>
228
229
PJ_BEGIN_DECL
230
231
232
/**
233
 * Forward declaration for media transport.
234
 */
235
typedef struct pjmedia_transport pjmedia_transport;
236
237
/**
238
 * Forward declaration for media transport info.
239
 */
240
typedef struct pjmedia_transport_info pjmedia_transport_info;
241
242
/**
243
 * Forward declaration for media transport attach param.
244
 */
245
typedef struct pjmedia_transport_attach_param pjmedia_transport_attach_param;
246
247
/**
248
 * This enumeration specifies the general behaviour of media processing
249
 */
250
typedef enum pjmedia_tranport_media_option
251
{
252
    /**
253
     * When this flag is specified, the transport will not perform media
254
     * transport validation, this is useful when transport is stacked with
255
     * other transport, for example when transport UDP is stacked under
256
     * transport SRTP, media transport validation only need to be done by 
257
     * transport SRTP.
258
     */
259
    PJMEDIA_TPMED_NO_TRANSPORT_CHECKING = 1,
260
261
    /**
262
     * When this flag is specified, the transport will allow multiplexing
263
     * RTP and RTCP, i.e. if the remote agrees, RTCP will be sent using
264
     * the same socket for RTP.
265
     */
266
    PJMEDIA_TPMED_RTCP_MUX = 2
267
268
} pjmedia_tranport_media_option;
269
270
271
/**
272
 * Media socket info is used to describe the underlying sockets
273
 * to be used as media transport.
274
 */
275
typedef struct pjmedia_sock_info
276
{
277
    /** The RTP socket handle */
278
    pj_sock_t       rtp_sock;
279
280
    /** Address to be advertised as the local address for the RTP
281
     *  socket, which does not need to be equal as the bound
282
     *  address (for example, this address can be the address resolved
283
     *  with STUN).
284
     */
285
    pj_sockaddr     rtp_addr_name;
286
287
    /** The RTCP socket handle. */
288
    pj_sock_t       rtcp_sock;
289
290
    /** Address to be advertised as the local address for the RTCP
291
     *  socket, which does not need to be equal as the bound
292
     *  address (for example, this address can be the address resolved
293
     *  with STUN).
294
     */
295
    pj_sockaddr     rtcp_addr_name;
296
297
} pjmedia_sock_info;
298
299
300
/**
301
 * This structure describes the operations for the stream transport.
302
 */
303
struct pjmedia_transport_op
304
{
305
    /**
306
     * Get media socket info from the specified transport.
307
     *
308
     * Application should call #pjmedia_transport_get_info() instead
309
     */
310
    pj_status_t (*get_info)(pjmedia_transport *tp,
311
                            pjmedia_transport_info *info);
312
313
    /**
314
     * This function is called by the stream when the transport is about
315
     * to be used by the stream for the first time, and it tells the transport
316
     * about remote RTP address to send the packet and some callbacks to be 
317
     * called for incoming packets. This function exists for backwards
318
     * compatibility. Transports should implement attach2 instead.
319
     *
320
     * Application should call #pjmedia_transport_attach() instead of 
321
     * calling this function directly.
322
     */
323
    pj_status_t (*attach)(pjmedia_transport *tp,
324
                          void *user_data,
325
                          const pj_sockaddr_t *rem_addr,
326
                          const pj_sockaddr_t *rem_rtcp,
327
                          unsigned addr_len,
328
                          void (*rtp_cb)(void *user_data,
329
                                         void *pkt,
330
                                         pj_ssize_t size),
331
                          void (*rtcp_cb)(void *user_data,
332
                                          void *pkt,
333
                                          pj_ssize_t size));
334
335
    /**
336
     * This function is called by the stream when the stream no longer
337
     * needs the transport (normally when the stream is about to be closed).
338
     * After the transport is detached, it will ignore incoming
339
     * RTP/RTCP packets, and will refuse to send outgoing RTP/RTCP packets.
340
     * Application may re-attach the media transport to another transport 
341
     * user (e.g. stream) after the transport has been detached.
342
     *
343
     * Application should call #pjmedia_transport_detach() instead of 
344
     * calling this function directly.
345
     */
346
    void (*detach)(pjmedia_transport *tp,
347
                   void *user_data);
348
349
    /**
350
     * This function is called by the stream to send RTP packet using the 
351
     * transport.
352
     *
353
     * Application should call #pjmedia_transport_send_rtp() instead of 
354
     * calling this function directly.
355
     */
356
    pj_status_t (*send_rtp)(pjmedia_transport *tp,
357
                            const void *pkt,
358
                            pj_size_t size);
359
360
    /**
361
     * This function is called by the stream to send RTCP packet using the
362
     * transport.
363
     *
364
     * Application should call #pjmedia_transport_send_rtcp() instead of 
365
     * calling this function directly.
366
     */
367
    pj_status_t (*send_rtcp)(pjmedia_transport *tp,
368
                             const void *pkt,
369
                             pj_size_t size);
370
371
    /**
372
     * This function is called by the stream to send RTCP packet using the
373
     * transport with destination address other than default specified in
374
     * #pjmedia_transport_attach().
375
     *
376
     * Application should call #pjmedia_transport_send_rtcp2() instead of 
377
     * calling this function directly.
378
     */
379
    pj_status_t (*send_rtcp2)(pjmedia_transport *tp,
380
                              const pj_sockaddr_t *addr,
381
                              unsigned addr_len,
382
                              const void *pkt,
383
                              pj_size_t size);
384
385
    /**
386
     * Prepare the transport for a new media session.
387
     *
388
     * Application should call #pjmedia_transport_media_create() instead of 
389
     * calling this function directly.
390
     */
391
    pj_status_t (*media_create)(pjmedia_transport *tp,
392
                                pj_pool_t *sdp_pool,
393
                                unsigned options,
394
                                const pjmedia_sdp_session *remote_sdp,
395
                                unsigned media_index);
396
397
    /**
398
     * This function is called by application to generate the SDP parts
399
     * related to transport type, e.g: ICE, SRTP.
400
     *
401
     * Application should call #pjmedia_transport_encode_sdp() instead of
402
     * calling this function directly.
403
     */
404
    pj_status_t (*encode_sdp)(pjmedia_transport *tp,
405
                              pj_pool_t *sdp_pool,
406
                              pjmedia_sdp_session *sdp_local,
407
                              const pjmedia_sdp_session *rem_sdp,
408
                              unsigned media_index);
409
410
    /**
411
     * This function is called by application to start the transport
412
     * based on local and remote SDP.
413
     *
414
     * Application should call #pjmedia_transport_media_start() instead of 
415
     * calling this function directly.
416
     */
417
    pj_status_t (*media_start) (pjmedia_transport *tp,
418
                                pj_pool_t *tmp_pool,
419
                                const pjmedia_sdp_session *sdp_local,
420
                                const pjmedia_sdp_session *sdp_remote,
421
                                unsigned media_index);
422
423
    /**
424
     * This function is called by application to stop the transport.
425
     *
426
     * Application should call #pjmedia_transport_media_stop() instead of 
427
     * calling this function directly.
428
     */
429
    pj_status_t (*media_stop)  (pjmedia_transport *tp);
430
431
    /**
432
     * This function can be called to simulate packet lost.
433
     *
434
     * Application should call #pjmedia_transport_simulate_lost() instead of 
435
     * calling this function directly.
436
     */
437
    pj_status_t (*simulate_lost)(pjmedia_transport *tp,
438
                                 pjmedia_dir dir,
439
                                 unsigned pct_lost);
440
441
    /**
442
     * This function can be called to destroy this transport.
443
     *
444
     * Application should call #pjmedia_transport_close() instead of 
445
     * calling this function directly.
446
     */
447
    pj_status_t (*destroy)(pjmedia_transport *tp);
448
449
    /**
450
     * This function is called by the stream when the transport is about
451
     * to be used by the stream for the first time, and it tells the transport
452
     * about remote RTP address to send the packet and some callbacks to be
453
     * called for incoming packets.
454
     *
455
     * Application should call #pjmedia_transport_attach2() instead of
456
     * calling this function directly.
457
     */
458
    pj_status_t (*attach2)(pjmedia_transport *tp,
459
                           pjmedia_transport_attach_param *att_param);
460
};
461
462
463
/**
464
 * @see pjmedia_transport_op.
465
 */
466
typedef struct pjmedia_transport_op pjmedia_transport_op;
467
468
469
/** 
470
 * Media transport type.
471
 */
472
typedef enum pjmedia_transport_type
473
{
474
    /** Media transport using standard UDP */
475
    PJMEDIA_TRANSPORT_TYPE_UDP,
476
477
    /** Media transport using ICE */
478
    PJMEDIA_TRANSPORT_TYPE_ICE,
479
480
    /** 
481
     * Media transport SRTP, this transport is actually security adapter to be
482
     * stacked with other transport to enable encryption on the underlying
483
     * transport.
484
     */
485
    PJMEDIA_TRANSPORT_TYPE_SRTP,
486
487
    /** Loopback media transport */
488
    PJMEDIA_TRANSPORT_TYPE_LOOP,
489
490
    /**
491
     * Start of user defined transport.
492
     */
493
    PJMEDIA_TRANSPORT_TYPE_USER
494
495
} pjmedia_transport_type;
496
497
498
/**
499
 * This structure declares media transport. A media transport is called
500
 * by the stream to transmit a packet, and will notify stream when
501
 * incoming packet is arrived.
502
 */
503
struct pjmedia_transport
504
{
505
    /** Transport name (for logging purpose). */
506
    char                     name[PJ_MAX_OBJ_NAME];
507
508
    /** Transport type. */
509
    pjmedia_transport_type   type;
510
511
    /** Transport's "virtual" function table. */
512
    pjmedia_transport_op    *op;
513
514
    /** Application/user data */
515
    void                    *user_data;
516
517
    /** Group lock, for synchronization between destroy() & callbacks. */
518
    pj_grp_lock_t           *grp_lock;
519
};
520
521
/**
522
 * This structure describes storage buffer of transport specific info.
523
 * The actual transport specific info contents will be defined by transport
524
 * implementation. Note that some transport implementations do not need to
525
 * provide specific info, since the general socket info is enough.
526
 */
527
typedef struct pjmedia_transport_specific_info
528
{
529
    /**
530
     * Specify media transport type.
531
     */
532
    pjmedia_transport_type   type;
533
534
    /**
535
     * Specify storage buffer size of transport specific info.
536
     */
537
    int                      cbsize;
538
539
    /**
540
     * Storage buffer of transport specific info.
541
     */
542
    char                     buffer[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE];
543
544
    /**
545
     * The media transport instance.
546
     */
547
    pjmedia_transport       *tp;
548
549
} pjmedia_transport_specific_info;
550
551
552
/**
553
 * This structure describes transport informations, including general 
554
 * socket information and specific information of single transport or 
555
 * stacked transports (e.g: SRTP stacked on top of UDP)
556
 */
557
struct pjmedia_transport_info
558
{
559
    /**
560
     * General socket info.
561
     */
562
    pjmedia_sock_info sock_info;
563
564
    /**
565
     * Remote address where RTP/RTCP originated from. In case this transport
566
     * hasn't ever received packet, the address can be invalid (zero).
567
     */
568
    pj_sockaddr     src_rtp_name;
569
    pj_sockaddr     src_rtcp_name;
570
571
    /**
572
     * Specifies number of transport specific info included.
573
     */
574
    unsigned specific_info_cnt;
575
576
    /**
577
     * Buffer storage of transport specific info.
578
     */
579
    pjmedia_transport_specific_info spc_info[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT];
580
581
};
582
583
/**
584
 * This structure describes the data passed when calling #rtp_cb2().
585
 */
586
typedef struct pjmedia_tp_cb_param
587
{
588
    /**
589
     * User data.
590
     */
591
    void               *user_data;
592
593
    /**
594
     * Packet buffer.
595
     */
596
    void               *pkt;
597
598
    /**
599
     * Packet size.
600
     */
601
    pj_ssize_t          size;
602
603
    /**
604
     * Packet's source address.
605
     */
606
    pj_sockaddr        *src_addr;
607
608
    /**
609
     * Should media transport switch remote address to \a rtp_src_addr?
610
     * Media transport should initialize it to PJ_FALSE, and application
611
     * can change the value as necessary.
612
     */
613
    pj_bool_t           rem_switch;
614
615
} pjmedia_tp_cb_param;
616
617
/**
618
 * This structure describes the data passed when calling
619
 * #pjmedia_transport_attach2().
620
 */
621
struct pjmedia_transport_attach_param
622
{
623
    /**
624
     * The media stream.
625
     */
626
    void *stream;
627
628
    /**
629
     * Indicate the stream type, either it's audio (PJMEDIA_TYPE_AUDIO) 
630
     * or video (PJMEDIA_TYPE_VIDEO).
631
     */
632
    pjmedia_type media_type;
633
634
    /**
635
     * Remote RTP address to send RTP packet to.
636
     */
637
    pj_sockaddr rem_addr;
638
639
    /**
640
     * Optional remote RTCP address. If the argument is NULL
641
     * or if the address is zero, the RTCP address will be
642
     * calculated from the RTP address (which is RTP port plus one).
643
     */
644
    pj_sockaddr rem_rtcp;
645
646
    /**
647
     * Length of the remote address.
648
     */
649
    unsigned addr_len;
650
651
    /**
652
     * Arbitrary user data to be set when the callbacks are called.
653
     */
654
    void *user_data;
655
656
    /**
657
     * Callback to be called when RTP packet is received on the transport.
658
     */
659
    void (*rtp_cb)(void *user_data, void *pkt, pj_ssize_t);
660
661
    /**
662
     * Callback to be called when RTCP packet is received on the transport.
663
     */
664
    void (*rtcp_cb)(void *user_data, void *pkt, pj_ssize_t);
665
666
    /**
667
     * Callback to be called when RTP packet is received on the transport.
668
     */
669
    void (*rtp_cb2)(pjmedia_tp_cb_param *param);
670
671
};
672
673
/**
674
 * Initialize transport info.
675
 *
676
 * @param info      Transport info to be initialized.
677
 */
678
PJ_INLINE(void) pjmedia_transport_info_init(pjmedia_transport_info *info)
679
0
{
680
0
    pj_bzero(info, sizeof(pjmedia_transport_info));
681
0
    info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET;
682
0
}
683
684
685
/**
686
 * Get media transport info from the specified transport and all underlying 
687
 * transports if any. The transport also contains information about socket info
688
 * which describes the local address of the transport, and would be needed
689
 * for example to fill in the "c=" and "m=" line of local SDP.
690
 *
691
 * @param tp        The transport.
692
 * @param info      Media transport info to be initialized.
693
 *
694
 * @return          PJ_SUCCESS on success.
695
 */
696
PJ_INLINE(pj_status_t) pjmedia_transport_get_info(pjmedia_transport *tp,
697
                                                  pjmedia_transport_info *info)
698
0
{
699
0
    if (tp && tp->op && tp->op->get_info)
700
0
        return (*tp->op->get_info)(tp, info);
701
0
    
702
0
    return PJ_ENOTSUP;
703
0
}
704
705
706
/**
707
 * Utility API to get transport type specific info from the specified media
708
 * transport info.
709
 * 
710
 * @param info      Media transport info.
711
 * @param type      Media transport type.
712
 *
713
 * @return          Pointer to media transport specific info, or NULL if
714
 *                  specific info for the transport type is not found.
715
 */
716
PJ_INLINE(void*) pjmedia_transport_info_get_spc_info(
717
                                                pjmedia_transport_info *info,
718
                                                pjmedia_transport_type type)
719
0
{
720
0
    unsigned i;
721
0
    for (i = 0; i < info->specific_info_cnt; ++i) {
722
0
        if (info->spc_info[i].type == type)
723
0
            return (void*)info->spc_info[i].buffer;
724
0
    }
725
0
    return NULL;
726
0
}
727
728
729
/**
730
 * Utility API to get the transport instance from the specified media
731
 * transport info.
732
 *
733
 * @param info      Media transport info.
734
 * @param type      Media transport type.
735
 *
736
 * @return          The media transport instance, or NULL if
737
 *                  the transport type is not found.
738
 */
739
PJ_INLINE(pjmedia_transport*) pjmedia_transport_info_get_transport(
740
                                                pjmedia_transport_info *info,
741
                                                pjmedia_transport_type type)
742
0
{
743
0
    unsigned i;
744
0
    for (i = 0; i < info->specific_info_cnt; ++i) {
745
0
        if (info->spc_info[i].type == type)
746
0
            return info->spc_info[i].tp;
747
0
    }
748
0
    return NULL;
749
0
}
750
751
752
/**
753
 * Attach callbacks to be called on receipt of incoming RTP/RTCP packets.
754
 * This is just a simple wrapper which calls <tt>attach2()</tt> member of
755
 * the transport if it is implemented, otherwise it calls <tt>attach()</tt>
756
 * member of the transport.
757
 *
758
 * @param tp        The media transport.
759
 * @param att_param The transport attach param.
760
 *
761
 * @return          PJ_SUCCESS on success, or the appropriate error code.
762
 */
763
PJ_INLINE(pj_status_t) pjmedia_transport_attach2(pjmedia_transport *tp,
764
                                  pjmedia_transport_attach_param *att_param)
765
0
{
766
0
    if (tp->op->attach2) {
767
0
        return (*tp->op->attach2)(tp, att_param);
768
0
    } else {
769
0
        return (*tp->op->attach)(tp, att_param->user_data, 
770
0
                                 (pj_sockaddr_t*)&att_param->rem_addr, 
771
0
                                 (pj_sockaddr_t*)&att_param->rem_rtcp, 
772
0
                                 att_param->addr_len, att_param->rtp_cb, 
773
0
                                 att_param->rtcp_cb);
774
0
    }
775
0
}
776
777
778
/**
779
 * Attach callbacks to be called on receipt of incoming RTP/RTCP packets.
780
 * This is just a simple wrapper which calls <tt>attach()</tt> member of 
781
 * the transport.
782
 *
783
 * @param tp        The media transport.
784
 * @param user_data Arbitrary user data to be set when the callbacks are 
785
 *                  called.
786
 * @param rem_addr  Remote RTP address to send RTP packet to.
787
 * @param rem_rtcp  Optional remote RTCP address. If the argument is NULL
788
 *                  or if the address is zero, the RTCP address will be
789
 *                  calculated from the RTP address (which is RTP port
790
 *                  plus one).
791
 * @param addr_len  Length of the remote address.
792
 * @param rtp_cb    Callback to be called when RTP packet is received on
793
 *                  the transport.
794
 * @param rtcp_cb   Callback to be called when RTCP packet is received on
795
 *                  the transport.
796
 *
797
 * @return          PJ_SUCCESS on success, or the appropriate error code.
798
 */
799
PJ_INLINE(pj_status_t) pjmedia_transport_attach(pjmedia_transport *tp,
800
                                                void *user_data,
801
                                                const pj_sockaddr_t *rem_addr,
802
                                                const pj_sockaddr_t *rem_rtcp,
803
                                                unsigned addr_len,
804
                                                void (*rtp_cb)(void *user_data,
805
                                                               void *pkt,
806
                                                               pj_ssize_t),
807
                                                void (*rtcp_cb)(void *usr_data,
808
                                                                void*pkt,
809
                                                                pj_ssize_t))
810
0
{
811
0
    if (tp->op->attach2) {
812
0
        pjmedia_transport_attach_param param;
813
0
814
0
        pj_bzero(&param, sizeof(param));
815
0
        param.user_data = user_data;
816
0
        pj_sockaddr_cp(&param.rem_addr, rem_addr);
817
0
        if (rem_rtcp && pj_sockaddr_has_addr(rem_rtcp)) {
818
0
            pj_sockaddr_cp(&param.rem_rtcp, rem_rtcp);
819
0
        } else {
820
0
            /* Copy RTCP address from the RTP address, with port + 1 */
821
0
            pj_memcpy(&param.rem_rtcp, rem_addr, addr_len);
822
0
            pj_sockaddr_set_port(&param.rem_rtcp,
823
0
                                 pj_sockaddr_get_port(rem_addr) + 1);
824
0
        }
825
0
        param.addr_len = addr_len;
826
0
        param.rtp_cb = rtp_cb;
827
0
        param.rtcp_cb = rtcp_cb;
828
0
829
0
        return (*tp->op->attach2)(tp, &param);
830
0
    } else {
831
0
        return (*tp->op->attach)(tp, user_data, rem_addr, rem_rtcp, addr_len,
832
0
                                 rtp_cb, rtcp_cb);
833
0
    }
834
0
}
835
836
837
/**
838
 * Detach callbacks from the transport.
839
 * This is just a simple wrapper which calls <tt>detach()</tt> member of 
840
 * the transport. After the transport is detached, it will ignore incoming
841
 * RTP/RTCP packets, and will refuse to send outgoing RTP/RTCP packets.
842
 * Application may re-attach the media transport to another transport user
843
 * (e.g. stream) after the transport has been detached.
844
 *
845
 * @param tp        The media transport.
846
 * @param user_data User data which must match the previously set value
847
 *                  on attachment.
848
 */
849
PJ_INLINE(void) pjmedia_transport_detach(pjmedia_transport *tp,
850
                                         void *user_data)
851
0
{
852
0
    (*tp->op->detach)(tp, user_data);
853
0
}
854
855
856
/**
857
 * Send RTP packet with the specified media transport. This is just a simple
858
 * wrapper which calls <tt>send_rtp()</tt> member of the transport. The 
859
 * RTP packet will be delivered to the destination address specified in
860
 * #pjmedia_transport_attach() function.
861
 *
862
 * @param tp        The media transport.
863
 * @param pkt       The packet to send.
864
 * @param size      Size of the packet.
865
 *
866
 * @return          PJ_SUCCESS on success, or the appropriate error code.
867
 */
868
PJ_INLINE(pj_status_t) pjmedia_transport_send_rtp(pjmedia_transport *tp,
869
                                                  const void *pkt,
870
                                                  pj_size_t size)
871
0
{
872
0
    return (*tp->op->send_rtp)(tp, pkt, size);
873
0
}
874
875
876
/**
877
 * Send RTCP packet with the specified media transport. This is just a simple
878
 * wrapper which calls <tt>send_rtcp()</tt> member of the transport. The 
879
 * RTCP packet will be delivered to the destination address specified in
880
 * #pjmedia_transport_attach() function.
881
 *
882
 * @param tp        The media transport.
883
 * @param pkt       The packet to send.
884
 * @param size      Size of the packet.
885
 *
886
 * @return          PJ_SUCCESS on success, or the appropriate error code.
887
 */
888
PJ_INLINE(pj_status_t) pjmedia_transport_send_rtcp(pjmedia_transport *tp,
889
                                                  const void *pkt,
890
                                                  pj_size_t size)
891
0
{
892
0
    return (*tp->op->send_rtcp)(tp, pkt, size);
893
0
}
894
895
896
/**
897
 * Send RTCP packet with the specified media transport. This is just a simple
898
 * wrapper which calls <tt>send_rtcp2()</tt> member of the transport. The 
899
 * RTCP packet will be delivered to the destination address specified in
900
 * param addr, if addr is NULL, RTCP packet will be delivered to destination 
901
 * address specified in #pjmedia_transport_attach() function.
902
 *
903
 * @param tp        The media transport.
904
 * @param addr      The destination address.
905
 * @param addr_len  Length of destination address.
906
 * @param pkt       The packet to send.
907
 * @param size      Size of the packet.
908
 *
909
 * @return          PJ_SUCCESS on success, or the appropriate error code.
910
 */
911
PJ_INLINE(pj_status_t) pjmedia_transport_send_rtcp2(pjmedia_transport *tp,
912
                                                    const pj_sockaddr_t *addr,
913
                                                    unsigned addr_len,
914
                                                    const void *pkt,
915
                                                    pj_size_t size)
916
0
{
917
0
    return (*tp->op->send_rtcp2)(tp, addr, addr_len, pkt, size);
918
0
}
919
920
921
/**
922
 * Prepare the media transport for a new media session, Application must
923
 * call this function before starting a new media session using this
924
 * transport.
925
 *
926
 * This is just a simple wrapper which calls <tt>media_create()</tt> member 
927
 * of the transport.
928
 *
929
 * @param tp            The media transport.
930
 * @param sdp_pool      Pool object to allocate memory related to SDP
931
 *                      messaging components.
932
 * @param options       Option flags, from #pjmedia_tranport_media_option
933
 * @param rem_sdp       Remote SDP if local SDP is an answer, otherwise
934
 *                      specify NULL if SDP is an offer.
935
 * @param media_index   Media index in SDP.
936
 *
937
 * @return              PJ_SUCCESS on success, or the appropriate error code.
938
 */
939
PJ_INLINE(pj_status_t) pjmedia_transport_media_create(pjmedia_transport *tp,
940
                                    pj_pool_t *sdp_pool,
941
                                    unsigned options,
942
                                    const pjmedia_sdp_session *rem_sdp,
943
                                    unsigned media_index)
944
0
{
945
0
    return (*tp->op->media_create)(tp, sdp_pool, options, rem_sdp, 
946
0
                                   media_index);
947
0
}
948
949
950
/**
951
 * Put transport specific information into the SDP. This function can be
952
 * called to put transport specific information in the initial or
953
 * subsequent SDP offer or answer.
954
 *
955
 * This is just a simple wrapper which calls <tt>encode_sdp()</tt> member 
956
 * of the transport.
957
 *
958
 * @param tp            The media transport.
959
 * @param sdp_pool      Pool object to allocate memory related to SDP
960
 *                      messaging components.
961
 * @param sdp           The local SDP to be filled in information from the
962
 *                      media transport.
963
 * @param rem_sdp       Remote SDP if local SDP is an answer, otherwise
964
 *                      specify NULL if SDP is an offer.
965
 * @param media_index   Media index in SDP.
966
 *
967
 * @return              PJ_SUCCESS on success, or the appropriate error code.
968
 */
969
PJ_INLINE(pj_status_t) pjmedia_transport_encode_sdp(pjmedia_transport *tp,
970
                                            pj_pool_t *sdp_pool,
971
                                            pjmedia_sdp_session *sdp,
972
                                            const pjmedia_sdp_session *rem_sdp,
973
                                            unsigned media_index)
974
0
{
975
0
    return (*tp->op->encode_sdp)(tp, sdp_pool, sdp, rem_sdp, media_index);
976
0
}
977
978
979
/**
980
 * Start the transport session with the settings in both local and remote 
981
 * SDP. The actual work that is done by this function depends on the 
982
 * underlying transport type. For SRTP, this will activate the encryption
983
 * and decryption based on the keys found the SDPs. For ICE, this will
984
 * start ICE negotiation according to the information found in the SDPs.
985
 *
986
 * This is just a simple wrapper which calls <tt>media_start()</tt> member 
987
 * of the transport.
988
 *
989
 * @param tp            The media transport.
990
 * @param tmp_pool      The memory pool for allocating temporary objects.
991
 * @param sdp_local     Local SDP.
992
 * @param sdp_remote    Remote SDP.
993
 * @param media_index   Media index in the SDP.
994
 *
995
 * @return              PJ_SUCCESS on success, or the appropriate error code.
996
 */
997
PJ_INLINE(pj_status_t) pjmedia_transport_media_start(pjmedia_transport *tp,
998
                                    pj_pool_t *tmp_pool,
999
                                    const pjmedia_sdp_session *sdp_local,
1000
                                    const pjmedia_sdp_session *sdp_remote,
1001
                                    unsigned media_index)
1002
0
{
1003
0
    return (*tp->op->media_start)(tp, tmp_pool, sdp_local, sdp_remote, 
1004
0
                                  media_index);
1005
0
}
1006
1007
1008
/**
1009
 * This API should be called when the session is stopped, to allow the media
1010
 * transport to release its resources used for the session.
1011
 *
1012
 * This is just a simple wrapper which calls <tt>media_stop()</tt> member 
1013
 * of the transport.
1014
 *
1015
 * @param tp            The media transport.
1016
 *
1017
 * @return              PJ_SUCCESS on success, or the appropriate error code.
1018
 */
1019
PJ_INLINE(pj_status_t) pjmedia_transport_media_stop(pjmedia_transport *tp)
1020
0
{
1021
0
    return (*tp->op->media_stop)(tp);
1022
0
}
1023
1024
/**
1025
 * Close media transport. This is just a simple wrapper which calls 
1026
 * <tt>destroy()</tt> member of the transport. This function will free
1027
 * all resources created by this transport (such as sockets, memory, etc.).
1028
 *
1029
 * @param tp        The media transport.
1030
 *
1031
 * @return          PJ_SUCCESS on success, or the appropriate error code.
1032
 */
1033
PJ_INLINE(pj_status_t) pjmedia_transport_close(pjmedia_transport *tp)
1034
0
{
1035
0
    if (tp->op->destroy)
1036
0
        return (*tp->op->destroy)(tp);
1037
0
    else
1038
0
        return PJ_SUCCESS;
1039
0
}
1040
1041
/**
1042
 * Simulate packet lost in the specified direction (for testing purposes).
1043
 * When enabled, the transport will randomly drop packets to the specified
1044
 * direction.
1045
 *
1046
 * @param tp        The media transport.
1047
 * @param dir       Media direction to which packets will be randomly dropped.
1048
 * @param pct_lost  Percent lost (0-100). Set to zero to disable packet
1049
 *                  lost simulation.
1050
 *
1051
 * @return          PJ_SUCCESS on success.
1052
 */
1053
PJ_INLINE(pj_status_t) pjmedia_transport_simulate_lost(pjmedia_transport *tp,
1054
                                                       pjmedia_dir dir,
1055
                                                       unsigned pct_lost)
1056
0
{
1057
0
    return (*tp->op->simulate_lost)(tp, dir, pct_lost);
1058
0
}
1059
1060
1061
PJ_END_DECL
1062
1063
/**
1064
 * @}
1065
 */
1066
1067
1068
#endif  /* __PJMEDIA_TRANSPORT_H__ */
1069