/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(¶m, sizeof(param)); |
815 | 0 | param.user_data = user_data; |
816 | 0 | pj_sockaddr_cp(¶m.rem_addr, rem_addr); |
817 | 0 | if (rem_rtcp && pj_sockaddr_has_addr(rem_rtcp)) { |
818 | 0 | pj_sockaddr_cp(¶m.rem_rtcp, rem_rtcp); |
819 | 0 | } else { |
820 | 0 | /* Copy RTCP address from the RTP address, with port + 1 */ |
821 | 0 | pj_memcpy(¶m.rem_rtcp, rem_addr, addr_len); |
822 | 0 | pj_sockaddr_set_port(¶m.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, ¶m); |
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 | | |