rtp_engine: rtcp_report_to_json can overflow the ssrc integer value
[asterisk/asterisk.git] / main / rtp_engine.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Pluggable RTP Architecture
22  *
23  * \author Joshua Colp <jcolp@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28 ***/
29
30 /*** DOCUMENTATION
31         <managerEvent language="en_US" name="RTCPSent">
32                 <managerEventInstance class="EVENT_FLAG_REPORTING">
33                         <synopsis>Raised when an RTCP packet is sent.</synopsis>
34                         <syntax>
35                                 <channel_snapshot/>
36                                 <parameter name="SSRC">
37                                         <para>The SSRC identifier for our stream</para>
38                                 </parameter>
39                                 <parameter name="PT">
40                                         <para>The type of packet for this RTCP report.</para>
41                                         <enumlist>
42                                                 <enum name="200(SR)"/>
43                                                 <enum name="201(RR)"/>
44                                         </enumlist>
45                                 </parameter>
46                                 <parameter name="To">
47                                         <para>The address the report is sent to.</para>
48                                 </parameter>
49                                 <parameter name="ReportCount">
50                                         <para>The number of reports that were sent.</para>
51                                         <para>The report count determines the number of ReportX headers in
52                                         the message. The X for each set of report headers will range from 0 to
53                                         <literal>ReportCount - 1</literal>.</para>
54                                 </parameter>
55                                 <parameter name="SentNTP" required="false">
56                                         <para>The time the sender generated the report. Only valid when
57                                         PT is <literal>200(SR)</literal>.</para>
58                                 </parameter>
59                                 <parameter name="SentRTP" required="false">
60                                         <para>The sender's last RTP timestamp. Only valid when PT is
61                                         <literal>200(SR)</literal>.</para>
62                                 </parameter>
63                                 <parameter name="SentPackets" required="false">
64                                         <para>The number of packets the sender has sent. Only valid when PT
65                                         is <literal>200(SR)</literal>.</para>
66                                 </parameter>
67                                 <parameter name="SentOctets" required="false">
68                                         <para>The number of bytes the sender has sent. Only valid when PT is
69                                         <literal>200(SR)</literal>.</para>
70                                 </parameter>
71                                 <parameter name="ReportXSourceSSRC">
72                                         <para>The SSRC for the source of this report block.</para>
73                                 </parameter>
74                                 <parameter name="ReportXFractionLost">
75                                         <para>The fraction of RTP data packets from <literal>ReportXSourceSSRC</literal>
76                                         lost since the previous SR or RR report was sent.</para>
77                                 </parameter>
78                                 <parameter name="ReportXCumulativeLost">
79                                         <para>The total number of RTP data packets from <literal>ReportXSourceSSRC</literal>
80                                         lost since the beginning of reception.</para>
81                                 </parameter>
82                                 <parameter name="ReportXHighestSequence">
83                                         <para>The highest sequence number received in an RTP data packet from
84                                         <literal>ReportXSourceSSRC</literal>.</para>
85                                 </parameter>
86                                 <parameter name="ReportXSequenceNumberCycles">
87                                         <para>The number of sequence number cycles seen for the RTP data
88                                         received from <literal>ReportXSourceSSRC</literal>.</para>
89                                 </parameter>
90                                 <parameter name="ReportXIAJitter">
91                                         <para>An estimate of the statistical variance of the RTP data packet
92                                         interarrival time, measured in timestamp units.</para>
93                                 </parameter>
94                                 <parameter name="ReportXLSR">
95                                         <para>The last SR timestamp received from <literal>ReportXSourceSSRC</literal>.
96                                         If no SR has been received from <literal>ReportXSourceSSRC</literal>,
97                                         then 0.</para>
98                                 </parameter>
99                                 <parameter name="ReportXDLSR">
100                                         <para>The delay, expressed in units of 1/65536 seconds, between
101                                         receiving the last SR packet from <literal>ReportXSourceSSRC</literal>
102                                         and sending this report.</para>
103                                 </parameter>
104                         </syntax>
105                         <see-also>
106                                 <ref type="managerEvent">RTCPReceived</ref>
107                         </see-also>
108                 </managerEventInstance>
109         </managerEvent>
110         <managerEvent language="en_US" name="RTCPReceived">
111                 <managerEventInstance class="EVENT_FLAG_REPORTING">
112                         <synopsis>Raised when an RTCP packet is received.</synopsis>
113                         <syntax>
114                                 <channel_snapshot/>
115                                 <parameter name="SSRC">
116                                         <para>The SSRC identifier for the remote system</para>
117                                 </parameter>
118                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RTCPSent']/managerEventInstance/syntax/parameter[@name='PT'])" />
119                                 <parameter name="From">
120                                         <para>The address the report was received from.</para>
121                                 </parameter>
122                                 <parameter name="RTT">
123                                         <para>Calculated Round-Trip Time in seconds</para>
124                                 </parameter>
125                                 <parameter name="ReportCount">
126                                         <para>The number of reports that were received.</para>
127                                         <para>The report count determines the number of ReportX headers in
128                                         the message. The X for each set of report headers will range from 0 to
129                                         <literal>ReportCount - 1</literal>.</para>
130                                 </parameter>
131                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RTCPSent']/managerEventInstance/syntax/parameter[@name='SentNTP'])" />
132                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RTCPSent']/managerEventInstance/syntax/parameter[@name='SentRTP'])" />
133                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RTCPSent']/managerEventInstance/syntax/parameter[@name='SentPackets'])" />
134                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RTCPSent']/managerEventInstance/syntax/parameter[@name='SentOctets'])" />
135                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='RTCPSent']/managerEventInstance/syntax/parameter[contains(@name, 'ReportX')])" />
136                         </syntax>
137                         <see-also>
138                                 <ref type="managerEvent">RTCPSent</ref>
139                         </see-also>
140                 </managerEventInstance>
141         </managerEvent>
142  ***/
143
144 #include "asterisk.h"
145
146 #include <math.h>                       /* for sqrt, MAX */
147 #include <sched.h>                      /* for sched_yield */
148 #include <sys/time.h>                   /* for timeval */
149 #include <time.h>                       /* for time_t */
150
151 #include "asterisk/_private.h"          /* for ast_rtp_engine_init prototype */
152 #include "asterisk/astobj2.h"           /* for ao2_cleanup, ao2_ref, etc */
153 #include "asterisk/channel.h"           /* for ast_channel_name, etc */
154 #include "asterisk/codec.h"             /* for ast_codec_media_type2str, etc */
155 #include "asterisk/format.h"            /* for ast_format_cmp, etc */
156 #include "asterisk/format_cache.h"      /* for ast_format_adpcm, etc */
157 #include "asterisk/format_cap.h"        /* for ast_format_cap_alloc, etc */
158 #include "asterisk/json.h"              /* for ast_json_ref, etc */
159 #include "asterisk/linkedlists.h"       /* for ast_rtp_engine::<anonymous>, etc */
160 #include "asterisk/lock.h"              /* for ast_rwlock_unlock, etc */
161 #include "asterisk/logger.h"            /* for ast_log, ast_debug, etc */
162 #include "asterisk/manager.h"
163 #include "asterisk/module.h"            /* for ast_module_unref, etc */
164 #include "asterisk/netsock2.h"          /* for ast_sockaddr_copy, etc */
165 #include "asterisk/options.h"           /* for ast_option_rtpptdynamic */
166 #include "asterisk/pbx.h"               /* for pbx_builtin_setvar_helper */
167 #include "asterisk/res_srtp.h"          /* for ast_srtp_res */
168 #include "asterisk/rtp_engine.h"        /* for ast_rtp_codecs, etc */
169 #include "asterisk/stasis.h"            /* for stasis_message_data, etc */
170 #include "asterisk/stasis_channels.h"   /* for ast_channel_stage_snapshot, etc */
171 #include "asterisk/strings.h"           /* for ast_str_append, etc */
172 #include "asterisk/time.h"              /* for ast_tvdiff_ms, ast_tvnow */
173 #include "asterisk/translate.h"         /* for ast_translate_available_formats */
174 #include "asterisk/utils.h"             /* for ast_free, ast_strdup, etc */
175 #include "asterisk/vector.h"            /* for AST_VECTOR_GET, etc */
176
177 struct ast_srtp_res *res_srtp = NULL;
178 struct ast_srtp_policy_res *res_srtp_policy = NULL;
179
180 /*! Structure that contains extmap negotiation information */
181 struct rtp_extmap {
182         /*! The RTP extension */
183         enum ast_rtp_extension extension;
184         /*! The current negotiated direction */
185         enum ast_rtp_extension_direction direction;
186 };
187
188 /*! Structure that represents an RTP session (instance) */
189 struct ast_rtp_instance {
190         /*! Engine that is handling this RTP instance */
191         struct ast_rtp_engine *engine;
192         /*! Data unique to the RTP engine */
193         void *data;
194         /*! RTP properties that have been set and their value */
195         int properties[AST_RTP_PROPERTY_MAX];
196         /*! Address that we are expecting RTP to come in to */
197         struct ast_sockaddr local_address;
198         /*! The original source address */
199         struct ast_sockaddr requested_target_address;
200         /*! Address that we are sending RTP to */
201         struct ast_sockaddr incoming_source_address;
202         /*! Instance that we are bridged to if doing remote or local bridging */
203         struct ast_rtp_instance *bridged;
204         /*! Payload and packetization information */
205         struct ast_rtp_codecs codecs;
206         /*! RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */
207         int timeout;
208         /*! RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */
209         int holdtimeout;
210         /*! RTP keepalive interval */
211         int keepalive;
212         /*! Glue currently in use */
213         struct ast_rtp_glue *glue;
214         /*! SRTP info associated with the instance */
215         struct ast_srtp *srtp;
216         /*! SRTP info dedicated for RTCP associated with the instance */
217         struct ast_srtp *rtcp_srtp;
218         /*! Channel unique ID */
219         char channel_uniqueid[AST_MAX_UNIQUEID];
220         /*! Time of last packet sent */
221         time_t last_tx;
222         /*! Time of last packet received */
223         time_t last_rx;
224         /*! Enabled RTP extensions */
225         AST_VECTOR(, enum ast_rtp_extension_direction) extmap_enabled;
226         /*! Negotiated RTP extensions (using index based on extension) */
227         AST_VECTOR(, int) extmap_negotiated;
228         /*! Negotiated RTP extensions (using index based on unique id) */
229         AST_VECTOR(, struct rtp_extmap) extmap_unique_ids;
230 };
231
232 /*!
233  * \brief URIs for known RTP extensions
234  */
235 static const char * const rtp_extension_uris[AST_RTP_EXTENSION_MAX] = {
236         [AST_RTP_EXTENSION_UNSUPPORTED]         = "",
237         [AST_RTP_EXTENSION_ABS_SEND_TIME]       = "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",
238 };
239
240 /*! List of RTP engines that are currently registered */
241 static AST_RWLIST_HEAD_STATIC(engines, ast_rtp_engine);
242
243 /*! List of RTP glues */
244 static AST_RWLIST_HEAD_STATIC(glues, ast_rtp_glue);
245
246 #define MAX_RTP_MIME_TYPES 128
247
248 /*! The following array defines the MIME Media type (and subtype) for each
249    of our codecs, or RTP-specific data type. */
250 static struct ast_rtp_mime_type {
251         /*! \brief A mapping object between the Asterisk codec and this RTP payload */
252         struct ast_rtp_payload_type payload_type;
253         /*! \brief The media type */
254         char type[16];
255         /*! \brief The format type */
256         char subtype[64];
257         /*! \brief Expected sample rate of the /c subtype */
258         unsigned int sample_rate;
259 } ast_rtp_mime_types[128]; /* This will Likely not need to grow any time soon. */
260 static ast_rwlock_t mime_types_lock;
261 static int mime_types_len = 0;
262
263 /*!
264  * \brief Mapping between Asterisk codecs and rtp payload types
265  *
266  * Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
267  * also, our own choices for dynamic payload types.  This is our master
268  * table for transmission
269  *
270  * See http://www.iana.org/assignments/rtp-parameters for a list of
271  * assigned values
272  */
273 static struct ast_rtp_payload_type *static_RTP_PT[AST_RTP_MAX_PT];
274 static ast_rwlock_t static_RTP_PT_lock;
275
276 /*! \brief \ref stasis topic for RTP related messages */
277 static struct stasis_topic *rtp_topic;
278
279
280 /*!
281  * \internal
282  * \brief Destructor for \c ast_rtp_payload_type
283  */
284 static void rtp_payload_type_dtor(void *obj)
285 {
286         struct ast_rtp_payload_type *payload = obj;
287
288         ao2_cleanup(payload->format);
289 }
290
291 static struct ast_rtp_payload_type *rtp_payload_type_alloc(struct ast_format *format,
292         int payload, int rtp_code, int primary_mapping)
293 {
294         struct ast_rtp_payload_type *type = ao2_alloc_options(
295                 sizeof(*type), rtp_payload_type_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
296
297         if (!type) {
298                 return NULL;
299         }
300
301         type->format = ao2_bump(format);
302         type->asterisk_format = type->format != NULL;
303         type->payload = payload;
304         type->rtp_code = rtp_code;
305         type->primary_mapping = primary_mapping;
306
307         return type;
308 }
309
310 struct ast_rtp_payload_type *ast_rtp_engine_alloc_payload_type(void)
311 {
312         return rtp_payload_type_alloc(NULL, 0, 0, 0);
313 }
314
315 int ast_rtp_engine_register2(struct ast_rtp_engine *engine, struct ast_module *module)
316 {
317         struct ast_rtp_engine *current_engine;
318
319         /* Perform a sanity check on the engine structure to make sure it has the basics */
320         if (ast_strlen_zero(engine->name) || !engine->new || !engine->destroy || !engine->write || !engine->read) {
321                 ast_log(LOG_WARNING, "RTP Engine '%s' failed sanity check so it was not registered.\n", !ast_strlen_zero(engine->name) ? engine->name : "Unknown");
322                 return -1;
323         }
324
325         /* Link owner module to the RTP engine for reference counting purposes */
326         engine->mod = module;
327
328         AST_RWLIST_WRLOCK(&engines);
329
330         /* Ensure that no two modules with the same name are registered at the same time */
331         AST_RWLIST_TRAVERSE(&engines, current_engine, entry) {
332                 if (!strcmp(current_engine->name, engine->name)) {
333                         ast_log(LOG_WARNING, "An RTP engine with the name '%s' has already been registered.\n", engine->name);
334                         AST_RWLIST_UNLOCK(&engines);
335                         return -1;
336                 }
337         }
338
339         /* The engine survived our critique. Off to the list it goes to be used */
340         AST_RWLIST_INSERT_TAIL(&engines, engine, entry);
341
342         AST_RWLIST_UNLOCK(&engines);
343
344         ast_verb(2, "Registered RTP engine '%s'\n", engine->name);
345
346         return 0;
347 }
348
349 int ast_rtp_engine_unregister(struct ast_rtp_engine *engine)
350 {
351         struct ast_rtp_engine *current_engine = NULL;
352
353         AST_RWLIST_WRLOCK(&engines);
354
355         if ((current_engine = AST_RWLIST_REMOVE(&engines, engine, entry))) {
356                 ast_verb(2, "Unregistered RTP engine '%s'\n", engine->name);
357         }
358
359         AST_RWLIST_UNLOCK(&engines);
360
361         return current_engine ? 0 : -1;
362 }
363
364 int ast_rtp_glue_register2(struct ast_rtp_glue *glue, struct ast_module *module)
365 {
366         struct ast_rtp_glue *current_glue = NULL;
367
368         if (ast_strlen_zero(glue->type)) {
369                 return -1;
370         }
371
372         glue->mod = module;
373
374         AST_RWLIST_WRLOCK(&glues);
375
376         AST_RWLIST_TRAVERSE(&glues, current_glue, entry) {
377                 if (!strcasecmp(current_glue->type, glue->type)) {
378                         ast_log(LOG_WARNING, "RTP glue with the name '%s' has already been registered.\n", glue->type);
379                         AST_RWLIST_UNLOCK(&glues);
380                         return -1;
381                 }
382         }
383
384         AST_RWLIST_INSERT_TAIL(&glues, glue, entry);
385
386         AST_RWLIST_UNLOCK(&glues);
387
388         ast_verb(2, "Registered RTP glue '%s'\n", glue->type);
389
390         return 0;
391 }
392
393 int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
394 {
395         struct ast_rtp_glue *current_glue = NULL;
396
397         AST_RWLIST_WRLOCK(&glues);
398
399         if ((current_glue = AST_RWLIST_REMOVE(&glues, glue, entry))) {
400                 ast_verb(2, "Unregistered RTP glue '%s'\n", glue->type);
401         }
402
403         AST_RWLIST_UNLOCK(&glues);
404
405         return current_glue ? 0 : -1;
406 }
407
408 static void instance_destructor(void *obj)
409 {
410         struct ast_rtp_instance *instance = obj;
411
412         /* Pass us off to the engine to destroy */
413         if (instance->data) {
414                 /*
415                  * Lock in case the RTP engine has other threads that
416                  * need synchronization with the destruction.
417                  */
418                 ao2_lock(instance);
419                 instance->engine->destroy(instance);
420                 ao2_unlock(instance);
421         }
422
423         if (instance->srtp) {
424                 res_srtp->destroy(instance->srtp);
425         }
426
427         if (instance->rtcp_srtp) {
428                 res_srtp->destroy(instance->rtcp_srtp);
429         }
430
431         ast_rtp_codecs_payloads_destroy(&instance->codecs);
432
433         AST_VECTOR_FREE(&instance->extmap_enabled);
434         AST_VECTOR_FREE(&instance->extmap_negotiated);
435         AST_VECTOR_FREE(&instance->extmap_unique_ids);
436
437         /* Drop our engine reference */
438         ast_module_unref(instance->engine->mod);
439
440         ast_debug(1, "Destroyed RTP instance '%p'\n", instance);
441 }
442
443 int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
444 {
445         ao2_ref(instance, -1);
446
447         return 0;
448 }
449
450 struct ast_rtp_instance *ast_rtp_instance_new(const char *engine_name,
451                 struct ast_sched_context *sched, const struct ast_sockaddr *sa,
452                 void *data)
453 {
454         struct ast_sockaddr address = {{0,}};
455         struct ast_rtp_instance *instance = NULL;
456         struct ast_rtp_engine *engine = NULL;
457         struct ast_module *mod_ref;
458
459         AST_RWLIST_RDLOCK(&engines);
460
461         /* If an engine name was specified try to use it or otherwise use the first one registered */
462         if (!ast_strlen_zero(engine_name)) {
463                 AST_RWLIST_TRAVERSE(&engines, engine, entry) {
464                         if (!strcmp(engine->name, engine_name)) {
465                                 break;
466                         }
467                 }
468         } else {
469                 engine = AST_RWLIST_FIRST(&engines);
470         }
471
472         /* If no engine was actually found bail out now */
473         if (!engine) {
474                 ast_log(LOG_ERROR, "No RTP engine was found. Do you have one loaded?\n");
475                 AST_RWLIST_UNLOCK(&engines);
476                 return NULL;
477         }
478
479         /* Bump up the reference count before we return so the module can not be unloaded */
480         mod_ref = ast_module_running_ref(engine->mod);
481
482         AST_RWLIST_UNLOCK(&engines);
483
484         if (!mod_ref) {
485                 /* BUGBUG: improve handling of this situation. */
486                 return NULL;
487         }
488
489         /* Allocate a new RTP instance */
490         if (!(instance = ao2_alloc(sizeof(*instance), instance_destructor))) {
491                 ast_module_unref(engine->mod);
492                 return NULL;
493         }
494         instance->engine = engine;
495         ast_sockaddr_copy(&instance->local_address, sa);
496         ast_sockaddr_copy(&address, sa);
497
498         if (ast_rtp_codecs_payloads_initialize(&instance->codecs)) {
499                 ao2_ref(instance, -1);
500                 return NULL;
501         }
502
503         /* Initialize RTP extension support */
504         if (AST_VECTOR_INIT(&instance->extmap_enabled, 0) ||
505                 AST_VECTOR_INIT(&instance->extmap_negotiated, 0) ||
506                 AST_VECTOR_INIT(&instance->extmap_unique_ids, 0)) {
507                 ao2_ref(instance, -1);
508                 return NULL;
509         }
510
511         ast_debug(1, "Using engine '%s' for RTP instance '%p'\n", engine->name, instance);
512
513         /*
514          * And pass it off to the engine to setup
515          *
516          * Lock in case the RTP engine has other threads that
517          * need synchronization with the construction.
518          */
519         ao2_lock(instance);
520         if (instance->engine->new(instance, sched, &address, data)) {
521                 ast_debug(1, "Engine '%s' failed to setup RTP instance '%p'\n", engine->name, instance);
522                 ao2_unlock(instance);
523                 ao2_ref(instance, -1);
524                 return NULL;
525         }
526         ao2_unlock(instance);
527
528         ast_debug(1, "RTP instance '%p' is setup and ready to go\n", instance);
529
530         return instance;
531 }
532
533 const char *ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
534 {
535         return instance->channel_uniqueid;
536 }
537
538 void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid)
539 {
540         ast_copy_string(instance->channel_uniqueid, uniqueid, sizeof(instance->channel_uniqueid));
541 }
542
543 void ast_rtp_instance_set_data(struct ast_rtp_instance *instance, void *data)
544 {
545         instance->data = data;
546 }
547
548 void *ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
549 {
550         return instance->data;
551 }
552
553 int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
554 {
555         int res;
556
557         ao2_lock(instance);
558         res = instance->engine->write(instance, frame);
559         ao2_unlock(instance);
560         return res;
561 }
562
563 struct ast_frame *ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
564 {
565         struct ast_frame *frame;
566
567         ao2_lock(instance);
568         frame = instance->engine->read(instance, rtcp);
569         ao2_unlock(instance);
570         return frame;
571 }
572
573 int ast_rtp_instance_set_local_address(struct ast_rtp_instance *instance,
574                 const struct ast_sockaddr *address)
575 {
576         ao2_lock(instance);
577         ast_sockaddr_copy(&instance->local_address, address);
578         ao2_unlock(instance);
579         return 0;
580 }
581
582 static void rtp_instance_set_incoming_source_address_nolock(struct ast_rtp_instance *instance,
583         const struct ast_sockaddr *address)
584 {
585         ast_sockaddr_copy(&instance->incoming_source_address, address);
586         if (instance->engine->remote_address_set) {
587                 instance->engine->remote_address_set(instance, &instance->incoming_source_address);
588         }
589 }
590
591 int ast_rtp_instance_set_incoming_source_address(struct ast_rtp_instance *instance,
592         const struct ast_sockaddr *address)
593 {
594         ao2_lock(instance);
595         rtp_instance_set_incoming_source_address_nolock(instance, address);
596         ao2_unlock(instance);
597
598         return 0;
599 }
600
601 int ast_rtp_instance_set_requested_target_address(struct ast_rtp_instance *instance,
602                                                   const struct ast_sockaddr *address)
603 {
604         ao2_lock(instance);
605
606         ast_sockaddr_copy(&instance->requested_target_address, address);
607         rtp_instance_set_incoming_source_address_nolock(instance, address);
608
609         ao2_unlock(instance);
610
611         return 0;
612 }
613
614 int ast_rtp_instance_get_and_cmp_local_address(struct ast_rtp_instance *instance,
615                 struct ast_sockaddr *address)
616 {
617         ao2_lock(instance);
618         if (ast_sockaddr_cmp(address, &instance->local_address) != 0) {
619                 ast_sockaddr_copy(address, &instance->local_address);
620                 ao2_unlock(instance);
621                 return 1;
622         }
623         ao2_unlock(instance);
624
625         return 0;
626 }
627
628 void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance,
629                 struct ast_sockaddr *address)
630 {
631         ao2_lock(instance);
632         ast_sockaddr_copy(address, &instance->local_address);
633         ao2_unlock(instance);
634 }
635
636 int ast_rtp_instance_get_and_cmp_requested_target_address(struct ast_rtp_instance *instance,
637                 struct ast_sockaddr *address)
638 {
639         ao2_lock(instance);
640         if (ast_sockaddr_cmp(address, &instance->requested_target_address) != 0) {
641                 ast_sockaddr_copy(address, &instance->requested_target_address);
642                 ao2_unlock(instance);
643                 return 1;
644         }
645         ao2_unlock(instance);
646
647         return 0;
648 }
649
650 void ast_rtp_instance_get_incoming_source_address(struct ast_rtp_instance *instance,
651                                                   struct ast_sockaddr *address)
652 {
653         ao2_lock(instance);
654         ast_sockaddr_copy(address, &instance->incoming_source_address);
655         ao2_unlock(instance);
656 }
657
658 void ast_rtp_instance_get_requested_target_address(struct ast_rtp_instance *instance,
659                                                    struct ast_sockaddr *address)
660 {
661         ao2_lock(instance);
662         ast_sockaddr_copy(address, &instance->requested_target_address);
663         ao2_unlock(instance);
664 }
665
666 void ast_rtp_instance_set_extended_prop(struct ast_rtp_instance *instance, int property, void *value)
667 {
668         if (instance->engine->extended_prop_set) {
669                 ao2_lock(instance);
670                 instance->engine->extended_prop_set(instance, property, value);
671                 ao2_unlock(instance);
672         }
673 }
674
675 void *ast_rtp_instance_get_extended_prop(struct ast_rtp_instance *instance, int property)
676 {
677         void *prop;
678
679         if (instance->engine->extended_prop_get) {
680                 ao2_lock(instance);
681                 prop = instance->engine->extended_prop_get(instance, property);
682                 ao2_unlock(instance);
683         } else {
684                 prop = NULL;
685         }
686
687         return prop;
688 }
689
690 void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
691 {
692         ao2_lock(instance);
693         instance->properties[property] = value;
694
695         if (instance->engine->prop_set) {
696                 instance->engine->prop_set(instance, property, value);
697         }
698         ao2_unlock(instance);
699 }
700
701 int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property)
702 {
703         int prop;
704
705         ao2_lock(instance);
706         prop = instance->properties[property];
707         ao2_unlock(instance);
708
709         return prop;
710 }
711
712 struct ast_rtp_codecs *ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
713 {
714         return &instance->codecs;
715 }
716
717 int ast_rtp_instance_extmap_enable(struct ast_rtp_instance *instance, int id, enum ast_rtp_extension extension,
718         enum ast_rtp_extension_direction direction)
719 {
720         struct rtp_extmap extmap = {
721                 .extension = extension,
722                 .direction = direction,
723         };
724
725         ao2_lock(instance);
726
727         if (!instance->engine->extension_enable || !instance->engine->extension_enable(instance, extension)) {
728                 ao2_unlock(instance);
729                 return 0;
730         }
731
732         /* We store enabled extensions separately so we can easily do negotiation */
733         if (AST_VECTOR_REPLACE(&instance->extmap_enabled, extension, direction)) {
734                 ao2_unlock(instance);
735                 return -1;
736         }
737
738         if (id <= 0) {
739                 /* We find a free unique identifier for this extension by just appending it to the
740                  * vector of unique ids. The size of the vector will become its unique identifier.
741                  * As well when we are asking for information on the extensions it will be returned,
742                  * allowing it to be added to the SDP offer.
743                  */
744                 if (AST_VECTOR_APPEND(&instance->extmap_unique_ids, extmap)) {
745                         AST_VECTOR_REPLACE(&instance->extmap_enabled, extension, AST_RTP_EXTENSION_DIRECTION_NONE);
746                         ao2_unlock(instance);
747                         return -1;
748                 }
749                 id = AST_VECTOR_SIZE(&instance->extmap_unique_ids);
750         } else {
751                 /* Otherwise we put it precisely where they want it */
752                 if (AST_VECTOR_REPLACE(&instance->extmap_unique_ids, id - 1, extmap)) {
753                         AST_VECTOR_REPLACE(&instance->extmap_enabled, extension, AST_RTP_EXTENSION_DIRECTION_NONE);
754                         ao2_unlock(instance);
755                         return -1;
756                 }
757         }
758
759         /* Now that we have an id add the extension to here */
760         if (AST_VECTOR_REPLACE(&instance->extmap_negotiated, extension, id)) {
761                 extmap.extension = AST_RTP_EXTENSION_UNSUPPORTED;
762                 extmap.direction = AST_RTP_EXTENSION_DIRECTION_NONE;
763                 AST_VECTOR_REPLACE(&instance->extmap_enabled, extension, AST_RTP_EXTENSION_DIRECTION_NONE);
764                 AST_VECTOR_REPLACE(&instance->extmap_unique_ids, id - 1, extmap);
765                 ao2_unlock(instance);
766                 return -1;
767         }
768
769         ao2_unlock(instance);
770
771         return 0;
772 }
773
774 /*! \brief Helper function which negotiates two RTP extension directions to get our current direction */
775 static enum ast_rtp_extension_direction rtp_extmap_negotiate_direction(enum ast_rtp_extension_direction ours,
776         enum ast_rtp_extension_direction theirs)
777 {
778         if (theirs == AST_RTP_EXTENSION_DIRECTION_NONE || ours == AST_RTP_EXTENSION_DIRECTION_NONE) {
779                 /* This should not occur but if it does tolerate either side not having this extension
780                  * in use.
781                  */
782                 return AST_RTP_EXTENSION_DIRECTION_NONE;
783         } else if (theirs == AST_RTP_EXTENSION_DIRECTION_INACTIVE) {
784                 /* Inactive is always inactive on our side */
785                 return AST_RTP_EXTENSION_DIRECTION_INACTIVE;
786         } else if (theirs == AST_RTP_EXTENSION_DIRECTION_SENDRECV) {
787                 return ours;
788         } else if (theirs == AST_RTP_EXTENSION_DIRECTION_SENDONLY) {
789                 /* If they are send only then we become recvonly if we are configured as sendrecv or recvonly */
790                 if (ours == AST_RTP_EXTENSION_DIRECTION_SENDRECV || ours == AST_RTP_EXTENSION_DIRECTION_RECVONLY) {
791                         return AST_RTP_EXTENSION_DIRECTION_RECVONLY;
792                 }
793         } else if (theirs == AST_RTP_EXTENSION_DIRECTION_RECVONLY) {
794                 /* If they are recv only then we become sendonly if we are configured as sendrecv or sendonly */
795                 if (ours == AST_RTP_EXTENSION_DIRECTION_SENDRECV || ours == AST_RTP_EXTENSION_DIRECTION_SENDONLY) {
796                         return AST_RTP_EXTENSION_DIRECTION_SENDONLY;
797                 }
798         }
799
800         return AST_RTP_EXTENSION_DIRECTION_NONE;
801 }
802
803 int ast_rtp_instance_extmap_negotiate(struct ast_rtp_instance *instance, int id, enum ast_rtp_extension_direction direction,
804         const char *uri, const char *attributes)
805 {
806         /* 'attributes' is currently unused but exists in the API to ensure it does not need to be altered
807          * in the future in case we need to use it.
808          */
809         int idx;
810         enum ast_rtp_extension extension = AST_RTP_EXTENSION_UNSUPPORTED;
811
812         /* Per the RFC the identifier has to be 1 or above */
813         if (id < 1) {
814                 return -1;
815         }
816
817         /* Convert the provided URI to the internal representation */
818         for (idx = 0; idx < ARRAY_LEN(rtp_extension_uris); ++idx) {
819                 if (!strcasecmp(rtp_extension_uris[idx], uri)) {
820                         extension = idx;
821                         break;
822                 }
823         }
824
825         ao2_lock(instance);
826         /* We only accept the extension if it is enabled */
827         if (extension < AST_VECTOR_SIZE(&instance->extmap_enabled) &&
828                 AST_VECTOR_GET(&instance->extmap_enabled, extension) != AST_RTP_EXTENSION_DIRECTION_NONE) {
829                 struct rtp_extmap extmap = {
830                         .extension = extension,
831                         .direction = rtp_extmap_negotiate_direction(AST_VECTOR_GET(&instance->extmap_enabled, extension), direction),
832                 };
833
834                 /* If the direction negotiation failed then don't accept or use this extension */
835                 if (extmap.direction != AST_RTP_EXTENSION_DIRECTION_NONE) {
836                         if (extension != AST_RTP_EXTENSION_UNSUPPORTED) {
837                                 AST_VECTOR_REPLACE(&instance->extmap_negotiated, extension, id);
838                         }
839                         AST_VECTOR_REPLACE(&instance->extmap_unique_ids, id - 1, extmap);
840                 }
841         }
842         ao2_unlock(instance);
843
844         return 0;
845 }
846
847 void ast_rtp_instance_extmap_clear(struct ast_rtp_instance *instance)
848 {
849         static const struct rtp_extmap extmap_none = {
850                 .extension = AST_RTP_EXTENSION_UNSUPPORTED,
851                 .direction = AST_RTP_EXTENSION_DIRECTION_NONE,
852         };
853         int idx;
854
855         ao2_lock(instance);
856
857         /* Clear both the known unique ids and the negotiated extensions as we are about to have
858          * new results set on us.
859          */
860         for (idx = 0; idx < AST_VECTOR_SIZE(&instance->extmap_unique_ids); ++idx) {
861                 AST_VECTOR_REPLACE(&instance->extmap_unique_ids, idx, extmap_none);
862         }
863
864         for (idx = 0; idx < AST_VECTOR_SIZE(&instance->extmap_negotiated); ++idx) {
865                 AST_VECTOR_REPLACE(&instance->extmap_negotiated, idx, -1);
866         }
867
868         ao2_unlock(instance);
869 }
870
871 int ast_rtp_instance_extmap_get_id(struct ast_rtp_instance *instance, enum ast_rtp_extension extension)
872 {
873         int id = -1;
874
875         ao2_lock(instance);
876         if (extension < AST_VECTOR_SIZE(&instance->extmap_negotiated)) {
877                 id = AST_VECTOR_GET(&instance->extmap_negotiated, extension);
878         }
879         ao2_unlock(instance);
880
881         return id;
882 }
883
884 size_t ast_rtp_instance_extmap_count(struct ast_rtp_instance *instance)
885 {
886         size_t count;
887
888         ao2_lock(instance);
889         count = AST_VECTOR_SIZE(&instance->extmap_unique_ids);
890         ao2_unlock(instance);
891
892         return count;
893 }
894
895 enum ast_rtp_extension ast_rtp_instance_extmap_get_extension(struct ast_rtp_instance *instance, int id)
896 {
897         enum ast_rtp_extension extension = AST_RTP_EXTENSION_UNSUPPORTED;
898
899         ao2_lock(instance);
900
901         /* The local unique identifier starts at '1' so the highest unique identifier
902          * can be the actual size of the vector. We compensate (as it is 0 index based)
903          * by dropping it down to 1 to get the correct information.
904          */
905         if (0 < id && id <= AST_VECTOR_SIZE(&instance->extmap_unique_ids)) {
906                 struct rtp_extmap *extmap = AST_VECTOR_GET_ADDR(&instance->extmap_unique_ids, id - 1);
907
908                 extension = extmap->extension;
909         }
910         ao2_unlock(instance);
911
912         return extension;
913 }
914
915 enum ast_rtp_extension_direction ast_rtp_instance_extmap_get_direction(struct ast_rtp_instance *instance, int id)
916 {
917         enum ast_rtp_extension_direction direction = AST_RTP_EXTENSION_DIRECTION_NONE;
918
919         ao2_lock(instance);
920
921         if (0 < id && id <= AST_VECTOR_SIZE(&instance->extmap_unique_ids)) {
922                 struct rtp_extmap *extmap = AST_VECTOR_GET_ADDR(&instance->extmap_unique_ids, id - 1);
923
924                 direction = extmap->direction;
925         }
926         ao2_unlock(instance);
927
928         return direction;
929 }
930
931 const char *ast_rtp_instance_extmap_get_uri(struct ast_rtp_instance *instance, int id)
932 {
933         enum ast_rtp_extension extension = ast_rtp_instance_extmap_get_extension(instance, id);
934
935         if (extension == AST_RTP_EXTENSION_UNSUPPORTED ||
936                 (unsigned int)extension >= ARRAY_LEN(rtp_extension_uris)) {
937                 return NULL;
938         }
939
940         return rtp_extension_uris[extension];
941 }
942
943 int ast_rtp_codecs_payloads_initialize(struct ast_rtp_codecs *codecs)
944 {
945         int res;
946
947         codecs->framing = 0;
948         ast_rwlock_init(&codecs->codecs_lock);
949         res = AST_VECTOR_INIT(&codecs->payload_mapping_rx, AST_RTP_MAX_PT);
950         res |= AST_VECTOR_INIT(&codecs->payload_mapping_tx, AST_RTP_MAX_PT);
951         if (res) {
952                 AST_VECTOR_FREE(&codecs->payload_mapping_rx);
953                 AST_VECTOR_FREE(&codecs->payload_mapping_tx);
954         }
955
956         return res;
957 }
958
959 void ast_rtp_codecs_payloads_destroy(struct ast_rtp_codecs *codecs)
960 {
961         int idx;
962         struct ast_rtp_payload_type *type;
963
964         for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_rx); ++idx) {
965                 type = AST_VECTOR_GET(&codecs->payload_mapping_rx, idx);
966                 ao2_t_cleanup(type, "destroying ast_rtp_codec rx mapping");
967         }
968         AST_VECTOR_FREE(&codecs->payload_mapping_rx);
969
970         for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_tx); ++idx) {
971                 type = AST_VECTOR_GET(&codecs->payload_mapping_tx, idx);
972                 ao2_t_cleanup(type, "destroying ast_rtp_codec tx mapping");
973         }
974         AST_VECTOR_FREE(&codecs->payload_mapping_tx);
975
976         ast_rwlock_destroy(&codecs->codecs_lock);
977 }
978
979 void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance)
980 {
981         ast_rtp_codecs_payloads_destroy(codecs);
982         ast_rtp_codecs_payloads_initialize(codecs);
983
984         if (instance && instance->engine && instance->engine->payload_set) {
985                 int i;
986
987                 ao2_lock(instance);
988                 for (i = 0; i < AST_RTP_MAX_PT; i++) {
989                         instance->engine->payload_set(instance, i, 0, NULL, 0);
990                 }
991                 ao2_unlock(instance);
992         }
993 }
994
995 /*!
996  * \internal
997  * \brief Clear the rx primary mapping flag on all other matching mappings.
998  * \since 14.0.0
999  *
1000  * \param codecs Codecs that need rx clearing.
1001  * \param to_match Payload type object to compare against.
1002  *
1003  * \note It is assumed that codecs is write locked before calling.
1004  *
1005  * \return Nothing
1006  */
1007 static void payload_mapping_rx_clear_primary(struct ast_rtp_codecs *codecs, struct ast_rtp_payload_type *to_match)
1008 {
1009         int idx;
1010         struct ast_rtp_payload_type *current;
1011         struct ast_rtp_payload_type *new_type;
1012         struct timeval now;
1013
1014         if (!to_match->primary_mapping) {
1015                 return;
1016         }
1017
1018         now = ast_tvnow();
1019         for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_rx); ++idx) {
1020                 current = AST_VECTOR_GET(&codecs->payload_mapping_rx, idx);
1021
1022                 if (!current || current == to_match || !current->primary_mapping) {
1023                         continue;
1024                 }
1025                 if (current->asterisk_format && to_match->asterisk_format) {
1026                         if (ast_format_cmp(current->format, to_match->format) == AST_FORMAT_CMP_NOT_EQUAL) {
1027                                 continue;
1028                         }
1029                 } else if (!current->asterisk_format && !to_match->asterisk_format) {
1030                         if (current->rtp_code != to_match->rtp_code) {
1031                                 continue;
1032                         }
1033                 } else {
1034                         continue;
1035                 }
1036
1037                 /* Replace current with non-primary marked version */
1038                 new_type = ast_rtp_engine_alloc_payload_type();
1039                 if (!new_type) {
1040                         continue;
1041                 }
1042                 *new_type = *current;
1043                 new_type->primary_mapping = 0;
1044                 new_type->when_retired = now;
1045                 ao2_bump(new_type->format);
1046                 AST_VECTOR_REPLACE(&codecs->payload_mapping_rx, idx, new_type);
1047                 ao2_ref(current, -1);
1048         }
1049 }
1050
1051 /*!
1052  * \internal
1053  * \brief Put the new_type into the rx payload type mapping.
1054  * \since 14.0.0
1055  *
1056  * \param codecs Codecs structure to put new_type into
1057  * \param payload type position to replace.
1058  * \param new_type RTP payload mapping object to store.
1059  *
1060  * \note It is assumed that codecs is write locked before calling.
1061  *
1062  * \return Nothing
1063  */
1064 static void rtp_codecs_payload_replace_rx(struct ast_rtp_codecs *codecs, int payload, struct ast_rtp_payload_type *new_type)
1065 {
1066         ao2_ref(new_type, +1);
1067         if (payload < AST_VECTOR_SIZE(&codecs->payload_mapping_rx)) {
1068                 ao2_t_cleanup(AST_VECTOR_GET(&codecs->payload_mapping_rx, payload),
1069                         "cleaning up rx mapping vector element about to be replaced");
1070         }
1071         if (AST_VECTOR_REPLACE(&codecs->payload_mapping_rx, payload, new_type)) {
1072                 ao2_ref(new_type, -1);
1073                 return;
1074         }
1075
1076         payload_mapping_rx_clear_primary(codecs, new_type);
1077 }
1078
1079 /*!
1080  * \internal
1081  * \brief Copy the rx payload type mapping to the destination.
1082  * \since 14.0.0
1083  *
1084  * \param src The source codecs structure
1085  * \param dest The destination codecs structure that the values from src will be copied to
1086  * \param instance Optionally the instance that the dst codecs structure belongs to
1087  *
1088  * \note It is assumed that src is at least read locked before calling.
1089  * \note It is assumed that dest is write locked before calling.
1090  *
1091  * \return Nothing
1092  */
1093 static void rtp_codecs_payloads_copy_rx(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
1094 {
1095         int idx;
1096         struct ast_rtp_payload_type *type;
1097
1098         for (idx = 0; idx < AST_VECTOR_SIZE(&src->payload_mapping_rx); ++idx) {
1099                 type = AST_VECTOR_GET(&src->payload_mapping_rx, idx);
1100                 if (!type) {
1101                         continue;
1102                 }
1103
1104                 ast_debug(2, "Copying rx payload mapping %d (%p) from %p to %p\n",
1105                         idx, type, src, dest);
1106                 rtp_codecs_payload_replace_rx(dest, idx, type);
1107
1108                 if (instance && instance->engine && instance->engine->payload_set) {
1109                         ao2_lock(instance);
1110                         instance->engine->payload_set(instance, idx, type->asterisk_format, type->format, type->rtp_code);
1111                         ao2_unlock(instance);
1112                 }
1113         }
1114 }
1115
1116 /*!
1117  * \internal
1118  * \brief Determine if a type of payload is already present in mappings.
1119  * \since 14.0.0
1120  *
1121  * \param codecs Codecs to be checked for mappings.
1122  * \param to_match Payload type object to compare against.
1123  *
1124  * \note It is assumed that codecs is write locked before calling.
1125  *
1126  * \retval 0 not found
1127  * \retval 1 found
1128  */
1129 static int payload_mapping_tx_is_present(const struct ast_rtp_codecs *codecs, const struct ast_rtp_payload_type *to_match)
1130 {
1131         int idx;
1132         struct ast_rtp_payload_type *current;
1133
1134         for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_tx); ++idx) {
1135                 current = AST_VECTOR_GET(&codecs->payload_mapping_tx, idx);
1136
1137                 if (!current) {
1138                         continue;
1139                 }
1140                 if (current == to_match) {
1141                         /* The exact object is already in the mapping. */
1142                         return 1;
1143                 }
1144                 if (current->asterisk_format && to_match->asterisk_format) {
1145                         if (ast_format_get_codec_id(current->format) != ast_format_get_codec_id(to_match->format)) {
1146                                 continue;
1147                         } else if (current->payload == to_match->payload) {
1148                                 return 0;
1149                         }
1150                 } else if (!current->asterisk_format && !to_match->asterisk_format) {
1151                         if (current->rtp_code != to_match->rtp_code) {
1152                                 continue;
1153                         }
1154                 } else {
1155                         continue;
1156                 }
1157
1158                 return 1;
1159         }
1160
1161         return 0;
1162 }
1163
1164 /*!
1165  * \internal
1166  * \brief Copy the tx payload type mapping to the destination.
1167  * \since 14.0.0
1168  *
1169  * \param src The source codecs structure
1170  * \param dest The destination codecs structure that the values from src will be copied to
1171  * \param instance Optionally the instance that the dst codecs structure belongs to
1172  *
1173  * \note It is assumed that src is at least read locked before calling.
1174  * \note It is assumed that dest is write locked before calling.
1175  *
1176  * \return Nothing
1177  */
1178 static void rtp_codecs_payloads_copy_tx(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
1179 {
1180         int idx;
1181         struct ast_rtp_payload_type *type;
1182
1183         for (idx = 0; idx < AST_VECTOR_SIZE(&src->payload_mapping_tx); ++idx) {
1184                 type = AST_VECTOR_GET(&src->payload_mapping_tx, idx);
1185                 if (!type) {
1186                         continue;
1187                 }
1188
1189                 ast_debug(2, "Copying tx payload mapping %d (%p) from %p to %p\n",
1190                         idx, type, src, dest);
1191                 ao2_ref(type, +1);
1192                 if (idx < AST_VECTOR_SIZE(&dest->payload_mapping_tx)) {
1193                         ao2_t_cleanup(AST_VECTOR_GET(&dest->payload_mapping_tx, idx),
1194                                 "cleaning up tx mapping vector element about to be replaced");
1195                 }
1196                 if (AST_VECTOR_REPLACE(&dest->payload_mapping_tx, idx, type)) {
1197                         ao2_ref(type, -1);
1198                         continue;
1199                 }
1200
1201                 if (instance && instance->engine && instance->engine->payload_set) {
1202                         ao2_lock(instance);
1203                         instance->engine->payload_set(instance, idx, type->asterisk_format, type->format, type->rtp_code);
1204                         ao2_unlock(instance);
1205                 }
1206         }
1207 }
1208
1209 void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
1210 {
1211         int idx;
1212         struct ast_rtp_payload_type *type;
1213
1214         ast_rwlock_wrlock(&dest->codecs_lock);
1215
1216         /* Deadlock avoidance because of held write lock. */
1217         while (ast_rwlock_tryrdlock(&src->codecs_lock)) {
1218                 ast_rwlock_unlock(&dest->codecs_lock);
1219                 sched_yield();
1220                 ast_rwlock_wrlock(&dest->codecs_lock);
1221         }
1222
1223         /*
1224          * This represents a completely new mapping of what the remote party is
1225          * expecting for payloads, so we clear out the entire tx payload mapping
1226          * vector and replace it.
1227          */
1228         for (idx = 0; idx < AST_VECTOR_SIZE(&dest->payload_mapping_tx); ++idx) {
1229                 type = AST_VECTOR_GET(&dest->payload_mapping_tx, idx);
1230                 ao2_t_cleanup(type, "destroying ast_rtp_codec tx mapping");
1231                 AST_VECTOR_REPLACE(&dest->payload_mapping_tx, idx, NULL);
1232         }
1233
1234         rtp_codecs_payloads_copy_rx(src, dest, instance);
1235         rtp_codecs_payloads_copy_tx(src, dest, instance);
1236         dest->framing = src->framing;
1237
1238         ast_rwlock_unlock(&src->codecs_lock);
1239         ast_rwlock_unlock(&dest->codecs_lock);
1240 }
1241
1242 void ast_rtp_codecs_payloads_xover(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
1243 {
1244         int idx;
1245         struct ast_rtp_payload_type *type;
1246
1247         ast_rwlock_wrlock(&dest->codecs_lock);
1248         if (src != dest) {
1249                 /* Deadlock avoidance because of held write lock. */
1250                 while (ast_rwlock_tryrdlock(&src->codecs_lock)) {
1251                         ast_rwlock_unlock(&dest->codecs_lock);
1252                         sched_yield();
1253                         ast_rwlock_wrlock(&dest->codecs_lock);
1254                 }
1255         }
1256
1257         /* Crossover copy payload type tx mapping to rx mapping. */
1258         for (idx = 0; idx < AST_VECTOR_SIZE(&src->payload_mapping_tx); ++idx) {
1259                 type = AST_VECTOR_GET(&src->payload_mapping_tx, idx);
1260                 if (!type) {
1261                         continue;
1262                 }
1263
1264                 /* All tx mapping elements should have the primary flag set. */
1265                 ast_assert(type->primary_mapping);
1266
1267                 ast_debug(2, "Crossover copying tx to rx payload mapping %d (%p) from %p to %p\n",
1268                         idx, type, src, dest);
1269                 rtp_codecs_payload_replace_rx(dest, idx, type);
1270
1271                 if (instance && instance->engine && instance->engine->payload_set) {
1272                         ao2_lock(instance);
1273                         instance->engine->payload_set(instance, idx, type->asterisk_format, type->format, type->rtp_code);
1274                         ao2_unlock(instance);
1275                 }
1276         }
1277
1278         dest->framing = src->framing;
1279
1280         if (src != dest) {
1281                 ast_rwlock_unlock(&src->codecs_lock);
1282         }
1283         ast_rwlock_unlock(&dest->codecs_lock);
1284 }
1285
1286 void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
1287 {
1288         struct ast_rtp_payload_type *new_type;
1289
1290         if (payload < 0 || payload >= AST_RTP_MAX_PT || payload > AST_RTP_PT_LAST_STATIC) {
1291                 return;
1292         }
1293
1294         ast_rwlock_rdlock(&static_RTP_PT_lock);
1295         new_type = ao2_bump(static_RTP_PT[payload]);
1296         ast_rwlock_unlock(&static_RTP_PT_lock);
1297         if (!new_type) {
1298                 ast_debug(1, "Don't have a default tx payload type %d format for m type on %p\n",
1299                         payload, codecs);
1300                 return;
1301         }
1302
1303         ast_debug(1, "Setting tx payload type %d based on m type on %p\n",
1304                 payload, codecs);
1305
1306         ast_rwlock_wrlock(&codecs->codecs_lock);
1307
1308         if (!payload_mapping_tx_is_present(codecs, new_type)) {
1309                 if (payload < AST_VECTOR_SIZE(&codecs->payload_mapping_tx)) {
1310                         ao2_t_cleanup(AST_VECTOR_GET(&codecs->payload_mapping_tx, payload),
1311                                 "cleaning up replaced tx payload type");
1312                 }
1313
1314                 if (AST_VECTOR_REPLACE(&codecs->payload_mapping_tx, payload, new_type)) {
1315                         ao2_ref(new_type, -1);
1316                 } else if (instance && instance->engine && instance->engine->payload_set) {
1317                         ao2_lock(instance);
1318                         instance->engine->payload_set(instance, payload, new_type->asterisk_format, new_type->format, new_type->rtp_code);
1319                         ao2_unlock(instance);
1320                 }
1321         } else {
1322                 ao2_ref(new_type, -1);
1323         }
1324
1325         ast_rwlock_unlock(&codecs->codecs_lock);
1326 }
1327
1328 int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt,
1329                                  char *mimetype, char *mimesubtype,
1330                                  enum ast_rtp_options options,
1331                                  unsigned int sample_rate)
1332 {
1333         unsigned int idx;
1334         int found = 0;
1335
1336         if (pt < 0 || pt >= AST_RTP_MAX_PT) {
1337                 return -1; /* bogus payload type */
1338         }
1339
1340         ast_rwlock_rdlock(&mime_types_lock);
1341         ast_rwlock_wrlock(&codecs->codecs_lock);
1342
1343         for (idx = 0; idx < mime_types_len; ++idx) {
1344                 const struct ast_rtp_mime_type *t = &ast_rtp_mime_types[idx];
1345                 struct ast_rtp_payload_type *new_type;
1346
1347                 if (strcasecmp(mimesubtype, t->subtype)) {
1348                         continue;
1349                 }
1350
1351                 if (strcasecmp(mimetype, t->type)) {
1352                         continue;
1353                 }
1354
1355                 /* if both sample rates have been supplied, and they don't match,
1356                  * then this not a match; if one has not been supplied, then the
1357                  * rates are not compared */
1358                 if (sample_rate && t->sample_rate &&
1359                     (sample_rate != t->sample_rate)) {
1360                         continue;
1361                 }
1362
1363                 found = 1;
1364
1365                 new_type = ast_rtp_engine_alloc_payload_type();
1366                 if (!new_type) {
1367                         continue;
1368                 }
1369
1370                 new_type->asterisk_format = t->payload_type.asterisk_format;
1371                 new_type->rtp_code = t->payload_type.rtp_code;
1372                 new_type->payload = pt;
1373                 new_type->primary_mapping = 1;
1374                 if (t->payload_type.asterisk_format
1375                         && ast_format_cmp(t->payload_type.format, ast_format_g726) == AST_FORMAT_CMP_EQUAL
1376                         && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
1377                         new_type->format = ast_format_g726_aal2;
1378                 } else {
1379                         new_type->format = t->payload_type.format;
1380                 }
1381
1382                 if (new_type->format) {
1383                         /* SDP parsing automatically increases the reference count */
1384                         new_type->format = ast_format_parse_sdp_fmtp(new_type->format, "");
1385                 }
1386
1387                 if (!payload_mapping_tx_is_present(codecs, new_type)) {
1388                         if (pt < AST_VECTOR_SIZE(&codecs->payload_mapping_tx)) {
1389                                 ao2_t_cleanup(AST_VECTOR_GET(&codecs->payload_mapping_tx, pt),
1390                                         "cleaning up replaced tx payload type");
1391                         }
1392
1393                         if (AST_VECTOR_REPLACE(&codecs->payload_mapping_tx, pt, new_type)) {
1394                                 ao2_ref(new_type, -1);
1395                         } else if (instance && instance->engine && instance->engine->payload_set) {
1396                                 ao2_lock(instance);
1397                                 instance->engine->payload_set(instance, pt, new_type->asterisk_format, new_type->format, new_type->rtp_code);
1398                                 ao2_unlock(instance);
1399                         }
1400                 } else {
1401                         ao2_ref(new_type, -1);
1402                 }
1403
1404                 break;
1405         }
1406
1407         ast_rwlock_unlock(&codecs->codecs_lock);
1408         ast_rwlock_unlock(&mime_types_lock);
1409
1410         return (found ? 0 : -2);
1411 }
1412
1413 int ast_rtp_codecs_payloads_set_rtpmap_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload, char *mimetype, char *mimesubtype, enum ast_rtp_options options)
1414 {
1415         return ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, instance, payload, mimetype, mimesubtype, options, 0);
1416 }
1417
1418 void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
1419 {
1420         struct ast_rtp_payload_type *type;
1421
1422         if (payload < 0 || payload >= AST_RTP_MAX_PT) {
1423                 return;
1424         }
1425
1426         ast_debug(2, "Unsetting payload %d on %p\n", payload, codecs);
1427
1428         ast_rwlock_wrlock(&codecs->codecs_lock);
1429
1430         if (payload < AST_VECTOR_SIZE(&codecs->payload_mapping_tx)) {
1431                 type = AST_VECTOR_GET(&codecs->payload_mapping_tx, payload);
1432                 ao2_cleanup(type);
1433                 AST_VECTOR_REPLACE(&codecs->payload_mapping_tx, payload, NULL);
1434         }
1435
1436         if (instance && instance->engine && instance->engine->payload_set) {
1437                 ao2_lock(instance);
1438                 instance->engine->payload_set(instance, payload, 0, NULL, 0);
1439                 ao2_unlock(instance);
1440         }
1441
1442         ast_rwlock_unlock(&codecs->codecs_lock);
1443 }
1444
1445 enum ast_media_type ast_rtp_codecs_get_stream_type(struct ast_rtp_codecs *codecs)
1446 {
1447         enum ast_media_type stream_type = AST_MEDIA_TYPE_UNKNOWN;
1448         int payload;
1449         struct ast_rtp_payload_type *type;
1450
1451         ast_rwlock_rdlock(&codecs->codecs_lock);
1452         for (payload = 0; payload < AST_VECTOR_SIZE(&codecs->payload_mapping_rx); ++payload) {
1453                 type = AST_VECTOR_GET(&codecs->payload_mapping_rx, payload);
1454                 if (type && type->asterisk_format) {
1455                         stream_type = ast_format_get_type(type->format);
1456                         break;
1457                 }
1458         }
1459         ast_rwlock_unlock(&codecs->codecs_lock);
1460
1461         return stream_type;
1462 }
1463
1464 struct ast_rtp_payload_type *ast_rtp_codecs_get_payload(struct ast_rtp_codecs *codecs, int payload)
1465 {
1466         struct ast_rtp_payload_type *type = NULL;
1467
1468         if (payload < 0 || payload >= AST_RTP_MAX_PT) {
1469                 return NULL;
1470         }
1471
1472         ast_rwlock_rdlock(&codecs->codecs_lock);
1473         if (payload < AST_VECTOR_SIZE(&codecs->payload_mapping_rx)) {
1474                 type = AST_VECTOR_GET(&codecs->payload_mapping_rx, payload);
1475                 ao2_bump(type);
1476         }
1477         ast_rwlock_unlock(&codecs->codecs_lock);
1478
1479         if (!type && payload <= AST_RTP_PT_LAST_STATIC) {
1480                 ast_rwlock_rdlock(&static_RTP_PT_lock);
1481                 type = ao2_bump(static_RTP_PT[payload]);
1482                 ast_rwlock_unlock(&static_RTP_PT_lock);
1483         }
1484
1485         return type;
1486 }
1487
1488 int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
1489 {
1490         struct ast_rtp_payload_type *type;
1491
1492         if (payload < 0 || payload >= AST_RTP_MAX_PT || !format) {
1493                 return -1;
1494         }
1495
1496         type = ast_rtp_engine_alloc_payload_type();
1497         if (!type) {
1498                 return -1;
1499         }
1500         ao2_ref(format, +1);
1501         type->format = format;
1502         type->asterisk_format = 1;
1503         type->payload = payload;
1504         type->primary_mapping = 1;
1505
1506         ast_rwlock_wrlock(&codecs->codecs_lock);
1507         if (!payload_mapping_tx_is_present(codecs, type)) {
1508                 if (payload < AST_VECTOR_SIZE(&codecs->payload_mapping_tx)) {
1509                         ao2_cleanup(AST_VECTOR_GET(&codecs->payload_mapping_tx, payload));
1510                 }
1511                 if (AST_VECTOR_REPLACE(&codecs->payload_mapping_tx, payload, type)) {
1512                         ao2_ref(type, -1);
1513                 }
1514         } else {
1515                 ao2_ref(type, -1);
1516         }
1517         ast_rwlock_unlock(&codecs->codecs_lock);
1518
1519         return 0;
1520 }
1521
1522 struct ast_format *ast_rtp_codecs_get_payload_format(struct ast_rtp_codecs *codecs, int payload)
1523 {
1524         struct ast_rtp_payload_type *type;
1525         struct ast_format *format = NULL;
1526
1527         if (payload < 0 || payload >= AST_RTP_MAX_PT) {
1528                 return NULL;
1529         }
1530
1531         ast_rwlock_rdlock(&codecs->codecs_lock);
1532         if (payload < AST_VECTOR_SIZE(&codecs->payload_mapping_tx)) {
1533                 type = AST_VECTOR_GET(&codecs->payload_mapping_tx, payload);
1534                 if (type && type->asterisk_format) {
1535                         format = ao2_bump(type->format);
1536                 }
1537         }
1538         ast_rwlock_unlock(&codecs->codecs_lock);
1539
1540         return format;
1541 }
1542
1543 void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing)
1544 {
1545         if (!framing) {
1546                 return;
1547         }
1548
1549         ast_rwlock_wrlock(&codecs->codecs_lock);
1550         codecs->framing = framing;
1551         ast_rwlock_unlock(&codecs->codecs_lock);
1552 }
1553
1554 unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs)
1555 {
1556         unsigned int framing;
1557
1558         ast_rwlock_rdlock(&codecs->codecs_lock);
1559         framing = codecs->framing;
1560         ast_rwlock_unlock(&codecs->codecs_lock);
1561
1562         return framing;
1563 }
1564
1565 void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats)
1566 {
1567         int idx;
1568
1569         ast_format_cap_remove_by_type(astformats, AST_MEDIA_TYPE_UNKNOWN);
1570         *nonastformats = 0;
1571
1572         ast_rwlock_rdlock(&codecs->codecs_lock);
1573
1574         for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_tx); ++idx) {
1575                 struct ast_rtp_payload_type *type;
1576
1577                 type = AST_VECTOR_GET(&codecs->payload_mapping_tx, idx);
1578                 if (!type) {
1579                         continue;
1580                 }
1581
1582                 if (type->asterisk_format) {
1583                         ast_format_cap_append(astformats, type->format, 0);
1584                 } else {
1585                         *nonastformats |= type->rtp_code;
1586                 }
1587         }
1588         if (codecs->framing) {
1589                 ast_format_cap_set_framing(astformats, codecs->framing);
1590         }
1591
1592         ast_rwlock_unlock(&codecs->codecs_lock);
1593 }
1594
1595 /*!
1596  * \internal
1597  * \brief Find the static payload type mapping for the format.
1598  * \since 14.0.0
1599  *
1600  * \param asterisk_format Non-zero if the given Asterisk format is present
1601  * \param format Asterisk format to look for
1602  * \param code The non-Asterisk format code to look for
1603  *
1604  * \note It is assumed that static_RTP_PT_lock is at least read locked before calling.
1605  *
1606  * \retval Numerical payload type
1607  * \retval -1 if not found.
1608  */
1609 static int find_static_payload_type(int asterisk_format, const struct ast_format *format, int code)
1610 {
1611         int idx;
1612         int payload = -1;
1613
1614         if (!asterisk_format) {
1615                 for (idx = 0; idx < AST_RTP_MAX_PT; ++idx) {
1616                         if (static_RTP_PT[idx]
1617                                 && !static_RTP_PT[idx]->asterisk_format
1618                                 && static_RTP_PT[idx]->rtp_code == code) {
1619                                 payload = idx;
1620                                 break;
1621                         }
1622                 }
1623         } else if (format) {
1624                 for (idx = 0; idx < AST_RTP_MAX_PT; ++idx) {
1625                         if (static_RTP_PT[idx]
1626                                 && static_RTP_PT[idx]->asterisk_format
1627                                 && ast_format_cmp(format, static_RTP_PT[idx]->format)
1628                                         != AST_FORMAT_CMP_NOT_EQUAL) {
1629                                 payload = idx;
1630                                 break;
1631                         }
1632                 }
1633         }
1634
1635         return payload;
1636 }
1637
1638 /*!
1639  * \internal
1640  * \brief Find the first unused payload type in a given range
1641  *
1642  * \param codecs The codec structure to look in
1643  * \param start Starting index
1644  * \param end Ending index
1645  * \param ignore Skip these payloads types
1646  *
1647  * \note The static_RTP_PT_lock object must be locked before calling
1648  *
1649  * \retval Numerical payload type
1650  * \retval -1 if not found.
1651  */
1652 static int find_unused_payload_in_range(const struct ast_rtp_codecs *codecs,
1653                 int start, int end, struct ast_rtp_payload_type *ignore[])
1654 {
1655         int x;
1656
1657         for (x = start; x < end; ++x) {
1658                 struct ast_rtp_payload_type *type;
1659
1660                 if (ignore[x]) {
1661                         continue;
1662                 } else if (!codecs || x >= AST_VECTOR_SIZE(&codecs->payload_mapping_rx)) {
1663                         return x;
1664                 }
1665
1666                 type = AST_VECTOR_GET(&codecs->payload_mapping_rx, x);
1667                 if (!type) {
1668                         return x;
1669                 }
1670         }
1671         return -1;
1672 }
1673
1674 /*!
1675  * \internal
1676  * \brief Find an unused payload type
1677  *
1678  * \param codecs Codecs structure to look in
1679  *
1680  * \note Both static_RTP_PT_lock and codecs (if given) must be at least
1681  *       read locked before calling.
1682  *
1683  * \retval Numerical payload type
1684  * \retval -1 if not found.
1685  */
1686 static int find_unused_payload(const struct ast_rtp_codecs *codecs)
1687 {
1688         int res;
1689
1690         /* find next available dynamic payload slot */
1691         res = find_unused_payload_in_range(
1692                 codecs, AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT, static_RTP_PT);
1693         if (res != -1) {
1694                 return res;
1695         }
1696
1697         if (ast_option_rtpusedynamic) {
1698                 /*
1699                  * We're using default values for some dynamic types. So if an unused
1700                  * slot was not found try again, but this time ignore the default
1701                  * values declared for dynamic types (except for 101 and 121) .
1702                  */
1703                 static struct ast_rtp_payload_type *ignore[AST_RTP_MAX_PT] = {0};
1704
1705                 ignore[101] = static_RTP_PT[101];
1706                 ignore[121] = static_RTP_PT[121];
1707
1708                 res = find_unused_payload_in_range(
1709                         codecs, AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT, ignore);
1710                 if (res != -1) {
1711                         return res;
1712                 }
1713         }
1714
1715         /* http://www.iana.org/assignments/rtp-parameters
1716          * RFC 3551, Section 3: "[...] applications which need to define more
1717          * than 32 dynamic payload types MAY bind codes below 96, in which case
1718          * it is RECOMMENDED that unassigned payload type numbers be used
1719          * first". Updated by RFC 5761, Section 4: "[...] values in the range
1720          * 64-95 MUST NOT be used [to avoid conflicts with RTCP]". Summaries:
1721          * https://tools.ietf.org/html/draft-roach-mmusic-unified-plan#section-3.2.1.2
1722          * https://tools.ietf.org/html/draft-wu-avtcore-dynamic-pt-usage#section-3
1723          */
1724         res = find_unused_payload_in_range(
1725                 codecs, MAX(ast_option_rtpptdynamic, AST_RTP_PT_LAST_STATIC + 1),
1726                 AST_RTP_PT_LAST_REASSIGN, static_RTP_PT);
1727         if (res != -1) {
1728                 return res;
1729         }
1730
1731         /* Yet, reusing mappings below AST_RTP_PT_LAST_STATIC (35) is not supported
1732          * in Asterisk because when Compact Headers are activated, no rtpmap is
1733          * send for those below 35. If you want to use 35 and below
1734          * A) do not use Compact Headers,
1735          * B) remove that code in chan_sip/res_pjsip, or
1736          * C) add a flag that this RTP Payload Type got reassigned dynamically
1737          *    and requires a rtpmap even with Compact Headers enabled.
1738          */
1739         res = find_unused_payload_in_range(
1740                 codecs, MAX(ast_option_rtpptdynamic, 20),
1741                 AST_RTP_PT_LAST_STATIC + 1, static_RTP_PT);
1742         if (res != -1) {
1743                 return res;
1744         }
1745
1746         return find_unused_payload_in_range(
1747                 codecs, MAX(ast_option_rtpptdynamic, 0),
1748                 20, static_RTP_PT);
1749 }
1750
1751 /*!
1752  * \internal
1753  * \brief Find the oldest non-primary dynamic rx payload type.
1754  * \since 14.0.0
1755  *
1756  * \param codecs Codecs structure to look in
1757  *
1758  * \note It is assumed that codecs is at least read locked before calling.
1759  *
1760  * \retval Numerical payload type
1761  * \retval -1 if not found.
1762  */
1763 static int rtp_codecs_find_non_primary_dynamic_rx(struct ast_rtp_codecs *codecs)
1764 {
1765         struct ast_rtp_payload_type *type;
1766         struct timeval oldest;
1767         int idx;
1768         int payload = -1;
1769
1770         idx = AST_RTP_PT_FIRST_DYNAMIC;
1771         for (; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_rx); ++idx) {
1772                 type = AST_VECTOR_GET(&codecs->payload_mapping_rx, idx);
1773                 if (type
1774                         && !type->primary_mapping
1775                         && (payload == -1
1776                                 || ast_tvdiff_ms(type->when_retired, oldest) < 0)) {
1777                         oldest = type->when_retired;
1778                         payload = idx;
1779                 }
1780         }
1781         return payload;
1782 }
1783
1784 /*!
1785  * \internal
1786  * \brief Assign a payload type for the rx mapping.
1787  * \since 14.0.0
1788  *
1789  * \param codecs Codecs structure to look in
1790  * \param asterisk_format Non-zero if the given Asterisk format is present
1791  * \param format Asterisk format to look for
1792  * \param code The format to look for
1793  * \param explicit Require the provided code to be explicitly used
1794  *
1795  * \note It is assumed that static_RTP_PT_lock is at least read locked before calling.
1796  *
1797  * \retval Numerical payload type
1798  * \retval -1 if could not assign.
1799  */
1800 static int rtp_codecs_assign_payload_code_rx(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code, int explicit)
1801 {
1802         int payload = code;
1803         struct ast_rtp_payload_type *new_type;
1804
1805         if (!explicit) {
1806                 payload = find_static_payload_type(asterisk_format, format, code);
1807
1808                 if (payload < 0 && (!asterisk_format || !ast_option_rtpusedynamic)) {
1809                         return payload;
1810                 }
1811         }
1812
1813         new_type = rtp_payload_type_alloc(format, payload, code, 1);
1814         if (!new_type) {
1815                 return -1;
1816         }
1817
1818         ast_rwlock_wrlock(&codecs->codecs_lock);
1819         if (payload > -1 && (payload < AST_RTP_PT_FIRST_DYNAMIC
1820                 || AST_VECTOR_SIZE(&codecs->payload_mapping_rx) <= payload
1821                 || !AST_VECTOR_GET(&codecs->payload_mapping_rx, payload))) {
1822                 /*
1823                  * The payload type is a static assignment
1824                  * or our default dynamic position is available.
1825                  */
1826                 rtp_codecs_payload_replace_rx(codecs, payload, new_type);
1827         } else if (!explicit && (-1 < (payload = find_unused_payload(codecs))
1828                 || -1 < (payload = rtp_codecs_find_non_primary_dynamic_rx(codecs)))) {
1829                 /*
1830                  * We found the first available empty dynamic position
1831                  * or we found a mapping that should no longer be
1832                  * actively used.
1833                  */
1834                 new_type->payload = payload;
1835                 rtp_codecs_payload_replace_rx(codecs, payload, new_type);
1836         } else if (explicit) {
1837                 /*
1838                 * They explicitly requested this payload number be used but it couldn't be
1839                 */
1840                 payload = -1;
1841         } else {
1842                 /*
1843                  * There are no empty or non-primary dynamic positions
1844                  * left.  Sadness.
1845                  *
1846                  * I don't think this is really possible.
1847                  */
1848                 ast_log(LOG_WARNING, "No dynamic RTP payload type values available "
1849                         "for %s - %d!\n", format ? ast_format_get_name(format) : "", code);
1850         }
1851         ast_rwlock_unlock(&codecs->codecs_lock);
1852
1853         ao2_ref(new_type, -1);
1854
1855         return payload;
1856 }
1857
1858 int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code)
1859 {
1860         struct ast_rtp_payload_type *type;
1861         int idx;
1862         int payload = -1;
1863
1864         ast_rwlock_rdlock(&static_RTP_PT_lock);
1865         if (!asterisk_format) {
1866                 ast_rwlock_rdlock(&codecs->codecs_lock);
1867                 for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_rx); ++idx) {
1868                         type = AST_VECTOR_GET(&codecs->payload_mapping_rx, idx);
1869                         if (!type) {
1870                                 continue;
1871                         }
1872
1873                         if (!type->asterisk_format
1874                                 && type->primary_mapping
1875                                 && type->rtp_code == code) {
1876                                 payload = idx;
1877                                 break;
1878                         }
1879                 }
1880                 ast_rwlock_unlock(&codecs->codecs_lock);
1881         } else if (format) {
1882                 ast_rwlock_rdlock(&codecs->codecs_lock);
1883                 for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_rx); ++idx) {
1884                         type = AST_VECTOR_GET(&codecs->payload_mapping_rx, idx);
1885                         if (!type) {
1886                                 continue;
1887                         }
1888
1889                         if (type->asterisk_format
1890                                 && type->primary_mapping
1891                                 && ast_format_cmp(format, type->format) == AST_FORMAT_CMP_EQUAL) {
1892                                 payload = idx;
1893                                 break;
1894                         }
1895                 }
1896                 ast_rwlock_unlock(&codecs->codecs_lock);
1897         }
1898
1899         if (payload < 0) {
1900                 payload = rtp_codecs_assign_payload_code_rx(codecs, asterisk_format, format,
1901                         code, 0);
1902         }
1903         ast_rwlock_unlock(&static_RTP_PT_lock);
1904
1905         return payload;
1906 }
1907
1908 int ast_rtp_codecs_payload_set_rx(struct ast_rtp_codecs *codecs, int code, struct ast_format *format)
1909 {
1910         return rtp_codecs_assign_payload_code_rx(codecs, 1, format, code, 1);
1911 }
1912
1913 int ast_rtp_codecs_payload_code_tx(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
1914 {
1915         struct ast_rtp_payload_type *type;
1916         int idx;
1917         int payload = -1;
1918
1919         if (!asterisk_format) {
1920                 ast_rwlock_rdlock(&codecs->codecs_lock);
1921                 for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_tx); ++idx) {
1922                         type = AST_VECTOR_GET(&codecs->payload_mapping_tx, idx);
1923                         if (!type) {
1924                                 continue;
1925                         }
1926
1927                         if (!type->asterisk_format
1928                                 && type->rtp_code == code) {
1929                                 payload = idx;
1930                                 break;
1931                         }
1932                 }
1933                 ast_rwlock_unlock(&codecs->codecs_lock);
1934         } else if (format) {
1935                 ast_rwlock_rdlock(&codecs->codecs_lock);
1936                 for (idx = 0; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_tx); ++idx) {
1937                         type = AST_VECTOR_GET(&codecs->payload_mapping_tx, idx);
1938                         if (!type) {
1939                                 continue;
1940                         }
1941
1942                         if (type->asterisk_format
1943                                 && ast_format_cmp(format, type->format) == AST_FORMAT_CMP_EQUAL) {
1944                                 payload = idx;
1945                                 break;
1946                         }
1947                 }
1948                 ast_rwlock_unlock(&codecs->codecs_lock);
1949         }
1950
1951         if (payload < 0) {
1952                 ast_rwlock_rdlock(&static_RTP_PT_lock);
1953                 payload = find_static_payload_type(asterisk_format, format, code);
1954                 ast_rwlock_unlock(&static_RTP_PT_lock);
1955         }
1956
1957         return payload;
1958 }
1959
1960 int ast_rtp_codecs_find_payload_code(struct ast_rtp_codecs *codecs, int payload)
1961 {
1962         struct ast_rtp_payload_type *type;
1963         int res = -1;
1964
1965         ast_rwlock_rdlock(&codecs->codecs_lock);
1966         if (payload < AST_VECTOR_SIZE(&codecs->payload_mapping_tx)) {
1967                 type = AST_VECTOR_GET(&codecs->payload_mapping_tx, payload);
1968                 if (type) {
1969                         res = payload;
1970                 }
1971         }
1972         ast_rwlock_unlock(&codecs->codecs_lock);
1973
1974         return res;
1975 }
1976
1977 const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format,
1978         const struct ast_format *format, int code, enum ast_rtp_options options)
1979 {
1980         int i;
1981         const char *res = "";
1982
1983         ast_rwlock_rdlock(&mime_types_lock);
1984         for (i = 0; i < mime_types_len; i++) {
1985                 if (ast_rtp_mime_types[i].payload_type.asterisk_format && asterisk_format && format &&
1986                         (ast_format_cmp(format, ast_rtp_mime_types[i].payload_type.format) != AST_FORMAT_CMP_NOT_EQUAL)) {
1987                         if ((ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) &&
1988                                         (options & AST_RTP_OPT_G726_NONSTANDARD)) {
1989                                 res = "G726-32";
1990                                 break;
1991                         } else {
1992                                 res = ast_rtp_mime_types[i].subtype;
1993                                 break;
1994                         }
1995                 } else if (!ast_rtp_mime_types[i].payload_type.asterisk_format && !asterisk_format &&
1996                         ast_rtp_mime_types[i].payload_type.rtp_code == code) {
1997
1998                         res = ast_rtp_mime_types[i].subtype;
1999                         break;
2000                 }
2001         }
2002         ast_rwlock_unlock(&mime_types_lock);
2003
2004         return res;
2005 }
2006
2007 unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format,
2008         const struct ast_format *format, int code)
2009 {
2010         unsigned int i;
2011         unsigned int res = 0;
2012
2013         ast_rwlock_rdlock(&mime_types_lock);
2014         for (i = 0; i < mime_types_len; ++i) {
2015                 if (ast_rtp_mime_types[i].payload_type.asterisk_format && asterisk_format && format &&
2016                         (ast_format_cmp(format, ast_rtp_mime_types[i].payload_type.format) != AST_FORMAT_CMP_NOT_EQUAL)) {
2017                         res = ast_rtp_mime_types[i].sample_rate;
2018                         break;
2019                 } else if (!ast_rtp_mime_types[i].payload_type.asterisk_format && !asterisk_format &&
2020                         ast_rtp_mime_types[i].payload_type.rtp_code == code) {
2021                         res = ast_rtp_mime_types[i].sample_rate;
2022                         break;
2023                 }
2024         }
2025         ast_rwlock_unlock(&mime_types_lock);
2026
2027         return res;
2028 }
2029
2030 char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, struct ast_format_cap *ast_format_capability, int rtp_capability, const int asterisk_format, enum ast_rtp_options options)
2031 {
2032         int found = 0;
2033         const char *name;
2034         if (!buf) {
2035                 return NULL;
2036         }
2037
2038
2039         if (asterisk_format) {
2040                 int x;
2041                 struct ast_format *tmp_fmt;
2042                 for (x = 0; x < ast_format_cap_count(ast_format_capability); x++) {
2043                         tmp_fmt = ast_format_cap_get_format(ast_format_capability, x);
2044                         name = ast_rtp_lookup_mime_subtype2(asterisk_format, tmp_fmt, 0, options);
2045                         ao2_ref(tmp_fmt, -1);
2046                         ast_str_append(&buf, 0, "%s|", name);
2047                         found = 1;
2048                 }
2049         } else {
2050                 int x;
2051                 ast_str_append(&buf, 0, "0x%x (", (unsigned int) rtp_capability);
2052                 for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
2053                         if (rtp_capability & x) {
2054                                 name = ast_rtp_lookup_mime_subtype2(asterisk_format, NULL, x, options);
2055                                 ast_str_append(&buf, 0, "%s|", name);
2056                                 found = 1;
2057                         }
2058                 }
2059         }
2060
2061         ast_str_append(&buf, 0, "%s", found ? ")" : "nothing)");
2062
2063         return ast_str_buffer(buf);
2064 }
2065
2066 int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
2067 {
2068         int res;
2069
2070         if (instance->engine->dtmf_begin) {
2071                 ao2_lock(instance);
2072                 res = instance->engine->dtmf_begin(instance, digit);
2073                 ao2_unlock(instance);
2074         } else {
2075                 res = -1;
2076         }
2077         return res;
2078 }
2079
2080 int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
2081 {
2082         int res;
2083
2084         if (instance->engine->dtmf_end) {
2085                 ao2_lock(instance);
2086                 res = instance->engine->dtmf_end(instance, digit);
2087                 ao2_unlock(instance);
2088         } else {
2089                 res = -1;
2090         }
2091         return res;
2092 }
2093
2094 int ast_rtp_instance_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
2095 {
2096         int res;
2097
2098         if (instance->engine->dtmf_end_with_duration) {
2099                 ao2_lock(instance);
2100                 res = instance->engine->dtmf_end_with_duration(instance, digit, duration);
2101                 ao2_unlock(instance);
2102         } else {
2103                 res = -1;
2104         }
2105         return res;
2106 }
2107
2108 int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
2109 {
2110         int res;
2111
2112         if (instance->engine->dtmf_mode_set) {
2113                 ao2_lock(instance);
2114                 res = instance->engine->dtmf_mode_set(instance, dtmf_mode);
2115                 ao2_unlock(instance);
2116         } else {
2117                 res = -1;
2118         }
2119         return res;
2120 }
2121
2122 enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
2123 {
2124         int res;
2125
2126         if (instance->engine->dtmf_mode_get) {
2127                 ao2_lock(instance);
2128                 res = instance->engine->dtmf_mode_get(instance);
2129                 ao2_unlock(instance);
2130         } else {
2131                 res = 0;
2132         }
2133         return res;
2134 }
2135
2136 void ast_rtp_instance_update_source(struct ast_rtp_instance *instance)
2137 {
2138         if (instance->engine->update_source) {
2139                 ao2_lock(instance);
2140                 instance->engine->update_source(instance);
2141                 ao2_unlock(instance);
2142         }
2143 }
2144
2145 void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
2146 {
2147         if (instance->engine->change_source) {
2148                 ao2_lock(instance);
2149                 instance->engine->change_source(instance);
2150                 ao2_unlock(instance);
2151         }
2152 }
2153
2154 int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
2155 {
2156         int res;
2157
2158         if (instance->engine->qos) {
2159                 ao2_lock(instance);
2160                 res = instance->engine->qos(instance, tos, cos, desc);
2161                 ao2_unlock(instance);
2162         } else {
2163                 res = -1;
2164         }
2165         return res;
2166 }
2167
2168 void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
2169 {
2170         if (instance->engine->stop) {
2171                 ao2_lock(instance);
2172                 instance->engine->stop(instance);
2173                 ao2_unlock(instance);
2174         }
2175 }
2176
2177 int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
2178 {
2179         int res;
2180
2181         if (instance->engine->fd) {
2182                 ao2_lock(instance);
2183                 res = instance->engine->fd(instance, rtcp);
2184                 ao2_unlock(instance);
2185         } else {
2186                 res = -1;
2187         }
2188         return res;
2189 }
2190
2191 struct ast_rtp_glue *ast_rtp_instance_get_glue(const char *type)
2192 {
2193         struct ast_rtp_glue *glue = NULL;
2194
2195         AST_RWLIST_RDLOCK(&glues);
2196
2197         AST_RWLIST_TRAVERSE(&glues, glue, entry) {
2198                 if (!strcasecmp(glue->type, type)) {
2199                         break;
2200                 }
2201         }
2202
2203         AST_RWLIST_UNLOCK(&glues);
2204
2205         return glue;
2206 }
2207
2208 /*!
2209  * \brief Conditionally unref an rtp instance
2210  */
2211 static void unref_instance_cond(struct ast_rtp_instance **instance)
2212 {
2213         if (*instance) {
2214                 ao2_ref(*instance, -1);
2215                 *instance = NULL;
2216         }
2217 }
2218
2219 struct ast_rtp_instance *ast_rtp_instance_get_bridged(struct ast_rtp_instance *instance)
2220 {
2221         struct ast_rtp_instance *bridged;
2222
2223         ao2_lock(instance);
2224         bridged = instance->bridged;
2225         ao2_unlock(instance);
2226         return bridged;
2227 }
2228
2229 void ast_rtp_instance_set_bridged(struct ast_rtp_instance *instance, struct ast_rtp_instance *bridged)
2230 {
2231         ao2_lock(instance);
2232         instance->bridged = bridged;
2233         ao2_unlock(instance);
2234 }
2235
2236 void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c_dst, struct ast_channel *c_src)
2237 {
2238         struct ast_rtp_instance *instance_dst = NULL, *instance_src = NULL,
2239                 *vinstance_dst = NULL, *vinstance_src = NULL,
2240                 *tinstance_dst = NULL, *tinstance_src = NULL;
2241         struct ast_rtp_glue *glue_dst, *glue_src;
2242         enum ast_rtp_glue_result audio_glue_dst_res = AST_RTP_GLUE_RESULT_FORBID, video_glue_dst_res = AST_RTP_GLUE_RESULT_FORBID;
2243         enum ast_rtp_glue_result audio_glue_src_res = AST_RTP_GLUE_RESULT_FORBID, video_glue_src_res = AST_RTP_GLUE_RESULT_FORBID;
2244         struct ast_format_cap *cap_dst = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
2245         struct ast_format_cap *cap_src = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
2246
2247         /* Lock both channels so we can look for the glue that binds them together */
2248         ast_channel_lock_both(c_dst, c_src);
2249
2250         if (!cap_src || !cap_dst) {
2251                 goto done;
2252         }
2253
2254         /* Grab glue that binds each channel to something using the RTP engine */
2255         if (!(glue_dst = ast_rtp_instance_get_glue(ast_channel_tech(c_dst)->type)) || !(glue_src = ast_rtp_instance_get_glue(ast_channel_tech(c_src)->type))) {
2256                 ast_debug(1, "Can't find native functions for channel '%s'\n", glue_dst ? ast_channel_name(c_src) : ast_channel_name(c_dst));
2257                 goto done;
2258         }
2259
2260         audio_glue_dst_res = glue_dst->get_rtp_info(c_dst, &instance_dst);
2261         video_glue_dst_res = glue_dst->get_vrtp_info ? glue_dst->get_vrtp_info(c_dst, &vinstance_dst) : AST_RTP_GLUE_RESULT_FORBID;
2262
2263         audio_glue_src_res = glue_src->get_rtp_info(c_src, &instance_src);
2264         video_glue_src_res = glue_src->get_vrtp_info ? glue_src->get_vrtp_info(c_src, &vinstance_src) : AST_RTP_GLUE_RESULT_FORBID;
2265
2266         /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
2267         if (video_glue_dst_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue_dst_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue_dst_res != AST_RTP_GLUE_RESULT_REMOTE)) {
2268                 audio_glue_dst_res = AST_RTP_GLUE_RESULT_FORBID;
2269         }
2270         if (video_glue_src_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue_src_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue_src_res != AST_RTP_GLUE_RESULT_REMOTE)) {
2271                 audio_glue_src_res = AST_RTP_GLUE_RESULT_FORBID;
2272         }
2273         if (audio_glue_dst_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue_dst_res == AST_RTP_GLUE_RESULT_FORBID || video_glue_dst_res == AST_RTP_GLUE_RESULT_REMOTE) && glue_dst->get_codec) {
2274                 glue_dst->get_codec(c_dst, cap_dst);
2275         }
2276         if (audio_glue_src_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue_src_res == AST_RTP_GLUE_RESULT_FORBID || video_glue_src_res == AST_RTP_GLUE_RESULT_REMOTE) && glue_src->get_codec) {
2277                 glue_src->get_codec(c_src, cap_src);
2278         }
2279
2280         /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
2281         if (audio_glue_dst_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue_src_res != AST_RTP_GLUE_RESULT_REMOTE) {
2282                 goto done;
2283         }
2284
2285         /* Make sure we have matching codecs */
2286         if (!ast_format_cap_iscompatible(cap_dst, cap_src)) {
2287                 goto done;
2288         }
2289
2290         ast_rtp_codecs_payloads_xover(&instance_src->codecs, &instance_dst->codecs, instance_dst);
2291
2292         if (vinstance_dst && vinstance_src) {
2293                 ast_rtp_codecs_payloads_xover(&vinstance_src->codecs, &vinstance_dst->codecs, vinstance_dst);
2294         }
2295         if (tinstance_dst && tinstance_src) {
2296                 ast_rtp_codecs_payloads_xover(&tinstance_src->codecs, &tinstance_dst->codecs, tinstance_dst);
2297         }
2298
2299         if (glue_dst->update_peer(c_dst, instance_src, vinstance_src, tinstance_src, cap_src, 0)) {
2300                 ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n",
2301                         ast_channel_name(c_dst), ast_channel_name(c_src));
2302         } else {
2303                 ast_debug(1, "Seeded SDP of '%s' with that of '%s'\n",
2304                         ast_channel_name(c_dst), ast_channel_name(c_src));
2305         }
2306
2307 done:
2308         ast_channel_unlock(c_dst);
2309         ast_channel_unlock(c_src);
2310
2311         ao2_cleanup(cap_dst);
2312         ao2_cleanup(cap_src);
2313
2314         unref_instance_cond(&instance_dst);
2315         unref_instance_cond(&instance_src);
2316         unref_instance_cond(&vinstance_dst);
2317         unref_instance_cond(&vinstance_src);
2318         unref_instance_cond(&tinstance_dst);
2319         unref_instance_cond(&tinstance_src);
2320 }
2321
2322 int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
2323 {
2324         struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
2325                         *vinstance0 = NULL, *vinstance1 = NULL,
2326                         *tinstance0 = NULL, *tinstance1 = NULL;
2327         struct ast_rtp_glue *glue0, *glue1;
2328         enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
2329         enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
2330         struct ast_format_cap *cap0 = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
2331         struct ast_format_cap *cap1 = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
2332
2333         /* If there is no second channel just immediately bail out, we are of no use in that scenario */
2334         if (!c1 || !cap1 || !cap0) {
2335                 ao2_cleanup(cap0);
2336                 ao2_cleanup(cap1);
2337                 return -1;
2338         }
2339
2340         /* Lock both channels so we can look for the glue that binds them together */
2341         ast_channel_lock_both(c0, c1);
2342
2343         /* Grab glue that binds each channel to something using the RTP engine */
2344         if (!(glue0 = ast_rtp_instance_get_glue(ast_channel_tech(c0)->type)) || !(glue1 = ast_rtp_instance_get_glue(ast_channel_tech(c1)->type))) {
2345                 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", glue0 ? ast_channel_name(c1) : ast_channel_name(c0));
2346                 goto done;
2347         }
2348
2349         audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
2350         video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
2351
2352         audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
2353         video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
2354
2355         /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
2356         if (video_glue0_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue0_res != AST_RTP_GLUE_RESULT_REMOTE)) {
2357                 audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
2358         }
2359         if (video_glue1_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue1_res != AST_RTP_GLUE_RESULT_REMOTE)) {
2360                 audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
2361         }
2362         if (audio_glue0_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue0_res == AST_RTP_GLUE_RESULT_FORBID || video_glue0_res == AST_RTP_GLUE_RESULT_REMOTE) && glue0->get_codec) {
2363                 glue0->get_codec(c0, cap0);
2364         }
2365         if (audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue1_res == AST_RTP_GLUE_RESULT_FORBID || video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) && glue1->get_codec) {
2366                 glue1->get_codec(c1, cap1);
2367         }
2368
2369         /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
2370         if (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE) {
2371                 goto done;
2372         }
2373
2374         /* Make sure we have matching codecs */
2375         if (!ast_format_cap_iscompatible(cap0, cap1)) {
2376                 goto done;
2377         }
2378
2379         /* Bridge media early */
2380         if (glue0->update_peer(c0, instance1, vinstance1, tinstance1, cap1, 0)) {
2381                 ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", ast_channel_name(c0), c1 ? ast_channel_name(c1) : "<unspecified>");
2382         }
2383
2384 done:
2385         ast_channel_unlock(c0);
2386         ast_channel_unlock(c1);
2387
2388         ao2_cleanup(cap0);
2389         ao2_cleanup(cap1);
2390
2391         unref_instance_cond(&instance0);
2392         unref_instance_cond(&instance1);
2393         unref_instance_cond(&vinstance0);
2394         unref_instance_cond(&vinstance1);
2395         unref_instance_cond(&tinstance0);
2396         unref_instance_cond(&tinstance1);
2397
2398         ast_debug(1, "Setting early bridge SDP of '%s' with that of '%s'\n", ast_channel_name(c0), c1 ? ast_channel_name(c1) : "<unspecified>");
2399
2400         return 0;
2401 }
2402
2403 int ast_rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations)
2404 {
2405         int res;
2406
2407         if (instance->engine->red_init) {
2408                 ao2_lock(instance);
2409                 res = instance->engine->red_init(instance, buffer_time, payloads, generations);
2410                 ao2_unlock(instance);
2411         } else {
2412                 res = -1;
2413         }
2414         return res;
2415 }
2416
2417 int ast_rtp_red_buffer(struct ast_rtp_instance *instance, struct ast_frame *frame)
2418 {
2419         int res;
2420
2421         if (instance->engine->red_buffer) {
2422                 ao2_lock(instance);
2423                 res = instance->engine->red_buffer(instance, frame);
2424                 ao2_unlock(instance);
2425         } else {
2426                 res = -1;
2427         }
2428         return res;
2429 }
2430
2431 int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
2432 {
2433         int res;
2434
2435         if (instance->engine->get_stat) {
2436                 ao2_lock(instance);
2437                 res = instance->engine->get_stat(instance, stats, stat);
2438                 ao2_unlock(instance);
2439         } else {
2440                 res = -1;
2441         }
2442         return res;
2443 }
2444
2445 char *ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_rtp_instance_stat_field field, char *buf, size_t size)
2446 {
2447         struct ast_rtp_instance_stats stats = { 0, };
2448         enum ast_rtp_instance_stat stat;
2449
2450         /* Determine what statistics we will need to retrieve based on field passed in */
2451         if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY) {
2452                 stat = AST_RTP_INSTANCE_STAT_ALL;
2453         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER) {
2454                 stat = AST_RTP_INSTANCE_STAT_COMBINED_JITTER;
2455         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS) {
2456                 stat = AST_RTP_INSTANCE_STAT_COMBINED_LOSS;
2457         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT) {
2458                 stat = AST_RTP_INSTANCE_STAT_COMBINED_RTT;
2459         } else {
2460                 return NULL;
2461         }
2462
2463         /* Attempt to actually retrieve the statistics we need to generate the quality string */
2464         if (ast_rtp_instance_get_stats(instance, &stats, stat)) {
2465                 return NULL;
2466         }
2467
2468         /* Now actually fill the buffer with the good information */
2469         if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY) {
2470                 snprintf(buf, size, "ssrc=%u;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f",
2471                          stats.local_ssrc, stats.remote_ssrc, stats.rxploss, stats.rxjitter, stats.rxcount, stats.txjitter, stats.txcount, stats.txploss, stats.rtt);
2472         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER) {
2473                 snprintf(buf, size, "minrxjitter=%f;maxrxjitter=%f;avgrxjitter=%f;stdevrxjitter=%f;reported_minjitter=%f;reported_maxjitter=%f;reported_avgjitter=%f;reported_stdevjitter=%f;",
2474                          stats.local_minjitter, stats.local_maxjitter, stats.local_normdevjitter, sqrt(stats.local_stdevjitter), stats.remote_minjitter, stats.remote_maxjitter, stats.remote_normdevjitter, sqrt(stats.remote_stdevjitter));
2475         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS) {
2476                 snprintf(buf, size, "minrxlost=%f;maxrxlost=%f;avgrxlost=%f;stdevrxlost=%f;reported_minlost=%f;reported_maxlost=%f;reported_avglost=%f;reported_stdevlost=%f;",
2477                          stats.local_minrxploss, stats.local_maxrxploss, stats.local_normdevrxploss, sqrt(stats.local_stdevrxploss), stats.remote_minrxploss, stats.remote_maxrxploss, stats.remote_normdevrxploss, sqrt(stats.remote_stdevrxploss));
2478         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT) {
2479                 snprintf(buf, size, "minrtt=%f;maxrtt=%f;avgrtt=%f;stdevrtt=%f;", stats.minrtt, stats.maxrtt, stats.normdevrtt, stats.stdevrtt);
2480         }
2481
2482         return buf;
2483 }
2484
2485 void ast_rtp_instance_set_stats_vars(struct ast_channel *chan, struct ast_rtp_instance *instance)
2486 {
2487         char quality_buf[AST_MAX_USER_FIELD];
2488         char *quality;
2489         struct ast_channel *bridge;
2490
2491         bridge = ast_channel_bridge_peer(chan);
2492         if (bridge) {
2493                 ast_channel_lock_both(chan, bridge);
2494                 ast_channel_stage_snapshot(bridge);
2495         } else {
2496                 ast_channel_lock(chan);
2497         }
2498         ast_channel_stage_snapshot(chan);
2499
2500         quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY,
2501                 quality_buf, sizeof(quality_buf));
2502         if (quality) {
2503                 pbx_builtin_setvar_helper(chan, "RTPAUDIOQOS", quality);
2504                 if (bridge) {
2505                         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSBRIDGED", quality);
2506                 }
2507         }
2508
2509         quality = ast_rtp_instance_get_quality(instance,
2510                 AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf));
2511         if (quality) {
2512                 pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSJITTER", quality);
2513                 if (bridge) {
2514                         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSJITTERBRIDGED", quality);
2515                 }
2516         }
2517
2518         quality = ast_rtp_instance_get_quality(instance,
2519                 AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf));
2520         if (quality) {
2521                 pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSLOSS", quality);
2522                 if (bridge) {
2523                         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSLOSSBRIDGED", quality);
2524                 }
2525         }
2526
2527         quality = ast_rtp_instance_get_quality(instance,
2528                 AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf));
2529         if (quality) {
2530                 pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSRTT", quality);
2531                 if (bridge) {
2532                         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSRTTBRIDGED", quality);
2533                 }
2534         }
2535
2536         ast_channel_stage_snapshot_done(chan);
2537         ast_channel_unlock(chan);
2538         if (bridge) {
2539                 ast_channel_stage_snapshot_done(bridge);
2540                 ast_channel_unlock(bridge);
2541                 ast_channel_unref(bridge);
2542         }
2543 }
2544
2545 int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, struct ast_format *format)
2546 {
2547         int res;
2548
2549         if (instance->engine->set_read_format) {
2550                 ao2_lock(instance);
2551                 res = instance->engine->set_read_format(instance, format);
2552                 ao2_unlock(instance);
2553         } else {
2554                 res = -1;
2555         }
2556         return res;
2557 }
2558
2559 int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, struct ast_format *format)
2560 {
2561         int res;
2562
2563         if (instance->engine->set_read_format) {
2564                 ao2_lock(instance);
2565                 res = instance->engine->set_write_format(instance, format);
2566                 ao2_unlock(instance);
2567         } else {
2568                 res = -1;
2569         }
2570         return res;
2571 }
2572
2573 /* XXX Nothing calls this */
2574 int ast_rtp_instance_make_compatible(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_channel *peer)
2575 {
2576         struct ast_rtp_glue *glue;
2577         struct ast_rtp_instance *peer_instance = NULL;
2578         int res = -1;
2579
2580         if (!instance->engine->make_compatible) {
2581                 return -1;
2582         }
2583
2584         ast_channel_lock(peer);
2585
2586         if (!(glue = ast_rtp_instance_get_glue(ast_channel_tech(peer)->type))) {
2587                 ast_channel_unlock(peer);
2588                 return -1;
2589         }
2590
2591         glue->get_rtp_info(peer, &peer_instance);
2592         if (!peer_instance) {
2593                 ast_log(LOG_ERROR, "Unable to get_rtp_info for peer type %s\n", glue->type);
2594                 ast_channel_unlock(peer);
2595                 return -1;
2596         }
2597         if (peer_instance->engine != instance->engine) {
2598                 ast_log(LOG_ERROR, "Peer engine mismatch for type %s\n", glue->type);
2599                 ast_channel_unlock(peer);
2600                 ao2_ref(peer_instance, -1);
2601                 return -1;
2602         }
2603
2604         /*
2605          * XXX Good thing nothing calls this function because we would need
2606          * deadlock avoidance to get the two instance locks.
2607          */
2608         res = instance->engine->make_compatible(chan, instance, peer, peer_instance);
2609
2610         ast_channel_unlock(peer);
2611
2612         ao2_ref(peer_instance, -1);
2613         peer_instance = NULL;
2614
2615         return res;
2616 }
2617
2618 void ast_rtp_instance_available_formats(struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result)
2619 {
2620         if (instance->engine->available_formats) {
2621                 ao2_lock(instance);
2622                 instance->engine->available_formats(instance, to_endpoint, to_asterisk, result);
2623                 ao2_unlock(instance);
2624                 if (ast_format_cap_count(result)) {
2625                         return;
2626                 }
2627         }
2628
2629         ast_translate_available_formats(to_endpoint, to_asterisk, result);
2630 }
2631
2632 int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
2633 {
2634         int res;
2635
2636         if (instance->engine->activate) {
2637                 ao2_lock(instance);
2638                 res = instance->engine->activate(instance);
2639                 ao2_unlock(instance);
2640         } else {
2641                 res = 0;
2642         }
2643         return res;
2644 }
2645
2646 void ast_rtp_instance_stun_request(struct ast_rtp_instance *instance,
2647                                    struct ast_sockaddr *suggestion,
2648                                    const char *username)
2649 {
2650         if (instance->engine->stun_request) {
2651                 instance->engine->stun_request(instance, suggestion, username);
2652         }
2653 }
2654
2655 void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
2656 {
2657         instance->timeout = timeout;
2658 }
2659
2660 void ast_rtp_instance_set_hold_timeout(struct ast_rtp_instance *instance, int timeout)
2661 {
2662         instance->holdtimeout = timeout;
2663 }
2664
2665 void ast_rtp_instance_set_keepalive(struct ast_rtp_instance *instance, int interval)
2666 {
2667         instance->keepalive = interval;
2668 }
2669
2670 int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance)
2671 {
2672         return instance->timeout;
2673 }
2674
2675 int ast_rtp_instance_get_hold_timeout(struct ast_rtp_instance *instance)
2676 {
2677         return instance->holdtimeout;
2678 }
2679
2680 int ast_rtp_instance_get_keepalive(struct ast_rtp_instance *instance)
2681 {
2682         return instance->keepalive;
2683 }
2684
2685 struct ast_rtp_engine *ast_rtp_instance_get_engine(struct ast_rtp_instance *instance)
2686 {
2687         return instance->engine;
2688 }
2689
2690 struct ast_rtp_glue *ast_rtp_instance_get_active_glue(struct ast_rtp_instance *instance)
2691 {
2692         return instance->glue;
2693 }
2694
2695 int ast_rtp_engine_register_srtp(struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res)
2696 {
2697         if (res_srtp || res_srtp_policy) {
2698                 return -1;
2699         }
2700         if (!srtp_res || !policy_res) {
2701                 return -1;
2702         }
2703
2704         res_srtp = srtp_res;
2705         res_srtp_policy = policy_res;
2706
2707         return 0;
2708 }
2709
2710 void ast_rtp_engine_unregister_srtp(void)
2711 {
2712         res_srtp = NULL;
2713         res_srtp_policy = NULL;
2714 }
2715
2716 int ast_rtp_engine_srtp_is_registered(void)
2717 {
2718         return res_srtp && res_srtp_policy;
2719 }
2720
2721 int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy *remote_policy, struct ast_srtp_policy *local_policy, int rtcp)
2722 {
2723         int res = 0;
2724         struct ast_srtp **srtp;
2725
2726         if (!res_srtp) {
2727                 return -1;
2728         }
2729
2730
2731         srtp = rtcp ? &instance->rtcp_srtp : &instance->srtp;
2732
2733         if (!*srtp) {
2734                 res = res_srtp->create(srtp, instance, remote_policy);
2735         } else if (remote_policy) {
2736                 res = res_srtp->replace(srtp, instance, remote_policy);
2737         }
2738         if (!res) {
2739                 res = res_srtp->add_stream(*srtp, local_policy);
2740         }
2741
2742         return res;
2743 }
2744
2745 struct ast_srtp *ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance, int rtcp)
2746 {
2747         if (rtcp && instance->rtcp_srtp) {
2748                 return instance->rtcp_srtp;
2749         } else {
2750                 return instance->srtp;
2751         }
2752 }
2753
2754 int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level)
2755 {
2756         int res;
2757
2758         if (instance->engine->sendcng) {
2759                 ao2_lock(instance);
2760                 res = instance->engine->sendcng(instance, level);
2761                 ao2_unlock(instance);
2762         } else {
2763                 res = -1;
2764         }
2765         return res;
2766 }
2767
2768 static void rtp_ice_wrap_set_authentication(struct ast_rtp_instance *instance, const char *ufrag, const char *password)
2769 {
2770         ao2_lock(instance);
2771         instance->engine->ice->set_authentication(instance, ufrag, password);
2772         ao2_unlock(instance);
2773 }
2774
2775 static void rtp_ice_wrap_add_remote_candidate(struct ast_rtp_instance *instance, const struct ast_rtp_engine_ice_candidate *candidate)
2776 {
2777         ao2_lock(instance);
2778         instance->engine->ice->add_remote_candidate(instance, candidate);
2779         ao2_unlock(instance);
2780 }
2781
2782 static void rtp_ice_wrap_start(struct ast_rtp_instance *instance)
2783 {
2784         ao2_lock(instance);
2785         instance->engine->ice->start(instance);
2786         ao2_unlock(instance);
2787 }
2788
2789 static void rtp_ice_wrap_stop(struct ast_rtp_instance *instance)
2790 {
2791         ao2_lock(instance);
2792         instance->engine->ice->stop(instance);
2793         ao2_unlock(instance);
2794 }
2795
2796 static const char *rtp_ice_wrap_get_ufrag(struct ast_rtp_instance *instance)
2797 {
2798         const char *ufrag;
2799
2800         ao2_lock(instance);
2801         ufrag = instance->engine->ice->get_ufrag(instance);
2802         ao2_unlock(instance);
2803         return ufrag;
2804 }
2805
2806 static const char *rtp_ice_wrap_get_password(struct ast_rtp_instance *instance)
2807 {
2808         const char *password;
2809
2810         ao2_lock(instance);
2811         password = instance->engine->ice->get_password(instance);
2812         ao2_unlock(instance);
2813         return password;
2814 }
2815
2816 static struct ao2_container *rtp_ice_wrap_get_local_candidates(struct ast_rtp_instance *instance)
2817 {
2818         struct ao2_container *local_candidates;
2819
2820         ao2_lock(instance);
2821         local_candidates = instance->engine->ice->get_local_candidates(instance);
2822         ao2_unlock(instance);
2823         return local_candidates;
2824 }
2825
2826 static void rtp_ice_wrap_ice_lite(struct ast_rtp_instance *instance)
2827 {
2828         ao2_lock(instance);
2829         instance->engine->ice->ice_lite(instance);
2830         ao2_unlock(instance);
2831 }
2832
2833 static void rtp_ice_wrap_set_role(struct ast_rtp_instance *instance,
2834         enum ast_rtp_ice_role role)
2835 {
2836         ao2_lock(instance);
2837         instance->engine->ice->set_role(instance, role);
2838         ao2_unlock(instance);
2839 }
2840
2841 static void rtp_ice_wrap_turn_request(struct ast_rtp_instance *instance,
2842         enum ast_rtp_ice_component_type component, enum ast_transport transport,
2843         const char *server, unsigned int port, const char *username, const char *password)
2844 {
2845         ao2_lock(instance);
2846         instance->engine->ice->turn_request(instance, component, transport, server, port,
2847                 username, password);
2848         ao2_unlock(instance);
2849 }
2850
2851 static void rtp_ice_wrap_change_components(struct ast_rtp_instance *instance,
2852         int num_components)
2853 {
2854         ao2_lock(instance);
2855         instance->engine->ice->change_components(instance, num_components);
2856         ao2_unlock(instance);
2857 }
2858
2859 static struct ast_rtp_engine_ice rtp_ice_wrappers = {
2860         .set_authentication = rtp_ice_wrap_set_authentication,
2861         .add_remote_candidate = rtp_ice_wrap_add_remote_candidate,
2862         .start = rtp_ice_wrap_start,
2863         .stop = rtp_ice_wrap_stop,
2864         .get_ufrag = rtp_ice_wrap_get_ufrag,
2865         .get_password = rtp_ice_wrap_get_password,
2866         .get_local_candidates = rtp_ice_wrap_get_local_candidates,
2867         .ice_lite = rtp_ice_wrap_ice_lite,
2868         .set_role = rtp_ice_wrap_set_role,
2869         .turn_request = rtp_ice_wrap_turn_request,
2870         .change_components = rtp_ice_wrap_change_components,
2871 };
2872
2873 struct ast_rtp_engine_ice *ast_rtp_instance_get_ice(struct ast_rtp_instance *instance)
2874 {
2875         if (instance->engine->ice) {
2876                 return &rtp_ice_wrappers;
2877         }
2878         /* ICE not available */
2879         return NULL;
2880 }
2881
2882 static int rtp_dtls_wrap_set_configuration(struct ast_rtp_instance *instance,
2883         const struct ast_rtp_dtls_cfg *dtls_cfg)
2884 {
2885         int set_configuration;
2886
2887         ao2_lock(instance);
2888         set_configuration = instance->engine->dtls->set_configuration(instance, dtls_cfg);
2889         ao2_unlock(instance);
2890         return set_configuration;
2891 }
2892
2893 static int rtp_dtls_wrap_active(struct ast_rtp_instance *instance)
2894 {
2895         int active;
2896
2897         ao2_lock(instance);
2898         active = instance->engine->dtls->active(instance);
2899         ao2_unlock(instance);
2900         return active;
2901 }
2902
2903 static void rtp_dtls_wrap_stop(struct ast_rtp_instance *instance)
2904 {
2905         ao2_lock(instance);
2906         instance->engine->dtls->stop(instance);
2907         ao2_unlock(instance);
2908 }
2909
2910 static void rtp_dtls_wrap_reset(struct ast_rtp_instance *instance)
2911 {
2912         ao2_lock(instance);
2913         instance->engine->dtls->reset(instance);
2914         ao2_unlock(instance);
2915 }
2916
2917 static enum ast_rtp_dtls_connection rtp_dtls_wrap_get_connection(struct ast_rtp_instance *instance)
2918 {
2919         enum ast_rtp_dtls_connection get_connection;
2920
2921         ao2_lock(instance);
2922         get_connection = instance->engine->dtls->get_connection(instance);
2923         ao2_unlock(instance);
2924         return get_connection;
2925 }
2926
2927 static enum ast_rtp_dtls_setup rtp_dtls_wrap_get_setup(struct ast_rtp_instance *instance)
2928 {
2929         enum ast_rtp_dtls_setup get_setup;
2930
2931         ao2_lock(instance);
2932         get_setup = instance->engine->dtls->get_setup(instance);
2933         ao2_unlock(instance);
2934         return get_setup;
2935 }
2936
2937 static void rtp_dtls_wrap_set_setup(struct ast_rtp_instance *instance,
2938         enum ast_rtp_dtls_setup setup)
2939 {
2940         ao2_lock(instance);
2941         instance->engine->dtls->set_setup(instance, setup);
2942         ao2_unlock(instance);
2943 }
2944
2945 static void rtp_dtls_wrap_set_fingerprint(struct ast_rtp_instance *instance,
2946         enum ast_rtp_dtls_hash hash, const char *fingerprint)
2947 {
2948         ao2_lock(instance);
2949         instance->engine->dtls->set_fingerprint(instance, hash, fingerprint);
2950         ao2_unlock(instance);
2951 }
2952
2953 static enum ast_rtp_dtls_hash rtp_dtls_wrap_get_fingerprint_hash(struct ast_rtp_instance *instance)
2954 {
2955         enum ast_rtp_dtls_hash get_fingerprint_hash;
2956
2957         ao2_lock(instance);
2958         get_fingerprint_hash = instance->engine->dtls->get_fingerprint_hash(instance);
2959         ao2_unlock(instance);
2960         return get_fingerprint_hash;
2961 }
2962
2963 static const char *rtp_dtls_wrap_get_fingerprint(struct ast_rtp_instance *instance)
2964 {
2965         const char *get_fingerprint;
2966
2967         ao2_lock(instance);
2968         get_fingerprint = instance->engine->dtls->get_fingerprint(instance);
2969         ao2_unlock(instance);
2970         return get_fingerprint;
2971 }
2972
2973 static struct ast_rtp_engine_dtls rtp_dtls_wrappers = {
2974         .set_configuration = rtp_dtls_wrap_set_configuration,
2975         .active = rtp_dtls_wrap_active,
2976         .stop = rtp_dtls_wrap_stop,
2977         .reset = rtp_dtls_wrap_reset,
2978         .get_connection = rtp_dtls_wrap_get_connection,
2979         .get_setup = rtp_dtls_wrap_get_setup,
2980         .set_setup = rtp_dtls_wrap_set_setup,
2981         .set_fingerprint = rtp_dtls_wrap_set_fingerprint,
2982         .get_fingerprint_hash = rtp_dtls_wrap_get_fingerprint_hash,
2983         .get_fingerprint = rtp_dtls_wrap_get_fingerprint,
2984 };
2985
2986 struct ast_rtp_engine_dtls *ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
2987 {
2988         if (instance->engine->dtls) {
2989                 return &rtp_dtls_wrappers;
2990         }
2991         /* DTLS not available */
2992         return NULL;
2993 }
2994
2995 int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name, const char *value)
2996 {
2997         if (!strcasecmp(name, "dtlsenable")) {
2998                 dtls_cfg->enabled = ast_true(value) ? 1 : 0;
2999         } else if (!strcasecmp(name, "dtlsverify")) {
3000                 if (!strcasecmp(value, "yes")) {
3001                         dtls_cfg->verify = AST_RTP_DTLS_VERIFY_FINGERPRINT | AST_RTP_DTLS_VERIFY_CERTIFICATE;
3002                 } else if (!strcasecmp(value, "fingerprint")) {
3003                         dtls_cfg->verify = AST_RTP_DTLS_VERIFY_FINGERPRINT;
3004                 } else if (!strcasecmp(value, "certificate")) {
3005                         dtls_cfg->verify = AST_RTP_DTLS_VERIFY_CERTIFICATE;
3006                 } else if (!strcasecmp(value, "no")) {
3007                         dtls_cfg->verify = AST_RTP_DTLS_VERIFY_NONE;
3008                 } else {
3009                         return -1;
3010                 }
3011         } else if (!strcasecmp(name, "dtlsrekey")) {
3012                 if (sscanf(value, "%30u", &dtls_cfg->rekey) != 1) {
3013                         return -1;
3014                 }
3015         } else if (!strcasecmp(name, "dtlsautogeneratecert")) {
3016                 dtls_cfg->ephemeral_cert = ast_true(value) ? 1 : 0;
3017         } else if (!strcasecmp(name, "dtlscertfile")) {
3018                 if (!ast_strlen_zero(value) && !ast_file_is_readable(value)) {
3019                         ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
3020                         return -1;
3021                 }
3022                 ast_free(dtls_cfg->certfile);
3023                 dtls_cfg->certfile = ast_strdup(value);
3024         } else if (!strcasecmp(name, "dtlsprivatekey")) {
3025                 if (!ast_strlen_zero(value) && !ast_file_is_readable(value)) {
3026                         ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
3027                         return -1;
3028                 }
3029                 ast_free(dtls_cfg->pvtfile);
3030                 dtls_cfg->pvtfile = ast_strdup(value);
3031         } else if (!strcasecmp(name, "dtlscipher")) {
3032                 ast_free(dtls_cfg->cipher);
3033                 dtls_cfg->cipher = ast_strdup(value);
3034         } else if (!strcasecmp(name, "dtlscafile")) {
3035                 if (!ast_strlen_zero(value) && !ast_file_is_readable(value)) {
3036                         ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
3037                         return -1;
3038                 }
3039                 ast_free(dtls_cfg->cafile);
3040                 dtls_cfg->cafile = ast_strdup(value);
3041         } else if (!strcasecmp(name, "dtlscapath") || !strcasecmp(name, "dtlscadir")) {
3042                 if (!ast_strlen_zero(value) && !ast_file_is_readable(value)) {
3043                         ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
3044                         return -1;
3045                 }
3046                 ast_free(dtls_cfg->capath);
3047                 dtls_cfg->capath = ast_strdup(value);
3048         } else if (!strcasecmp(name, "dtlssetup")) {
3049                 if (!strcasecmp(value, "active")) {
3050                         dtls_cfg->default_setup = AST_RTP_DTLS_SETUP_ACTIVE;
3051                 } else if (!strcasecmp(value, "passive")) {
3052                         dtls_cfg->default_setup = AST_RTP_DTLS_SETUP_PASSIVE;
3053                 } else if (!strcasecmp(value, "actpass")) {
3054                         dtls_cfg->default_setup = AST_RTP_DTLS_SETUP_ACTPASS;
3055                 }
3056         } else if (!strcasecmp(name, "dtlsfingerprint")) {
3057                 if (!strcasecmp(value, "sha-256")) {
3058                         dtls_cfg->hash = AST_RTP_DTLS_HASH_SHA256;
3059                 } else if (!strcasecmp(value, "sha-1")) {
3060                         dtls_cfg->hash = AST_RTP_DTLS_HASH_SHA1;
3061                 }
3062         } else {
3063                 return -1;
3064         }
3065
3066         return 0;
3067 }
3068
3069 int ast_rtp_dtls_cfg_validate(struct ast_rtp_dtls_cfg *dtls_cfg)
3070 {
3071         if (dtls_cfg->ephemeral_cert) {
3072                 if (!ast_strlen_zero(dtls_cfg->certfile)) {
3073                         ast_log(LOG_ERROR, "You cannot request automatically generated certificates"
3074                                 " (dtls_auto_generate_cert) and also specify a certificate file"
3075                                 " (dtls_cert_file) at the same time\n");
3076                         return -1;
3077                 } else if (!ast_strlen_zero(dtls_cfg->pvtfile)
3078                                   || !ast_strlen_zero(dtls_cfg->cafile)
3079                                   || !ast_strlen_zero(dtls_cfg->capath)) {
3080                         ast_log(LOG_NOTICE, "dtls_pvt_file, dtls_cafile, and dtls_ca_path are"
3081                                 " ignored when dtls_auto_generate_cert is enabled\n");
3082                 }
3083         }
3084
3085         return 0;
3086 }
3087
3088 void ast_rtp_dtls_cfg_copy(const struct ast_rtp_dtls_cfg *src_cfg, struct ast_rtp_dtls_cfg *dst_cfg)
3089 {
3090         ast_rtp_dtls_cfg_free(dst_cfg);         /* Prevent a double-call leaking memory via ast_strdup */
3091
3092         dst_cfg->enabled = src_cfg->enabled;
3093         dst_cfg->verify = src_cfg->verify;
3094         dst_cfg->rekey = src_cfg->rekey;
3095         dst_cfg->suite = src_cfg->suite;
3096         dst_cfg->hash = src_cfg->hash;
3097         dst_cfg->ephemeral_cert = src_cfg->ephemeral_cert;
3098         dst_cfg->certfile = ast_strdup(src_cfg->certfile);
3099         dst_cfg->pvtfile = ast_strdup(src_cfg->pvtfile);
3100         dst_cfg->cipher = ast_strdup(src_cfg->cipher);
3101         dst_cfg->cafile = ast_strdup(src_cfg->cafile);
3102         dst_cfg->capath = ast_strdup(src_cfg->capath);
3103         dst_cfg->default_setup = src_cfg->default_setup;
3104 }
3105
3106 void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg)
3107 {
3108         ast_free(dtls_cfg->certfile);
3109         dtls_cfg->certfile = NULL;
3110         ast_free(dtls_cfg->pvtfile);
3111         dtls_cfg->pvtfile = NULL;
3112         ast_free(dtls_cfg->cipher);
3113         dtls_cfg->cipher = NULL;
3114         ast_free(dtls_cfg->cafile);
3115         dtls_cfg->cafile = NULL;
3116         ast_free(dtls_cfg->capath);
3117         dtls_cfg->capath = NULL;
3118 }
3119
3120 /*! \internal
3121  * \brief Small helper routine that cleans up entry i in
3122  * \c ast_rtp_mime_types.
3123  */
3124 static void rtp_engine_mime_type_cleanup(int i)
3125 {
3126         ao2_cleanup(ast_rtp_mime_types[i].payload_type.format);
3127         memset(&ast_rtp_mime_types[i], 0, sizeof(struct ast_rtp_mime_type));
3128 }
3129
3130 static void set_next_mime_type(struct ast_format *format, int rtp_code, const char *type, const char *subtype, unsigned int sample_rate)
3131 {
3132         int x;
3133
3134         ast_rwlock_wrlock(&mime_types_lock);
3135
3136         x = mime_types_len;
3137         if (ARRAY_LEN(ast_rtp_mime_types) <= x) {
3138                 ast_rwlock_unlock(&mime_types_lock);
3139                 return;
3140         }
3141
3142         /* Make sure any previous value in ast_rtp_mime_types is cleaned up */
3143         memset(&ast_rtp_mime_types[x], 0, sizeof(struct ast_rtp_mime_type));
3144         if (format) {
3145                 ast_rtp_mime_types[x].payload_type.asterisk_format = 1;
3146                 ast_rtp_mime_types[x].payload_type.format = ao2_bump(format);
3147         } else {
3148                 ast_rtp_mime_types[x].payload_type.rtp_code = rtp_code;
3149         }
3150         ast_copy_string(ast_rtp_mime_types[x].type, type, sizeof(ast_rtp_mime_types[x].type));
3151         ast_copy_string(ast_rtp_mime_types[x].subtype, subtype, sizeof(ast_rtp_mime_types[x].subtype));
3152         ast_rtp_mime_types[x].sample_rate = sample_rate;
3153         mime_types_len++;
3154
3155         ast_rwlock_unlock(&mime_types_lock);
3156 }
3157
3158 static void add_static_payload(int payload, struct ast_format *format, int rtp_code)
3159 {
3160         struct ast_rtp_payload_type *type;
3161
3162         /*
3163          * ARRAY_LEN's result is cast to an int so 'map' is not autocast to a size_t,
3164          * which if negative would cause an assertion.
3165          */
3166         ast_assert(payload < (int)ARRAY_LEN(static_RTP_PT));
3167
3168         if (ast_option_rtpusedynamic && payload < 0) {
3169                 /*
3170                  * We're going to build dynamic payloads dynamically. An RTP code is
3171                  * required otherwise one will be dynamically allocated per instance.
3172                  */
3173                 return;
3174         }
3175
3176         /*
3177          * Either the given payload is truly a static type, or Asterisk is
3178          * globally storing the dynamic payloads in the static_RTP_PT object.
3179          */
3180         ast_rwlock_wrlock(&static_RTP_PT_lock);
3181
3182         if (payload < 0) {
3183                 /*
3184                  * This is a dynamic payload that will be stored globally,
3185                  * so find the next available empty slot.
3186                  */
3187                 payload = find_unused_payload(NULL);
3188                 if (payload < 0) {
3189                         ast_log(LOG_WARNING, "No dynamic RTP payload type values available "
3190                                 "for %s - %d!\n", format ? ast_format_get_name(format) : "", rtp_code);
3191                         ast_rwlock_unlock(&static_RTP_PT_lock);
3192                         return;
3193                 }
3194         }
3195
3196         type = rtp_payload_type_alloc(format, payload, rtp_code, 1);
3197         if (type) {
3198                 ao2_cleanup(static_RTP_PT[payload]);
3199                 static_RTP_PT[payload] = type;
3200         }
3201         ast_rwlock_unlock(&static_RTP_PT_lock);
3202 }
3203
3204 int ast_rtp_engine_load_format(struct ast_format *format)
3205 {
3206         char *codec_name = ast_strdupa(ast_format_get_codec_name(format));
3207
3208         codec_name = ast_str_to_upper(codec_name);
3209
3210         set_next_mime_type(format,
3211                 0,
3212                 ast_codec_media_type2str(ast_format_get_type(format)),
3213                 codec_name,
3214                 ast_format_get_sample_rate(format));
3215         add_static_payload(-1, format, 0);
3216
3217         return 0;
3218 }
3219
3220 int ast_rtp_engine_unload_format(struct ast_format *format)
3221 {
3222         int x;
3223         int y = 0;
3224
3225         ast_rwlock_wrlock(&static_RTP_PT_lock);
3226         /* remove everything pertaining to this format id from the lists */
3227         for (x = 0; x < AST_RTP_MAX_PT; x++) {
3228                 if (static_RTP_PT[x]
3229                         && ast_format_cmp(static_RTP_PT[x]->format, format) == AST_FORMAT_CMP_EQUAL) {
3230                         ao2_ref(static_RTP_PT[x], -1);
3231                         static_RTP_PT[x] = NULL;
3232                 }
3233         }
3234         ast_rwlock_unlock(&static_RTP_PT_lock);
3235
3236         ast_rwlock_wrlock(&mime_types_lock);
3237         /* rebuild the list skipping the items matching this id */
3238         for (x = 0; x < mime_types_len; x++) {
3239                 if (ast_format_cmp(ast_rtp_mime_types[x].payload_type.format, format) == AST_FORMAT_CMP_EQUAL) {
3240                         rtp_engine_mime_type_cleanup(x);
3241                         continue;
3242                 }
3243                 if (x != y) {
3244                         ast_rtp_mime_types[y] = ast_rtp_mime_types[x];
3245                 }
3246                 y++;
3247         }
3248         mime_types_len = y;
3249         ast_rwlock_unlock(&mime_types_lock);
3250         return 0;
3251 }
3252
3253 /*!
3254  * \internal
3255  * \brief \ref stasis message payload for RTCP messages
3256  */
3257 struct rtcp_message_payload {
3258         struct ast_channel_snapshot *snapshot;  /*< The channel snapshot, if available */
3259         struct ast_rtp_rtcp_report *report;     /*< The RTCP report */
3260         struct ast_json *blob;                  /*< Extra JSON data to publish */
3261 };
3262
3263 static void rtcp_message_payload_dtor(void *obj)
3264 {
3265         struct rtcp_message_payload *payload = obj;
3266
3267         ao2_cleanup(payload->report);
3268         ao2_cleanup(payload->snapshot);
3269         ast_json_unref(payload->blob);
3270 }
3271
3272 static struct ast_manager_event_blob *rtcp_report_to_ami(struct stasis_message *msg)
3273 {
3274         struct rtcp_message_payload *payload = stasis_message_data(msg);
3275         RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
3276         RAII_VAR(struct ast_str *, packet_string, ast_str_create(512), ast_free);
3277         unsigned int ssrc = payload->report->ssrc;
3278         unsigned int type = payload->report->type;
3279         unsigned int report_count = payload->report->reception_report_count;
3280         int i;
3281
3282         if (!packet_string) {
3283                 return NULL;
3284         }
3285
3286         if (payload->snapshot) {
3287                 channel_string = ast_manager_build_channel_state_string(payload->snapshot);
3288                 if (!channel_string) {
3289                         return NULL;
3290                 }
3291         }
3292
3293         if (payload->blob) {
3294                 /* Optional data */
3295                 struct ast_json *to = ast_json_object_get(payload->blob, "to");
3296                 struct ast_json *from = ast_json_object_get(payload->blob, "from");
3297               &nbs