Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Functions | Variables
bridge_native_rtp.c File Reference

Native RTP bridging technology module. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_technology.h"
#include "asterisk/frame.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/stream.h"
Include dependency graph for bridge_native_rtp.c:

Go to the source code of this file.

Data Structures

struct  native_rtp_bridge_channel_data
 Internal structure which contains instance information about bridged RTP channels. More...
 
struct  native_rtp_framehook_data
 Internal structure which contains bridged RTP channel hook data. More...
 
struct  rtp_glue_data
 
struct  rtp_glue_stream
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static int native_rtp_bridge_capable (struct ast_channel *chan)
 
static struct native_rtp_bridge_channel_datanative_rtp_bridge_channel_data_alloc (void)
 
static void native_rtp_bridge_channel_data_free (struct native_rtp_bridge_channel_data *data)
 
static int native_rtp_bridge_compatible (struct ast_bridge *bridge)
 
static int native_rtp_bridge_compatible_check (struct ast_bridge *bridge, struct ast_bridge_channel *bc0, struct ast_bridge_channel *bc1)
 
static int native_rtp_bridge_framehook_attach (struct ast_bridge_channel *bridge_channel)
 
static void native_rtp_bridge_framehook_detach (struct ast_bridge_channel *bridge_channel)
 
static int native_rtp_bridge_join (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 Forward declarations. More...
 
static void native_rtp_bridge_leave (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 
static void native_rtp_bridge_start (struct ast_bridge *bridge, struct ast_channel *target)
 
static void native_rtp_bridge_stop (struct ast_bridge *bridge, struct ast_channel *target)
 
static void native_rtp_bridge_suspend (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 
static void native_rtp_bridge_unsuspend (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 
static int native_rtp_bridge_write (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 
static struct ast_framenative_rtp_framehook (struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
 
static int native_rtp_framehook_consume (void *data, enum ast_frame_type type)
 
static struct ast_stream_topologynative_rtp_request_stream_topology_update (struct ast_stream_topology *existing_topology, struct ast_stream_topology *requested_topology)
 
static void native_rtp_stream_topology_changed (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 
static void rtp_glue_data_destroy (struct rtp_glue_data *glue)
 
static int rtp_glue_data_get (struct ast_channel *c0, struct rtp_glue_data *glue0, struct ast_channel *c1, struct rtp_glue_data *glue1)
 
static void rtp_glue_data_init (struct rtp_glue_data *glue)
 
static void rtp_glue_data_reset (struct rtp_glue_data *glue)
 
static enum ast_rtp_glue_result rtp_glue_get_current_combined_result (struct ast_channel *c0, struct ast_channel *c1)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Native RTP bridging module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_bridge_technology native_rtp_bridge
 

Detailed Description

Native RTP bridging technology module.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file bridge_native_rtp.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1113 of file bridge_native_rtp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1113 of file bridge_native_rtp.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1113 of file bridge_native_rtp.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 1104 of file bridge_native_rtp.c.

References ast_bridge_technology_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and unload_module().

1105 {
1107  unload_module();
1108  return AST_MODULE_LOAD_DECLINE;
1109  }
1110  return AST_MODULE_LOAD_SUCCESS;
1111 }
static int unload_module(void)
static struct ast_bridge_technology native_rtp_bridge
#define ast_bridge_technology_register(technology)
See __ast_bridge_technology_register()
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78

◆ native_rtp_bridge_capable()

static int native_rtp_bridge_capable ( struct ast_channel chan)
static

Definition at line 622 of file bridge_native_rtp.c.

References ast_channel_has_hook_requiring_audio(), and AST_STATE_UP.

Referenced by native_rtp_bridge_compatible_check().

623 {
625  && ast_channel_state(chan) == AST_STATE_UP;
626 }
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_channel_has_hook_requiring_audio(struct ast_channel *chan)
Check if the channel has any active hooks that require audio.
Definition: channel.c:2530

◆ native_rtp_bridge_channel_data_alloc()

static struct native_rtp_bridge_channel_data* native_rtp_bridge_channel_data_alloc ( void  )
static

Definition at line 150 of file bridge_native_rtp.c.

References ast_calloc, native_rtp_bridge_channel_data::glue, and rtp_glue_data_init().

Referenced by native_rtp_bridge_join().

151 {
152  struct native_rtp_bridge_channel_data *data;
153 
154  data = ast_calloc(1, sizeof(*data));
155  if (data) {
156  rtp_glue_data_init(&data->glue);
157  }
158  return data;
159 }
Internal structure which contains instance information about bridged RTP channels.
static void rtp_glue_data_init(struct rtp_glue_data *glue)
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct rtp_glue_data glue
Channel&#39;s cached RTP glue information.

◆ native_rtp_bridge_channel_data_free()

static void native_rtp_bridge_channel_data_free ( struct native_rtp_bridge_channel_data data)
static

Definition at line 136 of file bridge_native_rtp.c.

References ao2_cleanup, ast_debug, ast_free, native_rtp_bridge_channel_data::glue, native_rtp_bridge_channel_data::hook_data, and rtp_glue_data_reset().

Referenced by native_rtp_bridge_join(), and native_rtp_bridge_leave().

137 {
138  ast_debug(2, "Destroying channel tech_pvt data %p\n", data);
139 
140  /*
141  * hook_data will probably already have been unreferenced by the framehook detach
142  * and the pointer set to null.
143  */
144  ao2_cleanup(data->hook_data);
145 
146  rtp_glue_data_reset(&data->glue);
147  ast_free(data);
148 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static void rtp_glue_data_reset(struct rtp_glue_data *glue)
struct native_rtp_framehook_data * hook_data
Channel&#39;s hook data.
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct rtp_glue_data glue
Channel&#39;s cached RTP glue information.

◆ native_rtp_bridge_compatible()

static int native_rtp_bridge_compatible ( struct ast_bridge bridge)
static

Definition at line 765 of file bridge_native_rtp.c.

References ast_channel_lock_both, ast_channel_unlock, ast_debug, AST_LIST_FIRST, AST_LIST_LAST, ast_bridge_channel::chan, ast_bridge::channels, native_rtp_bridge_compatible_check(), ast_bridge::num_channels, and ast_bridge::uniqueid.

766 {
767  struct ast_bridge_channel *bc0;
768  struct ast_bridge_channel *bc1;
769  int is_compatible;
770 
771  /* We require two channels before even considering native bridging */
772  if (bridge->num_channels != 2) {
773  ast_debug(1, "Bridge '%s' can not use native RTP bridge as two channels are required\n",
774  bridge->uniqueid);
775  return 0;
776  }
777 
778  bc0 = AST_LIST_FIRST(&bridge->channels);
779  bc1 = AST_LIST_LAST(&bridge->channels);
780 
781  ast_channel_lock_both(bc0->chan, bc1->chan);
782  is_compatible = native_rtp_bridge_compatible_check(bridge, bc0, bc1);
783  ast_channel_unlock(bc0->chan);
784  ast_channel_unlock(bc1->chan);
785 
786  return is_compatible;
787 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
const ast_string_field uniqueid
Definition: bridge.h:409
static int native_rtp_bridge_compatible_check(struct ast_bridge *bridge, struct ast_bridge_channel *bc0, struct ast_bridge_channel *bc1)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
unsigned int num_channels
Definition: bridge.h:381

◆ native_rtp_bridge_compatible_check()

static int native_rtp_bridge_compatible_check ( struct ast_bridge bridge,
struct ast_bridge_channel bc0,
struct ast_bridge_channel bc1 
)
static

Definition at line 632 of file bridge_native_rtp.c.

References ao2_cleanup, ao2_container_count(), ast_channel_name(), ast_channel_rawreadformat(), ast_channel_rawwriteformat(), ast_debug, ast_format_cap_alloc, ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format_framing(), ast_format_cap_get_names(), ast_format_cap_iscompatible(), AST_FORMAT_CAP_NAMES_LEN, ast_rtp_codecs_get_framing(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, ast_rtp_instance_dtmf_mode_get(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_engine(), ast_str_alloca, ast_bridge_channel::chan, ast_rtp_engine::dtmf_compatible, ast_bridge_features::dtmf_hooks, ast_bridge_channel::features, ast_rtp_engine::local_bridge, native_rtp_bridge_capable(), NULL, RAII_VAR, rtp_glue_data_destroy(), rtp_glue_data_get(), rtp_glue_data_init(), and ast_bridge::uniqueid.

Referenced by native_rtp_bridge_compatible().

633 {
634  enum ast_rtp_glue_result native_type;
635  int read_ptime0;
636  int read_ptime1;
637  int write_ptime0;
638  int write_ptime1;
639  struct rtp_glue_data glue_a;
640  struct rtp_glue_data glue_b;
641  RAII_VAR(struct ast_format_cap *, cap0, NULL, ao2_cleanup);
642  RAII_VAR(struct ast_format_cap *, cap1, NULL, ao2_cleanup);
645 
646  ast_debug(1, "Bridge '%s'. Checking compatability for channels '%s' and '%s'\n",
647  bridge->uniqueid, ast_channel_name(bc0->chan), ast_channel_name(bc1->chan));
648 
649  if (!native_rtp_bridge_capable(bc0->chan)) {
650  ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has features which prevent it\n",
651  bridge->uniqueid, ast_channel_name(bc0->chan));
652  return 0;
653  }
654 
655  if (!native_rtp_bridge_capable(bc1->chan)) {
656  ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has features which prevent it\n",
657  bridge->uniqueid, ast_channel_name(bc1->chan));
658  return 0;
659  }
660 
661  rtp_glue_data_init(&glue_a);
662  glue0 = &glue_a;
663  rtp_glue_data_init(&glue_b);
664  glue1 = &glue_b;
665  if (rtp_glue_data_get(bc0->chan, glue0, bc1->chan, glue1)) {
666  ast_debug(1, "Bridge '%s' can not use native RTP bridge as could not get details\n",
667  bridge->uniqueid);
668  return 0;
669  }
670  native_type = glue0->result;
671 
672  if (native_type == AST_RTP_GLUE_RESULT_FORBID) {
673  ast_debug(1, "Bridge '%s' can not use native RTP bridge as it was forbidden while getting details\n",
674  bridge->uniqueid);
675  return 0;
676  }
677 
679  && ast_rtp_instance_dtmf_mode_get(glue0->audio.instance)) {
680  ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has DTMF hooks\n",
681  bridge->uniqueid, ast_channel_name(bc0->chan));
682  return 0;
683  }
684 
686  && ast_rtp_instance_dtmf_mode_get(glue1->audio.instance)) {
687  ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has DTMF hooks\n",
688  bridge->uniqueid, ast_channel_name(bc1->chan));
689  return 0;
690  }
691 
692  if (native_type == AST_RTP_GLUE_RESULT_LOCAL
693  && (ast_rtp_instance_get_engine(glue0->audio.instance)->local_bridge
694  != ast_rtp_instance_get_engine(glue1->audio.instance)->local_bridge
695  || (ast_rtp_instance_get_engine(glue0->audio.instance)->dtmf_compatible
696  && !ast_rtp_instance_get_engine(glue0->audio.instance)->dtmf_compatible(bc0->chan,
697  glue0->audio.instance, bc1->chan, glue1->audio.instance)))) {
698  ast_debug(1, "Bridge '%s' can not use local native RTP bridge as local bridge or DTMF is not compatible\n",
699  bridge->uniqueid);
700  return 0;
701  }
702 
705  if (!cap0 || !cap1) {
706  return 0;
707  }
708 
709  /* Make sure that codecs match */
710  if (glue0->cb->get_codec) {
711  glue0->cb->get_codec(bc0->chan, cap0);
712  }
713  if (glue1->cb->get_codec) {
714  glue1->cb->get_codec(bc1->chan, cap1);
715  }
716  if (ast_format_cap_count(cap0) != 0
717  && ast_format_cap_count(cap1) != 0
718  && !ast_format_cap_iscompatible(cap0, cap1)) {
719  struct ast_str *codec_buf0 = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
720  struct ast_str *codec_buf1 = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
721 
722  ast_debug(1, "Bridge '%s': Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n",
723  bridge->uniqueid,
724  ast_format_cap_get_names(cap0, &codec_buf0),
725  ast_format_cap_get_names(cap1, &codec_buf1));
726  return 0;
727  }
728 
729  if (glue0->audio.instance && glue1->audio.instance) {
730  unsigned int framing_inst0, framing_inst1;
731  framing_inst0 = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(glue0->audio.instance));
732  framing_inst1 = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(glue1->audio.instance));
733  if (framing_inst0 != framing_inst1) {
734  /* ptimes are asymmetric on the two call legs so we can't use the native bridge */
735  ast_debug(1, "Asymmetric ptimes on the two call legs (%u != %u). Cannot native bridge in RTP\n",
736  framing_inst0, framing_inst1);
737  return 0;
738  }
739  ast_debug(3, "Symmetric ptimes on the two call legs (%u). May be able to native bridge in RTP\n",
740  framing_inst0);
741  }
742 
747 
748  if (read_ptime0 != write_ptime1 || read_ptime1 != write_ptime0) {
749  ast_debug(1, "Bridge '%s': Packetization differs between RTP streams (%d != %d or %d != %d). Cannot native bridge in RTP\n",
750  bridge->uniqueid,
751  read_ptime0, write_ptime1, read_ptime1, write_ptime0);
752  return 0;
753  }
754  ast_debug(3, "Bridge '%s': Packetization comparison success between RTP streams (read_ptime0:%d == write_ptime1:%d and read_ptime1:%d == write_ptime0:%d).\n",
755  bridge->uniqueid,
756  read_ptime0, write_ptime1, read_ptime1, write_ptime0);
757 
758  return 1;
759 }
const ast_string_field uniqueid
Definition: bridge.h:409
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ast_bridge_features * features
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:727
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
struct ao2_container * dtmf_hooks
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
#define ast_str_alloca(init_len)
Definition: strings.h:800
#define NULL
Definition: resample.c:96
unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs)
Get the framing used for a set of codecs.
Definition: rtp_engine.c:1569
static void rtp_glue_data_destroy(struct rtp_glue_data *glue)
static int rtp_glue_data_get(struct ast_channel *c0, struct rtp_glue_data *glue0, struct ast_channel *c1, struct rtp_glue_data *glue1)
static void rtp_glue_data_init(struct rtp_glue_data *glue)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int(* dtmf_compatible)(struct ast_channel *chan0, struct ast_rtp_instance *instance0, struct ast_channel *chan1, struct ast_rtp_instance *instance1)
Definition: rtp_engine.h:671
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static int native_rtp_bridge_capable(struct ast_channel *chan)
struct ast_rtp_engine * ast_rtp_instance_get_engine(struct ast_rtp_instance *instance)
Get the RTP engine in use on an RTP instance.
Definition: rtp_engine.c:2700
ast_rtp_glue_result
Definition: rtp_engine.h:158
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format)
Get the framing for a format.
Definition: format_cap.c:443
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
struct ast_channel * chan
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
int(* local_bridge)(struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1)
Definition: rtp_engine.h:663
enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance)
Get the DTMF mode of an RTP instance.
Definition: rtp_engine.c:2137
struct ast_format * ast_channel_rawwriteformat(struct ast_channel *chan)
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition: format_cap.c:655

◆ native_rtp_bridge_framehook_attach()

static int native_rtp_bridge_framehook_attach ( struct ast_bridge_channel bridge_channel)
static

Definition at line 793 of file bridge_native_rtp.c.

References __ao2_cleanup(), AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_bump, ao2_ref, ast_assert, ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, ast_framehook_attach(), AST_FRAMEHOOK_INTERFACE_VERSION, ast_bridge_channel::bridge, ast_bridge_channel::chan, ast_framehook_interface::data, native_rtp_bridge_channel_data::hook_data, native_rtp_framehook_data::id, native_rtp_framehook(), native_rtp_framehook_consume(), NULL, ast_bridge_channel::tech_pvt, ast_bridge::uniqueid, and ast_framehook_interface::version.

Referenced by native_rtp_bridge_join().

794 {
795  struct native_rtp_bridge_channel_data *data = bridge_channel->tech_pvt;
796  struct ast_framehook_interface hook = {
798  .event_cb = native_rtp_framehook,
799  .destroy_cb = __ao2_cleanup,
800  .consume_cb = native_rtp_framehook_consume,
801  .disable_inheritance = 1,
802  };
803 
804  ast_assert(data->hook_data == NULL);
805  data->hook_data = ao2_alloc_options(sizeof(*data->hook_data), NULL,
807  if (!data->hook_data) {
808  return -1;
809  }
810 
811  ast_debug(2, "Bridge '%s'. Attaching hook data %p to '%s'\n",
812  bridge_channel->bridge->uniqueid, data, ast_channel_name(bridge_channel->chan));
813 
814  /* We're giving 1 ref to the framehook and keeping the one from the alloc for ourselves */
815  hook.data = ao2_bump(data->hook_data);
816 
817  ast_channel_lock(bridge_channel->chan);
818  data->hook_data->id = ast_framehook_attach(bridge_channel->chan, &hook);
819  ast_channel_unlock(bridge_channel->chan);
820  if (data->hook_data->id < 0) {
821  /*
822  * We need to drop both the reference we hold in data,
823  * and the one the framehook would hold.
824  */
825  ao2_ref(data->hook_data, -2);
826  data->hook_data = NULL;
827 
828  return -1;
829  }
830 
831  return 0;
832 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
const ast_string_field uniqueid
Definition: bridge.h:409
static struct ast_frame * native_rtp_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
void __ao2_cleanup(void *obj)
Definition: astobj2.c:674
int id
Framehook used to intercept certain control frames.
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
struct ast_bridge * bridge
Bridge this channel is participating in.
Internal structure which contains instance information about bridged RTP channels.
#define ao2_bump(obj)
Definition: astobj2.h:491
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int native_rtp_framehook_consume(void *data, enum ast_frame_type type)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct native_rtp_framehook_data * hook_data
Channel&#39;s hook data.
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * tech_pvt
Private information unique to the bridge technology.
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)

◆ native_rtp_bridge_framehook_detach()

static void native_rtp_bridge_framehook_detach ( struct ast_bridge_channel bridge_channel)
static

Definition at line 838 of file bridge_native_rtp.c.

References ao2_cleanup, ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, ast_framehook_detach(), ast_bridge_channel::bridge, ast_bridge_channel::chan, native_rtp_framehook_data::detached, native_rtp_bridge_channel_data::hook_data, native_rtp_framehook_data::id, NULL, ast_bridge_channel::tech_pvt, and ast_bridge::uniqueid.

Referenced by native_rtp_bridge_leave().

839 {
840  struct native_rtp_bridge_channel_data *data = bridge_channel->tech_pvt;
841 
842  if (!data || !data->hook_data) {
843  return;
844  }
845 
846  ast_debug(2, "Bridge '%s'. Detaching hook data %p from '%s'\n",
847  bridge_channel->bridge->uniqueid, data->hook_data, ast_channel_name(bridge_channel->chan));
848 
849  ast_channel_lock(bridge_channel->chan);
850  ast_framehook_detach(bridge_channel->chan, data->hook_data->id);
851  data->hook_data->detached = 1;
852  ast_channel_unlock(bridge_channel->chan);
853  ao2_cleanup(data->hook_data);
854  data->hook_data = NULL;
855 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
const ast_string_field uniqueid
Definition: bridge.h:409
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
int id
Framehook used to intercept certain control frames.
#define NULL
Definition: resample.c:96
struct ast_bridge * bridge
Bridge this channel is participating in.
Internal structure which contains instance information about bridged RTP channels.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct native_rtp_framehook_data * hook_data
Channel&#39;s hook data.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * tech_pvt
Private information unique to the bridge technology.
struct ast_channel * chan
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
unsigned int detached
Set when this framehook has been detached.

◆ native_rtp_bridge_join()

static int native_rtp_bridge_join ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Forward declarations.

Definition at line 967 of file bridge_native_rtp.c.

References ast_assert, ast_channel_get_stream_topology(), ast_channel_lock_both, ast_channel_name(), ast_channel_request_stream_topology_change(), ast_channel_unlock, ast_debug, AST_LIST_FIRST, AST_LIST_LAST, ast_stream_topology_free(), ast_stream_topology_get_count(), ast_bridge_channel::chan, ast_bridge::channels, native_rtp_bridge_channel_data_alloc(), native_rtp_bridge_channel_data_free(), native_rtp_bridge_framehook_attach(), native_rtp_bridge_start(), native_rtp_request_stream_topology_update(), NULL, ast_bridge_channel::suspended, SWAP, ast_bridge_channel::tech_pvt, and ast_bridge::uniqueid.

Referenced by native_rtp_bridge_unsuspend().

968 {
969  struct ast_stream_topology *req_top;
970  struct ast_stream_topology *existing_top;
971  struct ast_stream_topology *new_top;
972  struct ast_channel *c0 = AST_LIST_FIRST(&bridge->channels)->chan;
973  struct ast_channel *c1 = AST_LIST_LAST(&bridge->channels)->chan;
974 
975  ast_debug(2, "Bridge '%s'. Channel '%s' is joining bridge tech\n",
976  bridge->uniqueid, ast_channel_name(bridge_channel->chan));
977 
978  ast_assert(bridge_channel->tech_pvt == NULL);
979 
980  if (bridge_channel->suspended) {
981  /* The channel will rejoin when it is unsuspended */
982  return 0;
983  }
984 
986  if (!bridge_channel->tech_pvt) {
987  return -1;
988  }
989 
990  if (native_rtp_bridge_framehook_attach(bridge_channel)) {
992  bridge_channel->tech_pvt = NULL;
993  return -1;
994  }
995 
996  if (c0 != c1) {
997  /* When both channels are joined we want to try to improve the experience by
998  * raising the number of streams so they match.
999  */
1000  ast_channel_lock_both(c0, c1);
1001  req_top = ast_channel_get_stream_topology(c0);
1002  existing_top = ast_channel_get_stream_topology(c1);
1003  if (ast_stream_topology_get_count(req_top) < ast_stream_topology_get_count(existing_top)) {
1004  SWAP(req_top, existing_top);
1005  SWAP(c0, c1);
1006  }
1007  new_top = native_rtp_request_stream_topology_update(existing_top, req_top);
1008  ast_channel_unlock(c0);
1009  ast_channel_unlock(c1);
1010 
1011  if (new_top) {
1013  ast_stream_topology_free(new_top);
1014  }
1015  }
1016 
1017  native_rtp_bridge_start(bridge, NULL);
1018  return 0;
1019 }
Main Channel structure associated with a channel.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
unsigned int suspended
#define ast_assert(a)
Definition: utils.h:695
#define SWAP(a, b)
Definition: utils.h:230
int ast_channel_request_stream_topology_change(struct ast_channel *chan, struct ast_stream_topology *topology, void *change_source)
Request that the stream topology of a channel change.
Definition: channel.c:11167
#define NULL
Definition: resample.c:96
static struct ast_bridge_technology native_rtp_bridge
static struct ast_stream_topology * native_rtp_request_stream_topology_update(struct ast_stream_topology *existing_topology, struct ast_stream_topology *requested_topology)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static void native_rtp_bridge_channel_data_free(struct native_rtp_bridge_channel_data *data)
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * tech_pvt
Private information unique to the bridge technology.
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
static struct native_rtp_bridge_channel_data * native_rtp_bridge_channel_data_alloc(void)
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
static void native_rtp_bridge_start(struct ast_bridge *bridge, struct ast_channel *target)
static int native_rtp_bridge_framehook_attach(struct ast_bridge_channel *bridge_channel)

◆ native_rtp_bridge_leave()

static void native_rtp_bridge_leave ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 1036 of file bridge_native_rtp.c.

References ast_channel_name(), ast_debug, ast_bridge_channel::chan, native_rtp_bridge_channel_data_free(), native_rtp_bridge_framehook_detach(), native_rtp_bridge_stop(), NULL, ast_bridge_channel::tech_pvt, and ast_bridge::uniqueid.

Referenced by native_rtp_bridge_suspend().

1037 {
1038  ast_debug(2, "Bridge '%s'. Channel '%s' is leaving bridge tech\n",
1039  bridge->uniqueid, ast_channel_name(bridge_channel->chan));
1040 
1041  if (!bridge_channel->tech_pvt) {
1042  return;
1043  }
1044 
1045  native_rtp_bridge_framehook_detach(bridge_channel);
1046  native_rtp_bridge_stop(bridge, NULL);
1047 
1049  bridge_channel->tech_pvt = NULL;
1050 }
const ast_string_field uniqueid
Definition: bridge.h:409
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static void native_rtp_bridge_channel_data_free(struct native_rtp_bridge_channel_data *data)
static void native_rtp_bridge_stop(struct ast_bridge *bridge, struct ast_channel *target)
static void native_rtp_bridge_framehook_detach(struct ast_bridge_channel *bridge_channel)
void * tech_pvt
Private information unique to the bridge technology.
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)

◆ native_rtp_bridge_start()

static void native_rtp_bridge_start ( struct ast_bridge bridge,
struct ast_channel target 
)
static

Definition at line 289 of file bridge_native_rtp.c.

References ao2_cleanup, ast_assert, ast_channel_lock_both, ast_channel_name(), ast_channel_unlock, ast_debug, ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, AST_LIST_FIRST, AST_LIST_LAST, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_engine(), ast_rtp_instance_set_bridged(), ast_verb, rtp_glue_data::audio, rtp_glue_data::cb, ast_bridge_channel::chan, ast_bridge::channels, done, ast_rtp_glue::get_codec, native_rtp_bridge_channel_data::glue, rtp_glue_stream::instance, ast_rtp_engine::local_bridge, NULL, native_rtp_bridge_channel_data::remote_cb, rtp_glue_data::result, rtp_glue_data_get(), ast_bridge_channel::tech_pvt, ast_bridge::uniqueid, ast_rtp_glue::update_peer, and rtp_glue_data::video.

Referenced by native_rtp_bridge_join(), and native_rtp_framehook().

290 {
291  struct ast_bridge_channel *bc0 = AST_LIST_FIRST(&bridge->channels);
292  struct ast_bridge_channel *bc1 = AST_LIST_LAST(&bridge->channels);
293  struct native_rtp_bridge_channel_data *data0;
294  struct native_rtp_bridge_channel_data *data1;
295  struct rtp_glue_data *glue0;
296  struct rtp_glue_data *glue1;
297  struct ast_format_cap *cap0;
298  struct ast_format_cap *cap1;
299  enum ast_rtp_glue_result native_type;
300 
301  if (bc0 == bc1) {
302  return;
303  }
304  data0 = bc0->tech_pvt;
305  data1 = bc1->tech_pvt;
306  if (!data0 || !data1) {
307  /* Not all channels are joined with the bridge tech yet */
308  return;
309  }
310  glue0 = &data0->glue;
311  glue1 = &data1->glue;
312 
313  ast_channel_lock_both(bc0->chan, bc1->chan);
314 
315  if (!glue0->cb || !glue1->cb) {
316  /*
317  * Somebody doesn't have glue data so the bridge isn't running
318  *
319  * Actually neither side should have glue data.
320  */
321  ast_assert(!glue0->cb && !glue1->cb);
322 
323  if (rtp_glue_data_get(bc0->chan, glue0, bc1->chan, glue1)) {
324  /*
325  * This might happen if one of the channels got masqueraded
326  * at a critical time. It's a bit of a stretch even then
327  * since the channel is in a bridge.
328  */
329  goto done;
330  }
331  }
332 
333  ast_debug(2, "Bridge '%s'. Tech starting '%s' and '%s' with target '%s'\n",
334  bridge->uniqueid, ast_channel_name(bc0->chan), ast_channel_name(bc1->chan),
335  target ? ast_channel_name(target) : "none");
336 
337  native_type = glue0->result;
338 
339  switch (native_type) {
343  }
346  }
349  ast_verb(4, "Locally RTP bridged '%s' and '%s' in stack\n",
351  break;
355  if (!cap0 || !cap1) {
356  ao2_cleanup(cap0);
357  ao2_cleanup(cap1);
358  break;
359  }
360 
361  if (glue0->cb->get_codec) {
362  glue0->cb->get_codec(bc0->chan, cap0);
363  }
364  if (glue1->cb->get_codec) {
365  glue1->cb->get_codec(bc1->chan, cap1);
366  }
367 
368  /*
369  * If we have a target, it's the channel that received the UNHOLD or
370  * UPDATE_RTP_PEER frame and was told to resume
371  */
372  if (!target) {
373  /* Send both channels to remote */
374  data0->remote_cb = glue0->cb;
375  data1->remote_cb = glue1->cb;
376  glue0->cb->update_peer(bc0->chan, glue1->audio.instance, glue1->video.instance, NULL, cap1, 0);
377  glue1->cb->update_peer(bc1->chan, glue0->audio.instance, glue0->video.instance, NULL, cap0, 0);
378  ast_verb(4, "Remotely bridged '%s' and '%s' - media will flow directly between them\n",
380  } else {
381  /*
382  * If a target was provided, it is the recipient of an unhold or an update and needs to have
383  * its media redirected to fit the current remote bridging needs. The other channel is either
384  * already set up to handle the new media path or will have its own set of updates independent
385  * of this pass.
386  */
387  ast_debug(2, "Bridge '%s'. Sending '%s' back to remote\n",
388  bridge->uniqueid, ast_channel_name(target));
389  if (bc0->chan == target) {
390  data0->remote_cb = glue0->cb;
391  glue0->cb->update_peer(bc0->chan, glue1->audio.instance, glue1->video.instance, NULL, cap1, 0);
392  } else {
393  data1->remote_cb = glue1->cb;
394  glue1->cb->update_peer(bc1->chan, glue0->audio.instance, glue0->video.instance, NULL, cap0, 0);
395  }
396  }
397 
398  ao2_cleanup(cap0);
399  ao2_cleanup(cap1);
400  break;
402  break;
403  }
404 
405  if (native_type != AST_RTP_GLUE_RESULT_REMOTE) {
406  /* Bring any remaining channels back to us. */
407  if (data0->remote_cb) {
408  ast_debug(2, "Bridge '%s'. Bringing back '%s' to us\n",
409  bridge->uniqueid, ast_channel_name(bc0->chan));
410  data0->remote_cb->update_peer(bc0->chan, NULL, NULL, NULL, NULL, 0);
411  data0->remote_cb = NULL;
412  }
413  if (data1->remote_cb) {
414  ast_debug(2, "Bridge '%s'. Bringing back '%s' to us\n",
415  bridge->uniqueid, ast_channel_name(bc1->chan));
416  data1->remote_cb->update_peer(bc1->chan, NULL, NULL, NULL, NULL, 0);
417  data1->remote_cb = NULL;
418  }
419  }
420 
421 done:
422  ast_channel_unlock(bc0->chan);
423  ast_channel_unlock(bc1->chan);
424 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
const ast_string_field uniqueid
Definition: bridge.h:409
int(* update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active)
Definition: rtp_engine.h:756
#define ast_assert(a)
Definition: utils.h:695
struct ast_rtp_glue * cb
glue callbacks
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
Internal structure which contains instance information about bridged RTP channels.
int done
Definition: test_amihooks.c:48
struct rtp_glue_stream video
static int rtp_glue_data_get(struct ast_channel *c0, struct rtp_glue_data *glue0, struct ast_channel *c1, struct rtp_glue_data *glue1)
void ast_rtp_instance_set_bridged(struct ast_rtp_instance *instance, struct ast_rtp_instance *bridged)
Set the other RTP instance that an instance is bridged to.
Definition: rtp_engine.c:2244
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_rtp_instance * instance
RTP instance.
struct ast_rtp_glue * remote_cb
Glue callbacks to bring remote channel streams back to Asterisk.
struct ast_rtp_engine * ast_rtp_instance_get_engine(struct ast_rtp_instance *instance)
Get the RTP engine in use on an RTP instance.
Definition: rtp_engine.c:2700
enum ast_rtp_glue_result result
ast_rtp_glue_result
Definition: rtp_engine.h:158
void(* get_codec)(struct ast_channel *chan, struct ast_format_cap *result_cap)
Callback for retrieving codecs that the channel can do. Result returned in result_cap.
Definition: rtp_engine.h:761
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * tech_pvt
Private information unique to the bridge technology.
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
struct rtp_glue_stream audio
int(* local_bridge)(struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1)
Definition: rtp_engine.h:663
struct rtp_glue_data glue
Channel&#39;s cached RTP glue information.

◆ native_rtp_bridge_stop()

static void native_rtp_bridge_stop ( struct ast_bridge bridge,
struct ast_channel target 
)
static

Definition at line 435 of file bridge_native_rtp.c.

References ast_assert, ast_channel_lock, ast_channel_lock_both, ast_channel_name(), ast_channel_unlock, ast_debug, AST_LIST_FIRST, AST_LIST_LAST, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_engine(), ast_rtp_instance_set_bridged(), rtp_glue_data::audio, rtp_glue_data::cb, ast_bridge_channel::chan, ast_bridge::channels, native_rtp_bridge_channel_data::glue, rtp_glue_stream::instance, ast_rtp_engine::local_bridge, NULL, native_rtp_bridge_channel_data::remote_cb, rtp_glue_data::result, rtp_glue_data_reset(), rtp_glue_get_current_combined_result(), ast_bridge_channel::tech_pvt, ast_bridge::uniqueid, and ast_rtp_glue::update_peer.

Referenced by native_rtp_bridge_leave(), and native_rtp_framehook().

436 {
437  struct ast_bridge_channel *bc0 = AST_LIST_FIRST(&bridge->channels);
438  struct ast_bridge_channel *bc1 = AST_LIST_LAST(&bridge->channels);
439  struct native_rtp_bridge_channel_data *data0;
440  struct native_rtp_bridge_channel_data *data1;
441  struct rtp_glue_data *glue0;
442  struct rtp_glue_data *glue1;
443 
444  if (bc0 == bc1) {
445  return;
446  }
447  data0 = bc0->tech_pvt;
448  data1 = bc1->tech_pvt;
449  if (!data0 || !data1) {
450  /* Not all channels are joined with the bridge tech */
451  return;
452  }
453  glue0 = &data0->glue;
454  glue1 = &data1->glue;
455 
456  ast_debug(2, "Bridge '%s'. Tech stopping '%s' and '%s' with target '%s'\n",
457  bridge->uniqueid, ast_channel_name(bc0->chan), ast_channel_name(bc1->chan),
458  target ? ast_channel_name(target) : "none");
459 
460  if (!glue0->cb || !glue1->cb) {
461  /*
462  * Somebody doesn't have glue data so the bridge isn't running
463  *
464  * Actually neither side should have glue data.
465  */
466  ast_assert(!glue0->cb && !glue1->cb);
467  /* At most one channel can be left at the remote endpoint here. */
468  ast_assert(!data0->remote_cb || !data1->remote_cb);
469 
470  /* Bring selected channel streams back to us */
471  if (data0->remote_cb && (!target || target == bc0->chan)) {
472  ast_channel_lock(bc0->chan);
473  ast_debug(2, "Bridge '%s'. Bringing back '%s' to us\n",
474  bridge->uniqueid, ast_channel_name(bc0->chan));
475  data0->remote_cb->update_peer(bc0->chan, NULL, NULL, NULL, NULL, 0);
476  data0->remote_cb = NULL;
477  ast_channel_unlock(bc0->chan);
478  }
479  if (data1->remote_cb && (!target || target == bc1->chan)) {
480  ast_channel_lock(bc1->chan);
481  ast_debug(2, "Bridge '%s'. Bringing back '%s' to us\n",
482  bridge->uniqueid, ast_channel_name(bc1->chan));
483  data1->remote_cb->update_peer(bc1->chan, NULL, NULL, NULL, NULL, 0);
484  data1->remote_cb = NULL;
485  ast_channel_unlock(bc1->chan);
486  }
487  return;
488  }
489 
490  ast_channel_lock_both(bc0->chan, bc1->chan);
491 
492  switch (glue0->result) {
496  }
499  }
502  break;
504  if (target) {
505  /*
506  * If a target was provided, it is being put on hold and should expect to
507  * receive media from Asterisk instead of what it was previously connected to.
508  */
509  ast_debug(2, "Bridge '%s'. Bringing back '%s' to us\n",
510  bridge->uniqueid, ast_channel_name(target));
511  if (bc0->chan == target) {
512  data0->remote_cb = NULL;
513  glue0->cb->update_peer(bc0->chan, NULL, NULL, NULL, NULL, 0);
514  } else {
515  data1->remote_cb = NULL;
516  glue1->cb->update_peer(bc1->chan, NULL, NULL, NULL, NULL, 0);
517  }
518  } else {
519  data0->remote_cb = NULL;
520  data1->remote_cb = NULL;
521  /*
522  * XXX We don't want to bring back the channels if we are
523  * switching to T.38. We have received a reinvite on one channel
524  * and we will be sending a reinvite on the other to start T.38.
525  * If we bring the streams back now we confuse the chan_pjsip
526  * channel driver processing the incoming T.38 reinvite with
527  * reinvite glare. I think this is really a bug in chan_pjsip
528  * that this exception case is working around.
529  */
532  ast_debug(2, "Bridge '%s'. Bringing back '%s' and '%s' to us\n",
533  bridge->uniqueid, ast_channel_name(bc0->chan),
534  ast_channel_name(bc1->chan));
535  glue0->cb->update_peer(bc0->chan, NULL, NULL, NULL, NULL, 0);
536  glue1->cb->update_peer(bc1->chan, NULL, NULL, NULL, NULL, 0);
537  } else {
538  ast_debug(2, "Bridge '%s'. Skip bringing back '%s' and '%s' to us\n",
539  bridge->uniqueid, ast_channel_name(bc0->chan),
540  ast_channel_name(bc1->chan));
541  }
542  }
543  break;
545  break;
546  }
547 
548  rtp_glue_data_reset(glue0);
549  rtp_glue_data_reset(glue1);
550 
551  ast_debug(2, "Discontinued RTP bridging of '%s' and '%s' - media will flow through Asterisk core\n",
553 
554  ast_channel_unlock(bc0->chan);
555  ast_channel_unlock(bc1->chan);
556 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static enum ast_rtp_glue_result rtp_glue_get_current_combined_result(struct ast_channel *c0, struct ast_channel *c1)
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
const ast_string_field uniqueid
Definition: bridge.h:409
int(* update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active)
Definition: rtp_engine.h:756
#define ast_assert(a)
Definition: utils.h:695
struct ast_rtp_glue * cb
glue callbacks
#define NULL
Definition: resample.c:96
Internal structure which contains instance information about bridged RTP channels.
void ast_rtp_instance_set_bridged(struct ast_rtp_instance *instance, struct ast_rtp_instance *bridged)
Set the other RTP instance that an instance is bridged to.
Definition: rtp_engine.c:2244
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_rtp_instance * instance
RTP instance.
static void rtp_glue_data_reset(struct rtp_glue_data *glue)
struct ast_rtp_glue * remote_cb
Glue callbacks to bring remote channel streams back to Asterisk.
struct ast_rtp_engine * ast_rtp_instance_get_engine(struct ast_rtp_instance *instance)
Get the RTP engine in use on an RTP instance.
Definition: rtp_engine.c:2700
enum ast_rtp_glue_result result
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * tech_pvt
Private information unique to the bridge technology.
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)
struct rtp_glue_stream audio
int(* local_bridge)(struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1)
Definition: rtp_engine.h:663
struct rtp_glue_data glue
Channel&#39;s cached RTP glue information.

◆ native_rtp_bridge_suspend()

static void native_rtp_bridge_suspend ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 1056 of file bridge_native_rtp.c.

References ast_channel_name(), ast_debug, ast_bridge_channel::chan, native_rtp_bridge_leave(), and ast_bridge::uniqueid.

1057 {
1058  ast_debug(2, "Bridge '%s'. Channel '%s' is suspending from bridge tech\n",
1059  bridge->uniqueid, ast_channel_name(bridge_channel->chan));
1060  native_rtp_bridge_leave(bridge, bridge_channel);
1061 }
const ast_string_field uniqueid
Definition: bridge.h:409
static void native_rtp_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)

◆ native_rtp_bridge_unsuspend()

static void native_rtp_bridge_unsuspend ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 1025 of file bridge_native_rtp.c.

References ast_channel_name(), ast_debug, ast_bridge_channel::chan, native_rtp_bridge_join(), and ast_bridge::uniqueid.

1026 {
1027  ast_debug(2, "Bridge '%s'. Channel '%s' is unsuspended back to bridge tech\n",
1028  bridge->uniqueid, ast_channel_name(bridge_channel->chan));
1029  native_rtp_bridge_join(bridge, bridge_channel);
1030 }
const ast_string_field uniqueid
Definition: bridge.h:409
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
static int native_rtp_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Forward declarations.

◆ native_rtp_bridge_write()

static int native_rtp_bridge_write ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel,
struct ast_frame frame 
)
static

Definition at line 1063 of file bridge_native_rtp.c.

References ast_bridge_queue_everyone_else(), AST_CONTROL_T38_PARAMETERS, AST_FRAME_CONTROL, AST_T38_REQUEST_NEGOTIATE, ast_frame::data, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::ptr, ast_control_t38_parameters::request_response, and ast_frame::subclass.

1064 {
1065  const struct ast_control_t38_parameters *t38_parameters;
1066  int defer = 0;
1067 
1068  if (!ast_bridge_queue_everyone_else(bridge, bridge_channel, frame)) {
1069  /* This frame was successfully queued so no need to defer */
1070  return 0;
1071  }
1072 
1073  /* Depending on the frame defer it so when the next channel joins it receives it */
1074  switch (frame->frametype) {
1075  case AST_FRAME_CONTROL:
1076  switch (frame->subclass.integer) {
1078  t38_parameters = frame->data.ptr;
1079  switch (t38_parameters->request_response) {
1081  defer = -1;
1082  break;
1083  default:
1084  break;
1085  }
1086  break;
1087  default:
1088  break;
1089  }
1090  break;
1091  default:
1092  break;
1093  }
1094 
1095  return defer;
1096 }
enum ast_control_t38 request_response
int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Queue the given frame to everyone else.
struct ast_frame_subclass subclass
union ast_frame::@263 data
enum ast_frame_type frametype

◆ native_rtp_framehook()

static struct ast_frame* native_rtp_framehook ( struct ast_channel chan,
struct ast_frame f,
enum ast_framehook_event  event,
void *  data 
)
static

Definition at line 562 of file bridge_native_rtp.c.

References ao2_ref, ast_bridge_lock, ast_bridge_unlock, ast_channel_get_bridge(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_FRAME_CONTROL, AST_FRAMEHOOK_EVENT_WRITE, native_rtp_framehook_data::detached, ast_frame::frametype, ast_frame_subclass::integer, native_rtp_bridge_start(), native_rtp_bridge_stop(), and ast_frame::subclass.

Referenced by native_rtp_bridge_framehook_attach().

564 {
565  struct ast_bridge *bridge;
566  struct native_rtp_framehook_data *native_data = data;
567 
568  if (!f
571  return f;
572  }
573 
574  bridge = ast_channel_get_bridge(chan);
575  if (bridge) {
576  /* native_rtp_bridge_start/stop are not being called from bridging
577  core so we need to lock the bridge prior to calling these functions
578  Unfortunately that means unlocking the channel, but as it
579  should not be modified this should be okay... hopefully...
580  unless this channel is being moved around right now and is in
581  the process of having this framehook removed (which is fine). To
582  ensure we then don't stop or start when we shouldn't we consult
583  the data provided. If this framehook has been detached then the
584  detached variable will be set. This is safe to check as it is only
585  manipulated with the bridge lock held. */
586  ast_channel_unlock(chan);
587  ast_bridge_lock(bridge);
588  if (!native_data->detached) {
589  switch (f->subclass.integer) {
590  case AST_CONTROL_HOLD:
591  native_rtp_bridge_stop(bridge, chan);
592  break;
593  case AST_CONTROL_UNHOLD:
595  native_rtp_bridge_start(bridge, chan);
596  break;
597  default:
598  break;
599  }
600  }
601  ast_bridge_unlock(bridge);
602  ao2_ref(bridge, -1);
603  ast_channel_lock(chan);
604  }
605 
606  return f;
607 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Definition: astman.c:222
struct ast_frame_subclass subclass
Internal structure which contains bridged RTP channel hook data.
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10735
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void native_rtp_bridge_stop(struct ast_bridge *bridge, struct ast_channel *target)
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
enum ast_frame_type frametype
unsigned int detached
Set when this framehook has been detached.
static void native_rtp_bridge_start(struct ast_bridge *bridge, struct ast_channel *target)

◆ native_rtp_framehook_consume()

static int native_rtp_framehook_consume ( void *  data,
enum ast_frame_type  type 
)
static

Definition at line 613 of file bridge_native_rtp.c.

References AST_FRAME_CONTROL.

Referenced by native_rtp_bridge_framehook_attach().

614 {
615  return (type == AST_FRAME_CONTROL ? 1 : 0);
616 }
static const char type[]
Definition: chan_ooh323.c:109

◆ native_rtp_request_stream_topology_update()

static struct ast_stream_topology* native_rtp_request_stream_topology_update ( struct ast_stream_topology existing_topology,
struct ast_stream_topology requested_topology 
)
static

Definition at line 857 of file bridge_native_rtp.c.

References AST_MEDIA_TYPE_AUDIO, ast_stream_get_formats(), ast_stream_get_state(), ast_stream_get_type(), ast_stream_set_formats(), ast_stream_set_state(), AST_STREAM_STATE_RECVONLY, AST_STREAM_STATE_REMOVED, AST_STREAM_STATE_SENDONLY, ast_stream_topology_clone(), ast_stream_topology_get_count(), ast_stream_topology_get_stream(), and NULL.

Referenced by native_rtp_bridge_join(), and native_rtp_stream_topology_changed().

860 {
861  struct ast_stream *stream;
862  const struct ast_format_cap *audio_formats = NULL;
863  struct ast_stream_topology *new_topology;
864  int i;
865 
866  new_topology = ast_stream_topology_clone(requested_topology);
867  if (!new_topology) {
868  return NULL;
869  }
870 
871  /* We find an existing stream with negotiated audio formats that we can place into
872  * any audio streams in the new topology to ensure that negotiation succeeds. Some
873  * endpoints incorrectly terminate the call if SDP negotiation fails.
874  */
875  for (i = 0; i < ast_stream_topology_get_count(existing_topology); ++i) {
876  stream = ast_stream_topology_get_stream(existing_topology, i);
877 
878  if (ast_stream_get_type(stream) != AST_MEDIA_TYPE_AUDIO ||
880  continue;
881  }
882 
883  audio_formats = ast_stream_get_formats(stream);
884  break;
885  }
886 
887  if (audio_formats) {
888  for (i = 0; i < ast_stream_topology_get_count(new_topology); ++i) {
889  stream = ast_stream_topology_get_stream(new_topology, i);
890 
891  if (ast_stream_get_type(stream) != AST_MEDIA_TYPE_AUDIO ||
893  continue;
894  }
895 
896  /* We haven't actually modified audio_formats so this is safe */
897  ast_stream_set_formats(stream, (struct ast_format_cap *)audio_formats);
898  }
899  }
900 
901  for (i = 0; i < ast_stream_topology_get_count(new_topology); ++i) {
902  stream = ast_stream_topology_get_stream(new_topology, i);
903 
904  /* For both recvonly and sendonly the stream state reflects our state, that is we
905  * are receiving only and we are sending only. Since we are renegotiating a remote
906  * party we need to swap this to reflect what we will be doing. That is, if we are
907  * receiving from Alice then we want to be sending to Bob, so swap recvonly to
908  * sendonly.
909  */
912  } else if (ast_stream_get_state(stream) == AST_STREAM_STATE_SENDONLY) {
914  }
915  }
916 
917  return new_topology;
918 }
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
Set when the stream has been removed/declined.
Definition: stream.h:78
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
#define NULL
Definition: resample.c:96
void ast_stream_set_formats(struct ast_stream *stream, struct ast_format_cap *caps)
Set the current negotiated formats of a stream.
Definition: stream.c:365
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Set when the stream is sending media only.
Definition: stream.h:86
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Definition: stream.c:380
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
Set when the stream is receiving media only.
Definition: stream.h:90
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373

◆ native_rtp_stream_topology_changed()

static void native_rtp_stream_topology_changed ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 920 of file bridge_native_rtp.c.

References ast_bridge_channel_stream_map(), ast_channel_get_stream_topology(), ast_channel_get_stream_topology_change_source(), ast_channel_lock_both, ast_channel_request_stream_topology_change(), ast_channel_unlock, AST_LIST_FIRST, AST_LIST_LAST, ast_stream_topology_free(), ast_bridge_channel::chan, ast_bridge::channels, and native_rtp_request_stream_topology_update().

922 {
923  struct ast_channel *c0 = bridge_channel->chan;
924  struct ast_channel *c1 = AST_LIST_FIRST(&bridge->channels)->chan;
925  struct ast_stream_topology *req_top;
926  struct ast_stream_topology *existing_top;
927  struct ast_stream_topology *new_top;
928 
929  ast_bridge_channel_stream_map(bridge_channel);
930 
932  == &native_rtp_bridge) {
933  return;
934  }
935 
936  if (c0 == c1) {
937  c1 = AST_LIST_LAST(&bridge->channels)->chan;
938  }
939 
940  if (c0 == c1) {
941  return;
942  }
943 
944  /* If a party renegotiates we want to renegotiate their counterpart to a matching
945  * topology.
946  */
947  ast_channel_lock_both(c0, c1);
948  req_top = ast_channel_get_stream_topology(c0);
949  existing_top = ast_channel_get_stream_topology(c1);
950  new_top = native_rtp_request_stream_topology_update(existing_top, req_top);
951  ast_channel_unlock(c0);
952  ast_channel_unlock(c1);
953 
954  if (!new_top) {
955  /* Failure. We'll just have to live with the current topology. */
956  return;
957  }
958 
960  ast_stream_topology_free(new_top);
961 }
Main Channel structure associated with a channel.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
int ast_channel_request_stream_topology_change(struct ast_channel *chan, struct ast_stream_topology *topology, void *change_source)
Request that the stream topology of a channel change.
Definition: channel.c:11167
static struct ast_bridge_technology native_rtp_bridge
static struct ast_stream_topology * native_rtp_request_stream_topology_update(struct ast_stream_topology *existing_topology, struct ast_stream_topology *requested_topology)
void * ast_channel_get_stream_topology_change_source(struct ast_channel *chan)
Retrieve the source that initiated the last stream topology change.
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
void ast_bridge_channel_stream_map(struct ast_bridge_channel *bridge_channel)
Maps a channel&#39;s stream topology to and from the bridge.
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743

◆ rtp_glue_data_destroy()

static void rtp_glue_data_destroy ( struct rtp_glue_data glue)
static

Definition at line 121 of file bridge_native_rtp.c.

References ao2_cleanup, rtp_glue_data::audio, rtp_glue_stream::instance, and rtp_glue_data::video.

Referenced by native_rtp_bridge_compatible_check(), rtp_glue_data_reset(), and rtp_glue_get_current_combined_result().

122 {
123  if (!glue) {
124  return;
125  }
126  ao2_cleanup(glue->audio.instance);
127  ao2_cleanup(glue->video.instance);
128 }
struct rtp_glue_stream video
struct ast_rtp_instance * instance
RTP instance.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct rtp_glue_stream audio

◆ rtp_glue_data_get()

static int rtp_glue_data_get ( struct ast_channel c0,
struct rtp_glue_data glue0,
struct ast_channel c1,
struct rtp_glue_data glue1 
)
static

Definition at line 168 of file bridge_native_rtp.c.

References ast_rtp_glue::allow_rtp_remote, ast_rtp_glue::allow_vrtp_remote, ast_channel_tech(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_glue(), rtp_glue_data::audio, rtp_glue_data::cb, ast_rtp_glue::get_rtp_info, ast_rtp_glue::get_vrtp_info, rtp_glue_stream::instance, rtp_glue_stream::result, rtp_glue_data::result, type, and rtp_glue_data::video.

Referenced by native_rtp_bridge_compatible_check(), native_rtp_bridge_start(), and rtp_glue_get_current_combined_result().

170 {
171  struct ast_rtp_glue *cb0;
172  struct ast_rtp_glue *cb1;
173  enum ast_rtp_glue_result combined_result;
174 
177  if (!cb0 || !cb1) {
178  /* One or both channels doesn't have any RTP glue registered. */
179  return -1;
180  }
181 
182  /* The glue callbacks bump the RTP instance refcounts for us. */
183 
184  glue0->cb = cb0;
185  glue0->audio.result = cb0->get_rtp_info(c0, &glue0->audio.instance);
186  glue0->video.result = cb0->get_vrtp_info
188 
189  glue1->cb = cb1;
190  glue1->audio.result = cb1->get_rtp_info(c1, &glue1->audio.instance);
191  glue1->video.result = cb1->get_vrtp_info
193 
194  /*
195  * Now determine the combined glue result.
196  */
197 
198  /* Apply any limitations on direct media bridging that may be present */
199  if (glue0->audio.result == glue1->audio.result && glue1->audio.result == AST_RTP_GLUE_RESULT_REMOTE) {
200  if (glue0->cb->allow_rtp_remote && !glue0->cb->allow_rtp_remote(c0, glue1->audio.instance)) {
201  /* If the allow_rtp_remote indicates that remote isn't allowed, revert to local bridge */
203  } else if (glue1->cb->allow_rtp_remote && !glue1->cb->allow_rtp_remote(c1, glue0->audio.instance)) {
205  }
206  }
207  if (glue0->video.result == glue1->video.result && glue1->video.result == AST_RTP_GLUE_RESULT_REMOTE) {
208  if (glue0->cb->allow_vrtp_remote && !glue0->cb->allow_vrtp_remote(c0, glue1->video.instance)) {
209  /* If the allow_vrtp_remote indicates that remote isn't allowed, revert to local bridge */
211  } else if (glue1->cb->allow_vrtp_remote && !glue1->cb->allow_vrtp_remote(c1, glue0->video.instance)) {
213  }
214  }
215 
216  /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
219  || glue0->video.result != AST_RTP_GLUE_RESULT_REMOTE)) {
221  }
224  || glue1->video.result != AST_RTP_GLUE_RESULT_REMOTE)) {
226  }
227 
228  /* The order of preference is: forbid, local, and remote. */
230  || glue1->audio.result == AST_RTP_GLUE_RESULT_FORBID) {
231  /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
232  combined_result = AST_RTP_GLUE_RESULT_FORBID;
233  } else if (glue0->audio.result == AST_RTP_GLUE_RESULT_LOCAL
234  || glue1->audio.result == AST_RTP_GLUE_RESULT_LOCAL) {
235  combined_result = AST_RTP_GLUE_RESULT_LOCAL;
236  } else {
237  combined_result = AST_RTP_GLUE_RESULT_REMOTE;
238  }
239  glue0->result = combined_result;
240  glue1->result = combined_result;
241 
242  return 0;
243 }
static const char type[]
Definition: chan_ooh323.c:109
struct ast_rtp_glue * cb
glue callbacks
struct rtp_glue_stream video
int(* allow_vrtp_remote)(struct ast_channel *chan1, struct ast_rtp_instance *instance)
Used to prevent two channels from remotely bridging video rtp if the channel tech has a reason for pr...
Definition: rtp_engine.h:747
enum ast_rtp_glue_result(* get_rtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance)
Callback for retrieving the RTP instance carrying audio.
Definition: rtp_engine.h:729
struct ast_rtp_instance * instance
RTP instance.
enum ast_rtp_glue_result result
ast_rtp_glue_result
Definition: rtp_engine.h:158
int(* allow_rtp_remote)(struct ast_channel *chan1, struct ast_rtp_instance *instance)
Used to prevent two channels from remotely bridging audio rtp if the channel tech has a reason for pr...
Definition: rtp_engine.h:735
struct rtp_glue_stream audio
enum ast_rtp_glue_result result
glue result
enum ast_rtp_glue_result(* get_vrtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance)
Callback for retrieving the RTP instance carrying video.
Definition: rtp_engine.h:741
struct ast_rtp_glue * ast_rtp_instance_get_glue(const char *type)
Get the RTP glue that binds a channel to the RTP engine.
Definition: rtp_engine.c:2206
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ rtp_glue_data_init()

static void rtp_glue_data_init ( struct rtp_glue_data glue)
static

Definition at line 111 of file bridge_native_rtp.c.

References AST_RTP_GLUE_RESULT_FORBID, rtp_glue_data::audio, rtp_glue_data::cb, rtp_glue_stream::instance, NULL, rtp_glue_stream::result, rtp_glue_data::result, and rtp_glue_data::video.

Referenced by native_rtp_bridge_channel_data_alloc(), native_rtp_bridge_compatible_check(), rtp_glue_data_reset(), and rtp_glue_get_current_combined_result().

112 {
113  glue->cb = NULL;
114  glue->audio.instance = NULL;
116  glue->video.instance = NULL;
119 }
struct ast_rtp_glue * cb
glue callbacks
#define NULL
Definition: resample.c:96
struct rtp_glue_stream video
struct ast_rtp_instance * instance
RTP instance.
enum ast_rtp_glue_result result
struct rtp_glue_stream audio
enum ast_rtp_glue_result result
glue result

◆ rtp_glue_data_reset()

static void rtp_glue_data_reset ( struct rtp_glue_data glue)
static

Definition at line 130 of file bridge_native_rtp.c.

References rtp_glue_data_destroy(), and rtp_glue_data_init().

Referenced by native_rtp_bridge_channel_data_free(), and native_rtp_bridge_stop().

131 {
132  rtp_glue_data_destroy(glue);
133  rtp_glue_data_init(glue);
134 }
static void rtp_glue_data_destroy(struct rtp_glue_data *glue)
static void rtp_glue_data_init(struct rtp_glue_data *glue)

◆ rtp_glue_get_current_combined_result()

static enum ast_rtp_glue_result rtp_glue_get_current_combined_result ( struct ast_channel c0,
struct ast_channel c1 
)
static

Definition at line 257 of file bridge_native_rtp.c.

References AST_RTP_GLUE_RESULT_FORBID, rtp_glue_data::result, rtp_glue_data_destroy(), rtp_glue_data_get(), and rtp_glue_data_init().

Referenced by native_rtp_bridge_stop().

259 {
260  struct rtp_glue_data glue_a;
261  struct rtp_glue_data glue_b;
262  struct rtp_glue_data *glue0;
263  struct rtp_glue_data *glue1;
264  enum ast_rtp_glue_result combined_result;
265 
266  rtp_glue_data_init(&glue_a);
267  glue0 = &glue_a;
268  rtp_glue_data_init(&glue_b);
269  glue1 = &glue_b;
270  if (rtp_glue_data_get(c0, glue0, c1, glue1)) {
272  }
273 
274  combined_result = glue0->result;
275  rtp_glue_data_destroy(glue0);
276  rtp_glue_data_destroy(glue1);
277  return combined_result;
278 }
static void rtp_glue_data_destroy(struct rtp_glue_data *glue)
static int rtp_glue_data_get(struct ast_channel *c0, struct rtp_glue_data *glue0, struct ast_channel *c1, struct rtp_glue_data *glue1)
static void rtp_glue_data_init(struct rtp_glue_data *glue)
enum ast_rtp_glue_result result
ast_rtp_glue_result
Definition: rtp_engine.h:158

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1098 of file bridge_native_rtp.c.

References ast_bridge_technology_unregister().

Referenced by load_module().

1099 {
1101  return 0;
1102 }
static struct ast_bridge_technology native_rtp_bridge
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
Unregister a bridge technology from use.
Definition: bridge.c:265

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Native RTP bridging module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 1113 of file bridge_native_rtp.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1113 of file bridge_native_rtp.c.

◆ native_rtp_bridge

struct ast_bridge_technology native_rtp_bridge
static

Definition at line 98 of file bridge_native_rtp.c.