Fix a bug where we would native bridge when we did not want to.
[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 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include <math.h>
31
32 #include "asterisk/channel.h"
33 #include "asterisk/frame.h"
34 #include "asterisk/module.h"
35 #include "asterisk/rtp_engine.h"
36 #include "asterisk/manager.h"
37 #include "asterisk/options.h"
38 #include "asterisk/astobj2.h"
39 #include "asterisk/pbx.h"
40
41 /*! Structure that represents an RTP session (instance) */
42 struct ast_rtp_instance {
43         /*! Engine that is handling this RTP instance */
44         struct ast_rtp_engine *engine;
45         /*! Data unique to the RTP engine */
46         void *data;
47         /*! RTP properties that have been set and their value */
48         int properties[AST_RTP_PROPERTY_MAX];
49         /*! Address that we are expecting RTP to come in to */
50         struct sockaddr_in local_address;
51         /*! Address that we are sending RTP to */
52         struct sockaddr_in remote_address;
53         /*! Instance that we are bridged to if doing remote or local bridging */
54         struct ast_rtp_instance *bridged;
55         /*! Payload and packetization information */
56         struct ast_rtp_codecs codecs;
57         /*! RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */
58         int timeout;
59         /*! RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */
60         int holdtimeout;
61         /*! DTMF mode in use */
62         enum ast_rtp_dtmf_mode dtmf_mode;
63 };
64
65 /*! List of RTP engines that are currently registered */
66 static AST_RWLIST_HEAD_STATIC(engines, ast_rtp_engine);
67
68 /*! List of RTP glues */
69 static AST_RWLIST_HEAD_STATIC(glues, ast_rtp_glue);
70
71 /*! The following array defines the MIME Media type (and subtype) for each
72    of our codecs, or RTP-specific data type. */
73 static const struct ast_rtp_mime_type {
74         struct ast_rtp_payload_type payload_type;
75         char *type;
76         char *subtype;
77         unsigned int sample_rate;
78 } ast_rtp_mime_types[] = {
79         {{1, AST_FORMAT_G723_1}, "audio", "G723", 8000},
80         {{1, AST_FORMAT_GSM}, "audio", "GSM", 8000},
81         {{1, AST_FORMAT_ULAW}, "audio", "PCMU", 8000},
82         {{1, AST_FORMAT_ULAW}, "audio", "G711U", 8000},
83         {{1, AST_FORMAT_ALAW}, "audio", "PCMA", 8000},
84         {{1, AST_FORMAT_ALAW}, "audio", "G711A", 8000},
85         {{1, AST_FORMAT_G726}, "audio", "G726-32", 8000},
86         {{1, AST_FORMAT_ADPCM}, "audio", "DVI4", 8000},
87         {{1, AST_FORMAT_SLINEAR}, "audio", "L16", 8000},
88         {{1, AST_FORMAT_LPC10}, "audio", "LPC", 8000},
89         {{1, AST_FORMAT_G729A}, "audio", "G729", 8000},
90         {{1, AST_FORMAT_G729A}, "audio", "G729A", 8000},
91         {{1, AST_FORMAT_G729A}, "audio", "G.729", 8000},
92         {{1, AST_FORMAT_SPEEX}, "audio", "speex", 8000},
93         {{1, AST_FORMAT_ILBC}, "audio", "iLBC", 8000},
94         /* this is the sample rate listed in the RTP profile for the G.722
95                       codec, *NOT* the actual sample rate of the media stream
96         */
97         {{1, AST_FORMAT_G722}, "audio", "G722", 8000},
98         {{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32", 8000},
99         {{0, AST_RTP_DTMF}, "audio", "telephone-event", 8000},
100         {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event", 8000},
101         {{0, AST_RTP_CN}, "audio", "CN", 8000},
102         {{1, AST_FORMAT_JPEG}, "video", "JPEG", 90000},
103         {{1, AST_FORMAT_PNG}, "video", "PNG", 90000},
104         {{1, AST_FORMAT_H261}, "video", "H261", 90000},
105         {{1, AST_FORMAT_H263}, "video", "H263", 90000},
106         {{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998", 90000},
107         {{1, AST_FORMAT_H264}, "video", "H264", 90000},
108         {{1, AST_FORMAT_MP4_VIDEO}, "video", "MP4V-ES", 90000},
109         {{1, AST_FORMAT_T140RED}, "text", "RED", 1000},
110         {{1, AST_FORMAT_T140}, "text", "T140", 1000},
111         {{1, AST_FORMAT_SIREN7}, "audio", "G7221", 16000},
112         {{1, AST_FORMAT_SIREN14}, "audio", "G7221", 32000},
113 };
114
115 /*!
116  * \brief Mapping between Asterisk codecs and rtp payload types
117  *
118  * Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
119  * also, our own choices for dynamic payload types.  This is our master
120  * table for transmission
121  *
122  * See http://www.iana.org/assignments/rtp-parameters for a list of
123  * assigned values
124  */
125 static const struct ast_rtp_payload_type static_RTP_PT[AST_RTP_MAX_PT] = {
126         [0] = {1, AST_FORMAT_ULAW},
127         #ifdef USE_DEPRECATED_G726
128         [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
129         #endif
130         [3] = {1, AST_FORMAT_GSM},
131         [4] = {1, AST_FORMAT_G723_1},
132         [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
133         [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
134         [7] = {1, AST_FORMAT_LPC10},
135         [8] = {1, AST_FORMAT_ALAW},
136         [9] = {1, AST_FORMAT_G722},
137         [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
138         [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
139         [13] = {0, AST_RTP_CN},
140         [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
141         [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
142         [18] = {1, AST_FORMAT_G729A},
143         [19] = {0, AST_RTP_CN},         /* Also used for CN */
144         [26] = {1, AST_FORMAT_JPEG},
145         [31] = {1, AST_FORMAT_H261},
146         [34] = {1, AST_FORMAT_H263},
147         [97] = {1, AST_FORMAT_ILBC},
148         [98] = {1, AST_FORMAT_H263_PLUS},
149         [99] = {1, AST_FORMAT_H264},
150         [101] = {0, AST_RTP_DTMF},
151         [102] = {1, AST_FORMAT_SIREN7},
152         [103] = {1, AST_FORMAT_H263_PLUS},
153         [104] = {1, AST_FORMAT_MP4_VIDEO},
154         [105] = {1, AST_FORMAT_T140RED},        /* Real time text chat (with redundancy encoding) */
155         [106] = {1, AST_FORMAT_T140},   /* Real time text chat */
156         [110] = {1, AST_FORMAT_SPEEX},
157         [111] = {1, AST_FORMAT_G726},
158         [112] = {1, AST_FORMAT_G726_AAL2},
159         [115] = {1, AST_FORMAT_SIREN14},
160         [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
161 };
162
163 int ast_rtp_engine_register2(struct ast_rtp_engine *engine, struct ast_module *module)
164 {
165         struct ast_rtp_engine *current_engine;
166
167         /* Perform a sanity check on the engine structure to make sure it has the basics */
168         if (ast_strlen_zero(engine->name) || !engine->new || !engine->destroy || !engine->write || !engine->read) {
169                 ast_log(LOG_WARNING, "RTP Engine '%s' failed sanity check so it was not registered.\n", !ast_strlen_zero(engine->name) ? engine->name : "Unknown");
170                 return -1;
171         }
172
173         /* Link owner module to the RTP engine for reference counting purposes */
174         engine->mod = module;
175
176         AST_RWLIST_WRLOCK(&engines);
177
178         /* Ensure that no two modules with the same name are registered at the same time */
179         AST_RWLIST_TRAVERSE(&engines, current_engine, entry) {
180                 if (!strcmp(current_engine->name, engine->name)) {
181                         ast_log(LOG_WARNING, "An RTP engine with the name '%s' has already been registered.\n", engine->name);
182                         AST_RWLIST_UNLOCK(&engines);
183                         return -1;
184                 }
185         }
186
187         /* The engine survived our critique. Off to the list it goes to be used */
188         AST_RWLIST_INSERT_TAIL(&engines, engine, entry);
189
190         AST_RWLIST_UNLOCK(&engines);
191
192         ast_verb(2, "Registered RTP engine '%s'\n", engine->name);
193
194         return 0;
195 }
196
197 int ast_rtp_engine_unregister(struct ast_rtp_engine *engine)
198 {
199         struct ast_rtp_engine *current_engine = NULL;
200
201         AST_RWLIST_WRLOCK(&engines);
202
203         if ((current_engine = AST_RWLIST_REMOVE(&engines, engine, entry))) {
204                 ast_verb(2, "Unregistered RTP engine '%s'\n", engine->name);
205         }
206
207         AST_RWLIST_UNLOCK(&engines);
208
209         return current_engine ? 0 : -1;
210 }
211
212 int ast_rtp_glue_register2(struct ast_rtp_glue *glue, struct ast_module *module)
213 {
214         struct ast_rtp_glue *current_glue = NULL;
215
216         if (ast_strlen_zero(glue->type)) {
217                 return -1;
218         }
219
220         glue->mod = module;
221
222         AST_RWLIST_WRLOCK(&glues);
223
224         AST_RWLIST_TRAVERSE(&glues, current_glue, entry) {
225                 if (!strcasecmp(current_glue->type, glue->type)) {
226                         ast_log(LOG_WARNING, "RTP glue with the name '%s' has already been registered.\n", glue->type);
227                         AST_RWLIST_UNLOCK(&glues);
228                         return -1;
229                 }
230         }
231
232         AST_RWLIST_INSERT_TAIL(&glues, glue, entry);
233
234         AST_RWLIST_UNLOCK(&glues);
235
236         ast_verb(2, "Registered RTP glue '%s'\n", glue->type);
237
238         return 0;
239 }
240
241 int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
242 {
243         struct ast_rtp_glue *current_glue = NULL;
244
245         AST_RWLIST_WRLOCK(&glues);
246
247         if ((current_glue = AST_RWLIST_REMOVE(&glues, glue, entry))) {
248                 ast_verb(2, "Unregistered RTP glue '%s'\n", glue->type);
249         }
250
251         AST_RWLIST_UNLOCK(&glues);
252
253         return current_glue ? 0 : -1;
254 }
255
256 static void instance_destructor(void *obj)
257 {
258         struct ast_rtp_instance *instance = obj;
259
260         /* Pass us off to the engine to destroy */
261         if (instance->data && instance->engine->destroy(instance)) {
262                 ast_debug(1, "Engine '%s' failed to destroy RTP instance '%p'\n", instance->engine->name, instance);
263                 return;
264         }
265
266         /* Drop our engine reference */
267         ast_module_unref(instance->engine->mod);
268
269         ast_debug(1, "Destroyed RTP instance '%p'\n", instance);
270 }
271
272 int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
273 {
274         ao2_ref(instance, -1);
275
276         return 0;
277 }
278
279 struct ast_rtp_instance *ast_rtp_instance_new(const char *engine_name, struct sched_context *sched, struct sockaddr_in *sin, void *data)
280 {
281         struct ast_rtp_instance *instance = NULL;
282         struct ast_rtp_engine *engine = NULL;
283
284         AST_RWLIST_RDLOCK(&engines);
285
286         /* If an engine name was specified try to use it or otherwise use the first one registered */
287         if (!ast_strlen_zero(engine_name)) {
288                 AST_RWLIST_TRAVERSE(&engines, engine, entry) {
289                         if (!strcmp(engine->name, engine_name)) {
290                                 break;
291                         }
292                 }
293         } else {
294                 engine = AST_RWLIST_FIRST(&engines);
295         }
296
297         /* If no engine was actually found bail out now */
298         if (!engine) {
299                 ast_log(LOG_ERROR, "No RTP engine was found. Do you have one loaded?\n");
300                 AST_RWLIST_UNLOCK(&engines);
301                 return NULL;
302         }
303
304         /* Bump up the reference count before we return so the module can not be unloaded */
305         ast_module_ref(engine->mod);
306
307         AST_RWLIST_UNLOCK(&engines);
308
309         /* Allocate a new RTP instance */
310         if (!(instance = ao2_alloc(sizeof(*instance), instance_destructor))) {
311                 ast_module_unref(engine->mod);
312                 return NULL;
313         }
314         instance->engine = engine;
315         memcpy(&instance->local_address, sin, sizeof(instance->local_address));
316
317         ast_debug(1, "Using engine '%s' for RTP instance '%p'\n", engine->name, instance);
318
319         /* And pass it off to the engine to setup */
320         if (instance->engine->new(instance, sched, sin, data)) {
321                 ast_debug(1, "Engine '%s' failed to setup RTP instance '%p'\n", engine->name, instance);
322                 ao2_ref(instance, -1);
323                 return NULL;
324         }
325
326         ast_debug(1, "RTP instance '%p' is setup and ready to go\n", instance);
327
328         return instance;
329 }
330
331 void ast_rtp_instance_set_data(struct ast_rtp_instance *instance, void *data)
332 {
333         instance->data = data;
334 }
335
336 void *ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
337 {
338         return instance->data;
339 }
340
341 int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
342 {
343         return instance->engine->write(instance, frame);
344 }
345
346 struct ast_frame *ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
347 {
348         return instance->engine->read(instance, rtcp);
349 }
350
351 int ast_rtp_instance_set_local_address(struct ast_rtp_instance *instance, struct sockaddr_in *address)
352 {
353         memcpy(&instance->local_address, address, sizeof(instance->local_address));
354         return 0;
355 }
356
357 int ast_rtp_instance_set_remote_address(struct ast_rtp_instance *instance, struct sockaddr_in *address)
358 {
359         if (&instance->remote_address != address) {
360                 memcpy(&instance->remote_address, address, sizeof(instance->remote_address));
361         }
362
363         /* moo */
364
365         if (instance->engine->remote_address_set) {
366                 instance->engine->remote_address_set(instance, address);
367         }
368
369         return 0;
370 }
371
372 int ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct sockaddr_in *address)
373 {
374         if ((address->sin_family != AF_INET) ||
375             (address->sin_port != instance->local_address.sin_port) ||
376             (address->sin_addr.s_addr != instance->local_address.sin_addr.s_addr)) {
377                 memcpy(address, &instance->local_address, sizeof(*address));
378                 return 1;
379         }
380
381         return 0;
382 }
383
384 int ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct sockaddr_in *address)
385 {
386         if ((address->sin_family != AF_INET) ||
387             (address->sin_port != instance->remote_address.sin_port) ||
388             (address->sin_addr.s_addr != instance->remote_address.sin_addr.s_addr)) {
389                 memcpy(address, &instance->remote_address, sizeof(*address));
390                 return 1;
391         }
392
393         return 0;
394 }
395
396 void ast_rtp_instance_set_extended_prop(struct ast_rtp_instance *instance, int property, void *value)
397 {
398         if (instance->engine->extended_prop_set) {
399                 instance->engine->extended_prop_set(instance, property, value);
400         }
401 }
402
403 void *ast_rtp_instance_get_extended_prop(struct ast_rtp_instance *instance, int property)
404 {
405         if (instance->engine->extended_prop_get) {
406                 return instance->engine->extended_prop_get(instance, property);
407         }
408
409         return NULL;
410 }
411
412 void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
413 {
414         instance->properties[property] = value;
415
416         if (instance->engine->prop_set) {
417                 instance->engine->prop_set(instance, property, value);
418         }
419 }
420
421 int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property)
422 {
423         return instance->properties[property];
424 }
425
426 struct ast_rtp_codecs *ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
427 {
428         return &instance->codecs;
429 }
430
431 void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance)
432 {
433         int i;
434
435         for (i = 0; i < AST_RTP_MAX_PT; i++) {
436                 ast_debug(2, "Clearing payload %d on %p\n", i, codecs);
437                 codecs->payloads[i].asterisk_format = 0;
438                 codecs->payloads[i].code = 0;
439                 if (instance && instance->engine && instance->engine->payload_set) {
440                         instance->engine->payload_set(instance, i, 0, 0);
441                 }
442         }
443 }
444
445 void ast_rtp_codecs_payloads_default(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance)
446 {
447         int i;
448
449         for (i = 0; i < AST_RTP_MAX_PT; i++) {
450                 if (static_RTP_PT[i].code) {
451                         ast_debug(2, "Set default payload %d on %p\n", i, codecs);
452                         codecs->payloads[i].asterisk_format = static_RTP_PT[i].asterisk_format;
453                         codecs->payloads[i].code = static_RTP_PT[i].code;
454                         if (instance && instance->engine && instance->engine->payload_set) {
455                                 instance->engine->payload_set(instance, i, codecs->payloads[i].asterisk_format, codecs->payloads[i].code);
456                         }
457                 }
458         }
459 }
460
461 void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_codecs *dest, struct ast_rtp_instance *instance)
462 {
463         int i;
464
465         for (i = 0; i < AST_RTP_MAX_PT; i++) {
466                 if (src->payloads[i].code) {
467                         ast_debug(2, "Copying payload %d from %p to %p\n", i, src, dest);
468                         dest->payloads[i].asterisk_format = src->payloads[i].asterisk_format;
469                         dest->payloads[i].code = src->payloads[i].code;
470                         if (instance && instance->engine && instance->engine->payload_set) {
471                                 instance->engine->payload_set(instance, i, dest->payloads[i].asterisk_format, dest->payloads[i].code);
472                         }
473                 }
474         }
475 }
476
477 void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
478 {
479         if (payload < 0 || payload > AST_RTP_MAX_PT || !static_RTP_PT[payload].code) {
480                 return;
481         }
482
483         codecs->payloads[payload].asterisk_format = static_RTP_PT[payload].asterisk_format;
484         codecs->payloads[payload].code = static_RTP_PT[payload].code;
485
486         ast_debug(1, "Setting payload %d based on m type on %p\n", payload, codecs);
487
488         if (instance && instance->engine && instance->engine->payload_set) {
489                 instance->engine->payload_set(instance, payload, codecs->payloads[payload].asterisk_format, codecs->payloads[payload].code);
490         }
491 }
492
493 int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int pt,
494                                  char *mimetype, char *mimesubtype,
495                                  enum ast_rtp_options options,
496                                  unsigned int sample_rate)
497 {
498         unsigned int i;
499         int found = 0;
500
501         if (pt < 0 || pt > AST_RTP_MAX_PT)
502                 return -1; /* bogus payload type */
503
504         for (i = 0; i < ARRAY_LEN(ast_rtp_mime_types); ++i) {
505                 const struct ast_rtp_mime_type *t = &ast_rtp_mime_types[i];
506
507                 if (strcasecmp(mimesubtype, t->subtype)) {
508                         continue;
509                 }
510
511                 if (strcasecmp(mimetype, t->type)) {
512                         continue;
513                 }
514
515                 /* if both sample rates have been supplied, and they don't match,
516                                       then this not a match; if one has not been supplied, then the
517                                       rates are not compared */
518                 if (sample_rate && t->sample_rate &&
519                     (sample_rate != t->sample_rate)) {
520                         continue;
521                 }
522
523                 found = 1;
524                 codecs->payloads[pt] = t->payload_type;
525
526                 if ((t->payload_type.code == AST_FORMAT_G726) &&
527                                         t->payload_type.asterisk_format &&
528                     (options & AST_RTP_OPT_G726_NONSTANDARD)) {
529                         codecs->payloads[pt].code = AST_FORMAT_G726_AAL2;
530                 }
531
532                 if (instance && instance->engine && instance->engine->payload_set) {
533                         instance->engine->payload_set(instance, pt, codecs->payloads[i].asterisk_format, codecs->payloads[i].code);
534                 }
535
536                 break;
537         }
538
539         return (found ? 0 : -2);
540 }
541
542 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)
543 {
544         return ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, instance, payload, mimetype, mimesubtype, options, 0);
545 }
546
547 void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
548 {
549         if (payload < 0 || payload > AST_RTP_MAX_PT) {
550                 return;
551         }
552
553         ast_debug(2, "Unsetting payload %d on %p\n", payload, codecs);
554
555         codecs->payloads[payload].asterisk_format = 0;
556         codecs->payloads[payload].code = 0;
557
558         if (instance && instance->engine && instance->engine->payload_set) {
559                 instance->engine->payload_set(instance, payload, 0, 0);
560         }
561 }
562
563 struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs *codecs, int payload)
564 {
565         struct ast_rtp_payload_type result = { .asterisk_format = 0, };
566
567         if (payload < 0 || payload > AST_RTP_MAX_PT) {
568                 return result;
569         }
570
571         result.asterisk_format = codecs->payloads[payload].asterisk_format;
572         result.code = codecs->payloads[payload].code;
573
574         if (!result.code) {
575                 result = static_RTP_PT[payload];
576         }
577
578         return result;
579 }
580
581 void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, int *astformats, int *nonastformats)
582 {
583         int i;
584
585         *astformats = *nonastformats = 0;
586
587         for (i = 0; i < AST_RTP_MAX_PT; i++) {
588                 if (codecs->payloads[i].code) {
589                         ast_debug(1, "Incorporating payload %d on %p\n", i, codecs);
590                 }
591                 if (codecs->payloads[i].asterisk_format) {
592                         *astformats |= codecs->payloads[i].code;
593                 } else {
594                         *nonastformats |= codecs->payloads[i].code;
595                 }
596         }
597 }
598
599 int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const int code)
600 {
601         int i;
602
603         for (i = 0; i < AST_RTP_MAX_PT; i++) {
604                 if (codecs->payloads[i].asterisk_format == asterisk_format && codecs->payloads[i].code == code) {
605                         ast_debug(2, "Found code %d at payload %d on %p\n", code, i, codecs);
606                         return i;
607                 }
608         }
609
610         for (i = 0; i < AST_RTP_MAX_PT; i++) {
611                 if (static_RTP_PT[i].asterisk_format == asterisk_format && static_RTP_PT[i].code == code) {
612                         return i;
613                 }
614         }
615
616         return -1;
617 }
618
619 const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, const int code, enum ast_rtp_options options)
620 {
621         int i;
622
623         for (i = 0; i < ARRAY_LEN(ast_rtp_mime_types); i++) {
624                 if (ast_rtp_mime_types[i].payload_type.code == code && ast_rtp_mime_types[i].payload_type.asterisk_format == asterisk_format) {
625                         if (asterisk_format && (code == AST_FORMAT_G726_AAL2) && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
626                                 return "G726-32";
627                         } else {
628                                 return ast_rtp_mime_types[i].subtype;
629                         }
630                 }
631         }
632
633         return "";
634 }
635
636 unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, int code)
637 {
638         unsigned int i;
639
640         for (i = 0; i < ARRAY_LEN(ast_rtp_mime_types); ++i) {
641                 if ((ast_rtp_mime_types[i].payload_type.code == code) && (ast_rtp_mime_types[i].payload_type.asterisk_format == asterisk_format)) {
642                         return ast_rtp_mime_types[i].sample_rate;
643                 }
644         }
645
646         return 0;
647 }
648
649 char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, const int capability, const int asterisk_format, enum ast_rtp_options options)
650 {
651         int format, found = 0;
652
653         if (!buf) {
654                 return NULL;
655         }
656
657         ast_str_append(&buf, 0, "0x%x (", capability);
658
659         for (format = 1; format < AST_RTP_MAX; format <<= 1) {
660                 if (capability & format) {
661                         const char *name = ast_rtp_lookup_mime_subtype2(asterisk_format, format, options);
662                         ast_str_append(&buf, 0, "%s|", name);
663                         found = 1;
664                 }
665         }
666
667         ast_str_append(&buf, 0, "%s", found ? ")" : "nothing)");
668
669         return ast_str_buffer(buf);
670 }
671
672 void ast_rtp_codecs_packetization_set(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, struct ast_codec_pref *prefs)
673 {
674         codecs->pref = *prefs;
675
676         if (instance && instance->engine->packetization_set) {
677                 instance->engine->packetization_set(instance, &instance->codecs.pref);
678         }
679 }
680
681 int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
682 {
683         return instance->engine->dtmf_begin ? instance->engine->dtmf_begin(instance, digit) : -1;
684 }
685
686 int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
687 {
688         return instance->engine->dtmf_end ? instance->engine->dtmf_end(instance, digit) : -1;
689 }
690
691 int ast_rtp_instance_dtmf_mode_set(struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
692 {
693         if (!instance->engine->dtmf_mode_set || instance->engine->dtmf_mode_set(instance, dtmf_mode)) {
694                 return -1;
695         }
696
697         instance->dtmf_mode = dtmf_mode;
698
699         return 0;
700 }
701
702 enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
703 {
704         return instance->dtmf_mode;
705 }
706
707 void ast_rtp_instance_new_source(struct ast_rtp_instance *instance)
708 {
709         if (instance->engine->new_source) {
710                 instance->engine->new_source(instance);
711         }
712 }
713
714 int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
715 {
716         return instance->engine->qos ? instance->engine->qos(instance, tos, cos, desc) : -1;
717 }
718
719 void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
720 {
721         if (instance->engine->stop) {
722                 instance->engine->stop(instance);
723         }
724 }
725
726 int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
727 {
728         return instance->engine->fd ? instance->engine->fd(instance, rtcp) : -1;
729 }
730
731 struct ast_rtp_glue *ast_rtp_instance_get_glue(const char *type)
732 {
733         struct ast_rtp_glue *glue = NULL;
734
735         AST_RWLIST_RDLOCK(&glues);
736
737         AST_RWLIST_TRAVERSE(&glues, glue, entry) {
738                 if (!strcasecmp(glue->type, type)) {
739                         break;
740                 }
741         }
742
743         AST_RWLIST_UNLOCK(&glues);
744
745         return glue;
746 }
747
748 static enum ast_bridge_result local_bridge_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
749 {
750         enum ast_bridge_result res = AST_BRIDGE_FAILED;
751         struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, };
752         struct ast_frame *fr = NULL;
753
754         /* Start locally bridging both instances */
755         if (instance0->engine->local_bridge && instance0->engine->local_bridge(instance0, instance1)) {
756                 ast_debug(1, "Failed to locally bridge %s to %s, backing out.\n", c0->name, c1->name);
757                 ast_channel_unlock(c0);
758                 ast_channel_unlock(c1);
759                 return AST_BRIDGE_FAILED_NOWARN;
760         }
761         if (instance1->engine->local_bridge && instance1->engine->local_bridge(instance1, instance0)) {
762                 ast_debug(1, "Failed to locally bridge %s to %s, backing out.\n", c1->name, c0->name);
763                 if (instance0->engine->local_bridge) {
764                         instance0->engine->local_bridge(instance0, NULL);
765                 }
766                 ast_channel_unlock(c0);
767                 ast_channel_unlock(c1);
768                 return AST_BRIDGE_FAILED_NOWARN;
769         }
770
771         ast_channel_unlock(c0);
772         ast_channel_unlock(c1);
773
774         instance0->bridged = instance1;
775         instance1->bridged = instance0;
776
777         ast_poll_channel_add(c0, c1);
778
779         /* Hop into a loop waiting for a frame from either channel */
780         cs[0] = c0;
781         cs[1] = c1;
782         cs[2] = NULL;
783         for (;;) {
784                 /* If the underlying formats have changed force this bridge to break */
785                 if ((c0->rawreadformat != c1->rawwriteformat) || (c1->rawreadformat != c0->rawwriteformat)) {
786                         ast_debug(1, "rtp-engine-local-bridge: Oooh, formats changed, backing out\n");
787                         res = AST_BRIDGE_FAILED_NOWARN;
788                         break;
789                 }
790                 /* Check if anything changed */
791                 if ((c0->tech_pvt != pvt0) ||
792                     (c1->tech_pvt != pvt1) ||
793                     (c0->masq || c0->masqr || c1->masq || c1->masqr) ||
794                     (c0->monitor || c0->audiohooks || c1->monitor || c1->audiohooks)) {
795                         ast_debug(1, "rtp-engine-local-bridge: Oooh, something is weird, backing out\n");
796                         /* If a masquerade needs to happen we have to try to read in a frame so that it actually happens. Without this we risk being called again and going into a loop */
797                         if ((c0->masq || c0->masqr) && (fr = ast_read(c0))) {
798                                 ast_frfree(fr);
799                         }
800                         if ((c1->masq || c1->masqr) && (fr = ast_read(c1))) {
801                                 ast_frfree(fr);
802                         }
803                         res = AST_BRIDGE_RETRY;
804                         break;
805                 }
806                 /* Wait on a channel to feed us a frame */
807                 if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
808                         if (!timeoutms) {
809                                 res = AST_BRIDGE_RETRY;
810                                 break;
811                         }
812                         ast_debug(2, "rtp-engine-local-bridge: Ooh, empty read...\n");
813                         if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
814                                 break;
815                         }
816                         continue;
817                 }
818                 /* Read in frame from channel */
819                 fr = ast_read(who);
820                 other = (who == c0) ? c1 : c0;
821                 /* Depending on the frame we may need to break out of our bridge */
822                 if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) &&
823                             ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) |
824                             ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)))) {
825                         /* Record received frame and who */
826                         *fo = fr;
827                         *rc = who;
828                         ast_debug(1, "rtp-engine-local-bridge: Ooh, got a %s\n", fr ? "digit" : "hangup");
829                         res = AST_BRIDGE_COMPLETE;
830                         break;
831                 } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
832                         if ((fr->subclass == AST_CONTROL_HOLD) ||
833                             (fr->subclass == AST_CONTROL_UNHOLD) ||
834                             (fr->subclass == AST_CONTROL_VIDUPDATE) ||
835                             (fr->subclass == AST_CONTROL_T38) ||
836                             (fr->subclass == AST_CONTROL_SRCUPDATE)) {
837                                 /* If we are going on hold, then break callback mode and P2P bridging */
838                                 if (fr->subclass == AST_CONTROL_HOLD) {
839                                         if (instance0->engine->local_bridge) {
840                                                 instance0->engine->local_bridge(instance0, NULL);
841                                         }
842                                         if (instance1->engine->local_bridge) {
843                                                 instance1->engine->local_bridge(instance1, NULL);
844                                         }
845                                         instance0->bridged = NULL;
846                                         instance1->bridged = NULL;
847                                 } else if (fr->subclass == AST_CONTROL_UNHOLD) {
848                                         if (instance0->engine->local_bridge) {
849                                                 instance0->engine->local_bridge(instance0, instance1);
850                                         }
851                                         if (instance1->engine->local_bridge) {
852                                                 instance1->engine->local_bridge(instance1, instance0);
853                                         }
854                                         instance0->bridged = instance1;
855                                         instance1->bridged = instance0;
856                                 }
857                                 ast_indicate_data(other, fr->subclass, fr->data.ptr, fr->datalen);
858                                 ast_frfree(fr);
859                         } else {
860                                 *fo = fr;
861                                 *rc = who;
862                                 ast_debug(1, "rtp-engine-local-bridge: Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass, who->name);
863                                 res = AST_BRIDGE_COMPLETE;
864                                 break;
865                         }
866                 } else {
867                         if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
868                             (fr->frametype == AST_FRAME_DTMF_END) ||
869                             (fr->frametype == AST_FRAME_VOICE) ||
870                             (fr->frametype == AST_FRAME_VIDEO) ||
871                             (fr->frametype == AST_FRAME_IMAGE) ||
872                             (fr->frametype == AST_FRAME_HTML) ||
873                             (fr->frametype == AST_FRAME_MODEM) ||
874                             (fr->frametype == AST_FRAME_TEXT)) {
875                                 ast_write(other, fr);
876                         }
877
878                         ast_frfree(fr);
879                 }
880                 /* Swap priority */
881                 cs[2] = cs[0];
882                 cs[0] = cs[1];
883                 cs[1] = cs[2];
884         }
885
886         /* Stop locally bridging both instances */
887         if (instance0->engine->local_bridge) {
888                 instance0->engine->local_bridge(instance0, NULL);
889         }
890         if (instance1->engine->local_bridge) {
891                 instance1->engine->local_bridge(instance1, NULL);
892         }
893
894         instance0->bridged = NULL;
895         instance1->bridged = NULL;
896
897         ast_poll_channel_del(c0, c1);
898
899         return res;
900 }
901
902 static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1,
903                                                  struct ast_rtp_instance *vinstance0, struct ast_rtp_instance *vinstance1, struct ast_rtp_instance *tinstance0,
904                                                  struct ast_rtp_instance *tinstance1, struct ast_rtp_glue *glue0, struct ast_rtp_glue *glue1, int codec0, int codec1, int timeoutms,
905                                                  int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
906 {
907         enum ast_bridge_result res = AST_BRIDGE_FAILED;
908         struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, };
909         int oldcodec0 = codec0, oldcodec1 = codec1;
910         struct sockaddr_in ac1 = {0,}, vac1 = {0,}, tac1 = {0,}, ac0 = {0,}, vac0 = {0,}, tac0 = {0,};
911         struct sockaddr_in t1 = {0,}, vt1 = {0,}, tt1 = {0,}, t0 = {0,}, vt0 = {0,}, tt0 = {0,};
912         struct ast_frame *fr = NULL;
913
914         /* Test the first channel */
915         if (!(glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0))) {
916                 ast_rtp_instance_get_remote_address(instance1, &ac1);
917                 if (vinstance1) {
918                         ast_rtp_instance_get_remote_address(vinstance1, &vac1);
919                 }
920                 if (tinstance1) {
921                         ast_rtp_instance_get_remote_address(tinstance1, &tac1);
922                 }
923         } else {
924                 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
925         }
926
927         /* Test the second channel */
928         if (!(glue1->update_peer(c1, instance0, vinstance0, tinstance0, codec0, 0))) {
929                 ast_rtp_instance_get_remote_address(instance0, &ac0);
930                 if (vinstance0) {
931                         ast_rtp_instance_get_remote_address(instance0, &vac0);
932                 }
933                 if (tinstance0) {
934                         ast_rtp_instance_get_remote_address(instance0, &tac0);
935                 }
936         } else {
937                 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c1->name, c0->name);
938         }
939
940         ast_channel_unlock(c0);
941         ast_channel_unlock(c1);
942
943         instance0->bridged = instance1;
944         instance1->bridged = instance0;
945
946         ast_poll_channel_add(c0, c1);
947
948         /* Go into a loop handling any stray frames that may come in */
949         cs[0] = c0;
950         cs[1] = c1;
951         cs[2] = NULL;
952         for (;;) {
953                 /* Check if anything changed */
954                 if ((c0->tech_pvt != pvt0) ||
955                     (c1->tech_pvt != pvt1) ||
956                     (c0->masq || c0->masqr || c1->masq || c1->masqr) ||
957                     (c0->monitor || c0->audiohooks || c1->monitor || c1->audiohooks)) {
958                         ast_debug(1, "Oooh, something is weird, backing out\n");
959                         res = AST_BRIDGE_RETRY;
960                         break;
961                 }
962
963                 /* Check if they have changed their address */
964                 ast_rtp_instance_get_remote_address(instance1, &t1);
965                 if (vinstance1) {
966                         ast_rtp_instance_get_remote_address(vinstance1, &vt1);
967                 }
968                 if (tinstance1) {
969                         ast_rtp_instance_get_remote_address(tinstance1, &tt1);
970                 }
971                 if (glue1->get_codec) {
972                         codec1 = glue1->get_codec(c1);
973                 }
974
975                 ast_rtp_instance_get_remote_address(instance0, &t0);
976                 if (vinstance0) {
977                         ast_rtp_instance_get_remote_address(vinstance0, &vt0);
978                 }
979                 if (tinstance0) {
980                         ast_rtp_instance_get_remote_address(tinstance0, &tt0);
981                 }
982                 if (glue0->get_codec) {
983                         codec0 = glue0->get_codec(c0);
984                 }
985
986                 if ((inaddrcmp(&t1, &ac1)) ||
987                     (vinstance1 && inaddrcmp(&vt1, &vac1)) ||
988                     (tinstance1 && inaddrcmp(&tt1, &tac1)) ||
989                     (codec1 != oldcodec1)) {
990                         ast_debug(1, "Oooh, '%s' changed end address to %s:%d (format %d)\n",
991                                   c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port), codec1);
992                         ast_debug(1, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n",
993                                   c1->name, ast_inet_ntoa(vt1.sin_addr), ntohs(vt1.sin_port), codec1);
994                         ast_debug(1, "Oooh, '%s' changed end taddress to %s:%d (format %d)\n",
995                                   c1->name, ast_inet_ntoa(tt1.sin_addr), ntohs(tt1.sin_port), codec1);
996                         ast_debug(1, "Oooh, '%s' was %s:%d/(format %d)\n",
997                                   c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
998                         ast_debug(1, "Oooh, '%s' was %s:%d/(format %d)\n",
999                                   c1->name, ast_inet_ntoa(vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
1000                         ast_debug(1, "Oooh, '%s' was %s:%d/(format %d)\n",
1001                                   c1->name, ast_inet_ntoa(tac1.sin_addr), ntohs(tac1.sin_port), oldcodec1);
1002                         if (glue0->update_peer(c0, t1.sin_addr.s_addr ? instance1 : NULL, vt1.sin_addr.s_addr ? vinstance1 : NULL, tt1.sin_addr.s_addr ? tinstance1 : NULL, codec1, 0)) {
1003                                 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
1004                         }
1005                         memcpy(&ac1, &t1, sizeof(ac1));
1006                         memcpy(&vac1, &vt1, sizeof(vac1));
1007                         memcpy(&tac1, &tt1, sizeof(tac1));
1008                         oldcodec1 = codec1;
1009                 }
1010                 if ((inaddrcmp(&t0, &ac0)) ||
1011                     (vinstance0 && inaddrcmp(&vt0, &vac0)) ||
1012                     (tinstance0 && inaddrcmp(&tt0, &tac0))) {
1013                         ast_debug(1, "Oooh, '%s' changed end address to %s:%d (format %d)\n",
1014                                   c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port), codec0);
1015                         ast_debug(1, "Oooh, '%s' was %s:%d/(format %d)\n",
1016                                   c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
1017                         if (glue1->update_peer(c1, t0.sin_addr.s_addr ? instance0 : NULL, vt0.sin_addr.s_addr ? vinstance0 : NULL, tt0.sin_addr.s_addr ? tinstance0 : NULL, codec0, 0)) {
1018                                 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
1019                         }
1020                         memcpy(&ac0, &t0, sizeof(ac0));
1021                         memcpy(&vac0, &vt0, sizeof(vac0));
1022                         memcpy(&tac0, &tt0, sizeof(tac0));
1023                         oldcodec0 = codec0;
1024                 }
1025
1026                 /* Wait for frame to come in on the channels */
1027                 if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
1028                         if (!timeoutms) {
1029                                 res = AST_BRIDGE_RETRY;
1030                                 break;
1031                         }
1032                         ast_debug(1, "Ooh, empty read...\n");
1033                         if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
1034                                 break;
1035                         }
1036                         continue;
1037                 }
1038                 fr = ast_read(who);
1039                 other = (who == c0) ? c1 : c0;
1040                 if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) &&
1041                             (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) ||
1042                              ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
1043                         /* Break out of bridge */
1044                         *fo = fr;
1045                         *rc = who;
1046                         ast_debug(1, "Oooh, got a %s\n", fr ? "digit" : "hangup");
1047                         res = AST_BRIDGE_COMPLETE;
1048                         break;
1049                 } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
1050                         if ((fr->subclass == AST_CONTROL_HOLD) ||
1051                             (fr->subclass == AST_CONTROL_UNHOLD) ||
1052                             (fr->subclass == AST_CONTROL_VIDUPDATE) ||
1053                             (fr->subclass == AST_CONTROL_T38) ||
1054                             (fr->subclass == AST_CONTROL_SRCUPDATE)) {
1055                                 if (fr->subclass == AST_CONTROL_HOLD) {
1056                                         /* If we someone went on hold we want the other side to reinvite back to us */
1057                                         if (who == c0) {
1058                                                 glue1->update_peer(c1, NULL, NULL, NULL, 0, 0);
1059                                         } else {
1060                                                 glue0->update_peer(c0, NULL, NULL, NULL, 0, 0);
1061                                         }
1062                                 } else if (fr->subclass == AST_CONTROL_UNHOLD) {
1063                                         /* If they went off hold they should go back to being direct */
1064                                         if (who == c0) {
1065                                                 glue1->update_peer(c1, instance0, vinstance0, tinstance0, codec0, 0);
1066                                         } else {
1067                                                 glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0);
1068                                         }
1069                                 }
1070                                 /* Update local address information */
1071                                 ast_rtp_instance_get_remote_address(instance0, &t0);
1072                                 memcpy(&ac0, &t0, sizeof(ac0));
1073                                 ast_rtp_instance_get_remote_address(instance1, &t1);
1074                                 memcpy(&ac1, &t1, sizeof(ac1));
1075                                 /* Update codec information */
1076                                 if (glue0->get_codec && c0->tech_pvt) {
1077                                         oldcodec0 = codec0 = glue0->get_codec(c0);
1078                                 }
1079                                 if (glue1->get_codec && c1->tech_pvt) {
1080                                         oldcodec1 = codec1 = glue1->get_codec(c1);
1081                                 }
1082                                 ast_indicate_data(other, fr->subclass, fr->data.ptr, fr->datalen);
1083                                 ast_frfree(fr);
1084                         } else {
1085                                 *fo = fr;
1086                                 *rc = who;
1087                                 ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass, who->name);
1088                                 return AST_BRIDGE_COMPLETE;
1089                         }
1090                 } else {
1091                         if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
1092                             (fr->frametype == AST_FRAME_DTMF_END) ||
1093                             (fr->frametype == AST_FRAME_VOICE) ||
1094                             (fr->frametype == AST_FRAME_VIDEO) ||
1095                             (fr->frametype == AST_FRAME_IMAGE) ||
1096                             (fr->frametype == AST_FRAME_HTML) ||
1097                             (fr->frametype == AST_FRAME_MODEM) ||
1098                             (fr->frametype == AST_FRAME_TEXT)) {
1099                                 ast_write(other, fr);
1100                         }
1101                         ast_frfree(fr);
1102                 }
1103                 /* Swap priority */
1104                 cs[2] = cs[0];
1105                 cs[0] = cs[1];
1106                 cs[1] = cs[2];
1107         }
1108
1109         if (glue0->update_peer(c0, NULL, NULL, NULL, 0, 0)) {
1110                 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
1111         }
1112         if (glue1->update_peer(c1, NULL, NULL, NULL, 0, 0)) {
1113                 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
1114         }
1115
1116         instance0->bridged = NULL;
1117         instance1->bridged = NULL;
1118
1119         ast_poll_channel_del(c0, c1);
1120
1121         return res;
1122 }
1123
1124 /*!
1125  * \brief Conditionally unref an rtp instance
1126  */
1127 static void unref_instance_cond(struct ast_rtp_instance **instance)
1128 {
1129         if (*instance) {
1130                 ao2_ref(*instance, -1);
1131                 *instance = NULL;
1132         }
1133 }
1134
1135 enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
1136 {
1137         struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
1138                         *vinstance0 = NULL, *vinstance1 = NULL,
1139                         *tinstance0 = NULL, *tinstance1 = NULL;
1140         struct ast_rtp_glue *glue0, *glue1;
1141         enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID, text_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
1142         enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID, text_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
1143         enum ast_bridge_result res = AST_BRIDGE_FAILED;
1144         int codec0 = 0, codec1 = 0;
1145         int unlock_chans = 1;
1146
1147         /* Lock both channels so we can look for the glue that binds them together */
1148         ast_channel_lock(c0);
1149         while (ast_channel_trylock(c1)) {
1150                 ast_channel_unlock(c0);
1151                 usleep(1);
1152                 ast_channel_lock(c0);
1153         }
1154
1155         /* Ensure neither channel got hungup during lock avoidance */
1156         if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
1157                 ast_log(LOG_WARNING, "Got hangup while attempting to bridge '%s' and '%s'\n", c0->name, c1->name);
1158                 goto done;
1159         }
1160
1161         /* Grab glue that binds each channel to something using the RTP engine */
1162         if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
1163                 ast_debug(1, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
1164                 goto done;
1165         }
1166
1167         audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
1168         video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
1169         text_glue0_res = glue0->get_trtp_info ? glue0->get_trtp_info(c0, &tinstance0) : AST_RTP_GLUE_RESULT_FORBID;
1170
1171         audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
1172         video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
1173         text_glue1_res = glue1->get_trtp_info ? glue1->get_trtp_info(c1, &tinstance1) : AST_RTP_GLUE_RESULT_FORBID;
1174
1175         /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
1176         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)) {
1177                 audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
1178         }
1179         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)) {
1180                 audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
1181         }
1182
1183         /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
1184         if (audio_glue0_res == AST_RTP_GLUE_RESULT_FORBID || audio_glue1_res == AST_RTP_GLUE_RESULT_FORBID) {
1185                 res = AST_BRIDGE_FAILED_NOWARN;
1186                 goto done;
1187         }
1188
1189         /* If we need to get DTMF see if we can do it outside of the RTP stream itself */
1190         if ((flags & AST_BRIDGE_DTMF_CHANNEL_0) && instance0->properties[AST_RTP_PROPERTY_DTMF]) {
1191                 res = AST_BRIDGE_FAILED_NOWARN;
1192                 goto done;
1193         }
1194         if ((flags & AST_BRIDGE_DTMF_CHANNEL_1) && instance1->properties[AST_RTP_PROPERTY_DTMF]) {
1195                 res = AST_BRIDGE_FAILED_NOWARN;
1196                 goto done;
1197         }
1198
1199         /* If we have gotten to a local bridge make sure that both sides have the same local bridge callback and that they are DTMF compatible */
1200         if ((audio_glue0_res == AST_RTP_GLUE_RESULT_LOCAL || audio_glue1_res == AST_RTP_GLUE_RESULT_LOCAL) && ((instance0->engine->local_bridge != instance1->engine->local_bridge) || (instance0->engine->dtmf_compatible && !instance0->engine->dtmf_compatible(c0, instance0, c1, instance1)))) {
1201                 res = AST_BRIDGE_FAILED_NOWARN;
1202                 goto done;
1203         }
1204
1205         /* Make sure that codecs match */
1206         codec0 = glue0->get_codec ? glue0->get_codec(c0) : 0;
1207         codec1 = glue1->get_codec ? glue1->get_codec(c1) : 0;
1208         if (codec0 && codec1 && !(codec0 & codec1)) {
1209                 ast_debug(1, "Channel codec0 = %d is not codec1 = %d, cannot native bridge in RTP.\n", codec0, codec1);
1210                 res = AST_BRIDGE_FAILED_NOWARN;
1211                 goto done;
1212         }
1213
1214         /* Depending on the end result for bridging either do a local bridge or remote bridge */
1215         if (audio_glue0_res == AST_RTP_GLUE_RESULT_LOCAL || audio_glue1_res == AST_RTP_GLUE_RESULT_LOCAL) {
1216                 ast_verbose(VERBOSE_PREFIX_3 "Locally bridging %s and %s\n", c0->name, c1->name);
1217                 res = local_bridge_loop(c0, c1, instance0, instance1, timeoutms, flags, fo, rc, c0->tech_pvt, c1->tech_pvt);
1218         } else {
1219                 ast_verbose(VERBOSE_PREFIX_3 "Remotely bridging %s and %s\n", c0->name, c1->name);
1220                 res = remote_bridge_loop(c0, c1, instance0, instance1, vinstance0, vinstance1,
1221                                 tinstance0, tinstance1, glue0, glue1, codec0, codec1, timeoutms, flags,
1222                                 fo, rc, c0->tech_pvt, c1->tech_pvt);
1223         }
1224
1225         unlock_chans = 0;
1226
1227 done:
1228         if (unlock_chans) {
1229                 ast_channel_unlock(c0);
1230                 ast_channel_unlock(c1);
1231         }
1232
1233         unref_instance_cond(&instance0);
1234         unref_instance_cond(&instance1);
1235         unref_instance_cond(&vinstance0);
1236         unref_instance_cond(&vinstance1);
1237         unref_instance_cond(&tinstance0);
1238         unref_instance_cond(&tinstance1);
1239
1240         return res;
1241 }
1242
1243 struct ast_rtp_instance *ast_rtp_instance_get_bridged(struct ast_rtp_instance *instance)
1244 {
1245         return instance->bridged;
1246 }
1247
1248 void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c0, struct ast_channel *c1)
1249 {
1250         struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
1251                 *vinstance0 = NULL, *vinstance1 = NULL,
1252                 *tinstance0 = NULL, *tinstance1 = NULL;
1253         struct ast_rtp_glue *glue0, *glue1;
1254         enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID, text_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
1255         enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID, text_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
1256         int codec0 = 0, codec1 = 0;
1257         int res = 0;
1258
1259         /* Lock both channels so we can look for the glue that binds them together */
1260         ast_channel_lock(c0);
1261         while (ast_channel_trylock(c1)) {
1262                 ast_channel_unlock(c0);
1263                 usleep(1);
1264                 ast_channel_lock(c0);
1265         }
1266
1267         /* Grab glue that binds each channel to something using the RTP engine */
1268         if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
1269                 ast_debug(1, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
1270                 goto done;
1271         }
1272
1273         audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
1274         video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
1275         text_glue0_res = glue0->get_trtp_info ? glue0->get_trtp_info(c0, &tinstance0) : AST_RTP_GLUE_RESULT_FORBID;
1276
1277         audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
1278         video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
1279         text_glue1_res = glue1->get_trtp_info ? glue1->get_trtp_info(c1, &tinstance1) : AST_RTP_GLUE_RESULT_FORBID;
1280
1281         /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
1282         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)) {
1283                 audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
1284         }
1285         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)) {
1286                 audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
1287         }
1288         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(c0)) {
1289                 codec0 = glue0->get_codec(c0);
1290         }
1291         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(c1)) {
1292                 codec1 = glue1->get_codec(c1);
1293         }
1294
1295         /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
1296         if (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE) {
1297                 goto done;
1298         }
1299
1300         /* Make sure we have matching codecs */
1301         if (!(codec0 & codec1)) {
1302                 goto done;
1303         }
1304
1305         ast_rtp_codecs_payloads_copy(&instance0->codecs, &instance1->codecs, instance1);
1306
1307         if (vinstance0 && vinstance1) {
1308                 ast_rtp_codecs_payloads_copy(&vinstance0->codecs, &vinstance1->codecs, vinstance1);
1309         }
1310         if (tinstance0 && tinstance1) {
1311                 ast_rtp_codecs_payloads_copy(&tinstance0->codecs, &tinstance1->codecs, tinstance1);
1312         }
1313
1314         res = 0;
1315
1316 done:
1317         ast_channel_unlock(c0);
1318         ast_channel_unlock(c1);
1319
1320         unref_instance_cond(&instance0);
1321         unref_instance_cond(&instance1);
1322         unref_instance_cond(&vinstance0);
1323         unref_instance_cond(&vinstance1);
1324         unref_instance_cond(&tinstance0);
1325         unref_instance_cond(&tinstance1);
1326
1327         if (!res) {
1328                 ast_debug(1, "Seeded SDP of '%s' with that of '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
1329         }
1330 }
1331
1332 int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
1333 {
1334         struct ast_rtp_instance *instance0 = NULL, *instance1 = NULL,
1335                         *vinstance0 = NULL, *vinstance1 = NULL,
1336                         *tinstance0 = NULL, *tinstance1 = NULL;
1337         struct ast_rtp_glue *glue0, *glue1;
1338         enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID, text_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
1339         enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID, text_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
1340         int codec0 = 0, codec1 = 0;
1341         int res = 0;
1342
1343         /* If there is no second channel just immediately bail out, we are of no use in that scenario */
1344         if (!c1) {
1345                 return -1;
1346         }
1347
1348         /* Lock both channels so we can look for the glue that binds them together */
1349         ast_channel_lock(c0);
1350         while (ast_channel_trylock(c1)) {
1351                 ast_channel_unlock(c0);
1352                 usleep(1);
1353                 ast_channel_lock(c0);
1354         }
1355
1356         /* Grab glue that binds each channel to something using the RTP engine */
1357         if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
1358                 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
1359                 goto done;
1360         }
1361
1362         audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
1363         video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
1364         text_glue0_res = glue0->get_trtp_info ? glue0->get_trtp_info(c0, &tinstance0) : AST_RTP_GLUE_RESULT_FORBID;
1365
1366         audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
1367         video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
1368         text_glue1_res = glue1->get_trtp_info ? glue1->get_trtp_info(c1, &tinstance1) : AST_RTP_GLUE_RESULT_FORBID;
1369
1370         /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
1371         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)) {
1372                 audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
1373         }
1374         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)) {
1375                 audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
1376         }
1377         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(c0)) {
1378                 codec0 = glue0->get_codec(c0);
1379         }
1380         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(c1)) {
1381                 codec1 = glue1->get_codec(c1);
1382         }
1383
1384         /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
1385         if (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE) {
1386                 goto done;
1387         }
1388
1389         /* Make sure we have matching codecs */
1390         if (!(codec0 & codec1)) {
1391                 goto done;
1392         }
1393
1394         /* Bridge media early */
1395         if (glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0)) {
1396                 ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
1397         }
1398
1399         res = 0;
1400
1401 done:
1402         ast_channel_unlock(c0);
1403         ast_channel_unlock(c1);
1404
1405         unref_instance_cond(&instance0);
1406         unref_instance_cond(&instance1);
1407         unref_instance_cond(&vinstance0);
1408         unref_instance_cond(&vinstance1);
1409         unref_instance_cond(&tinstance0);
1410         unref_instance_cond(&tinstance1);
1411
1412         if (!res) {
1413                 ast_debug(1, "Setting early bridge SDP of '%s' with that of '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
1414         }
1415
1416         return res;
1417 }
1418
1419 int ast_rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations)
1420 {
1421         return instance->engine->red_init ? instance->engine->red_init(instance, buffer_time, payloads, generations) : -1;
1422 }
1423
1424 int ast_rtp_red_buffer(struct ast_rtp_instance *instance, struct ast_frame *frame)
1425 {
1426         return instance->engine->red_buffer ? instance->engine->red_buffer(instance, frame) : -1;
1427 }
1428
1429 int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
1430 {
1431         return instance->engine->get_stat ? instance->engine->get_stat(instance, stats, stat) : -1;
1432 }
1433
1434 char *ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_rtp_instance_stat_field field, char *buf, size_t size)
1435 {
1436         struct ast_rtp_instance_stats stats;
1437         enum ast_rtp_instance_stat stat;
1438
1439         /* Determine what statistics we will need to retrieve based on field passed in */
1440         if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY) {
1441                 stat = AST_RTP_INSTANCE_STAT_ALL;
1442         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER) {
1443                 stat = AST_RTP_INSTANCE_STAT_COMBINED_JITTER;
1444         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS) {
1445                 stat = AST_RTP_INSTANCE_STAT_COMBINED_LOSS;
1446         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT) {
1447                 stat = AST_RTP_INSTANCE_STAT_COMBINED_RTT;
1448         } else {
1449                 return NULL;
1450         }
1451
1452         /* Attempt to actually retrieve the statistics we need to generate the quality string */
1453         if (ast_rtp_instance_get_stats(instance, &stats, stat)) {
1454                 return NULL;
1455         }
1456
1457         /* Now actually fill the buffer with the good information */
1458         if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY) {
1459                 snprintf(buf, size, "ssrc=%i;themssrc=%u;lp=%u;rxjitter=%u;rxcount=%u;txjitter=%u;txcount=%u;rlp=%u;rtt=%u",
1460                          stats.local_ssrc, stats.remote_ssrc, stats.rxploss, stats.txjitter, stats.rxcount, stats.rxjitter, stats.txcount, stats.txploss, stats.rtt);
1461         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER) {
1462                 snprintf(buf, size, "minrxjitter=%f;maxrxjitter=%f;avgrxjitter=%f;stdevrxjitter=%f;reported_minjitter=%f;reported_maxjitter=%f;reported_avgjitter=%f;reported_stdevjitter=%f;",
1463                          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));
1464         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS) {
1465                 snprintf(buf, size, "minrxlost=%f;maxrxlost=%f;avgrxlost=%f;stdevrxlost=%f;reported_minlost=%f;reported_maxlost=%f;reported_avglost=%f;reported_stdevlost=%f;",
1466                          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));
1467         } else if (field == AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT) {
1468                 snprintf(buf, size, "minrtt=%f;maxrtt=%f;avgrtt=%f;stdevrtt=%f;", stats.minrtt, stats.maxrtt, stats.normdevrtt, stats.stdevrtt);
1469         }
1470
1471         return buf;
1472 }
1473
1474 void ast_rtp_instance_set_stats_vars(struct ast_channel *chan, struct ast_rtp_instance *instance)
1475 {
1476         char quality_buf[AST_MAX_USER_FIELD], *quality;
1477         struct ast_channel *bridge = ast_bridged_channel(chan);
1478
1479         if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) {
1480                 pbx_builtin_setvar_helper(chan, "RTPAUDIOQOS", quality);
1481                 if (bridge) {
1482                         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSBRIDGED", quality);
1483                 }
1484         }
1485
1486         if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_JITTER, quality_buf, sizeof(quality_buf)))) {
1487                 pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSJITTER", quality);
1488                 if (bridge) {
1489                         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSJITTERBRIDGED", quality);
1490                 }
1491         }
1492
1493         if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_LOSS, quality_buf, sizeof(quality_buf)))) {
1494                 pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSLOSS", quality);
1495                 if (bridge) {
1496                         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSLOSSBRIDGED", quality);
1497                 }
1498         }
1499
1500         if ((quality = ast_rtp_instance_get_quality(instance, AST_RTP_INSTANCE_STAT_FIELD_QUALITY_RTT, quality_buf, sizeof(quality_buf)))) {
1501                 pbx_builtin_setvar_helper(chan, "RTPAUDIOQOSRTT", quality);
1502                 if (bridge) {
1503                         pbx_builtin_setvar_helper(bridge, "RTPAUDIOQOSRTTBRIDGED", quality);
1504                 }
1505         }
1506 }
1507
1508 int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, int format)
1509 {
1510         return instance->engine->set_read_format ? instance->engine->set_read_format(instance, format) : -1;
1511 }
1512
1513 int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, int format)
1514 {
1515         return instance->engine->set_write_format ? instance->engine->set_write_format(instance, format) : -1;
1516 }
1517
1518 int ast_rtp_instance_make_compatible(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_channel *peer)
1519 {
1520         struct ast_rtp_glue *glue;
1521         struct ast_rtp_instance *peer_instance = NULL;
1522         int res = -1;
1523
1524         if (!instance->engine->make_compatible) {
1525                 return -1;
1526         }
1527
1528         ast_channel_lock(peer);
1529
1530         if (!(glue = ast_rtp_instance_get_glue(peer->tech->type))) {
1531                 ast_channel_unlock(peer);
1532                 return -1;
1533         }
1534
1535         glue->get_rtp_info(peer, &peer_instance);
1536
1537         if (!peer_instance || peer_instance->engine != instance->engine) {
1538                 ast_channel_unlock(peer);
1539                 peer_instance = (ao2_ref(peer_instance, -1), NULL);
1540                 return -1;
1541         }
1542
1543         res = instance->engine->make_compatible(chan, instance, peer, peer_instance);
1544
1545         ast_channel_unlock(peer);
1546
1547         peer_instance = (ao2_ref(peer_instance, -1), NULL);
1548
1549         return res;
1550 }
1551
1552 int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
1553 {
1554         return instance->engine->activate ? instance->engine->activate(instance) : 0;
1555 }
1556
1557 void ast_rtp_instance_stun_request(struct ast_rtp_instance *instance, struct sockaddr_in *suggestion, const char *username)
1558 {
1559         if (instance->engine->stun_request) {
1560                 instance->engine->stun_request(instance, suggestion, username);
1561         }
1562 }
1563
1564 void ast_rtp_instance_set_timeout(struct ast_rtp_instance *instance, int timeout)
1565 {
1566         instance->timeout = timeout;
1567 }
1568
1569 void ast_rtp_instance_set_hold_timeout(struct ast_rtp_instance *instance, int timeout)
1570 {
1571         instance->holdtimeout = timeout;
1572 }
1573
1574 int ast_rtp_instance_get_timeout(struct ast_rtp_instance *instance)
1575 {
1576         return instance->timeout;
1577 }
1578
1579 int ast_rtp_instance_get_hold_timeout(struct ast_rtp_instance *instance)
1580 {
1581         return instance->holdtimeout;
1582 }