Asterisk - The Open Source Telephony Project  GIT-master-e8cda4b
Data Structures | Macros | Enumerations | Functions
core_unreal.h File Reference

Unreal channel derivative framework. More...

#include "asterisk/astobj2.h"
#include "asterisk/channel.h"
#include "asterisk/bridge.h"
#include "asterisk/abstract_jb.h"

Go to the source code of this file.

Data Structures

struct  ast_unreal_pvt
 The base pvt structure for local channel derivatives. More...
 
struct  ast_unreal_pvt_callbacks
 Callbacks that can be provided by concrete implementations of the unreal channel driver that will be called when events occur in the unreal layer. More...
 

Macros

#define AST_UNREAL_CARETAKER_THREAD   (1 << 0)
 
#define AST_UNREAL_IS_OUTBOUND(a, b)   ((a) == (b)->chan ? 1 : 0)
 
#define AST_UNREAL_MOH_INTERCEPT   (1 << 2)
 
#define AST_UNREAL_NO_OPTIMIZATION   (1 << 1)
 
#define AST_UNREAL_OPTIMIZE_BEGUN   (1 << 3)
 

Enumerations

enum  ast_unreal_channel_indicator { AST_UNREAL_OWNER, AST_UNREAL_CHAN }
 

Functions

struct ast_unreal_pvtast_unreal_alloc (size_t size, ao2_destructor_fn destructor, struct ast_format_cap *cap)
 Allocate the base unreal struct for a derivative. More...
 
struct ast_unreal_pvtast_unreal_alloc_stream_topology (size_t size, ao2_destructor_fn destructor, struct ast_stream_topology *topology)
 Allocate the base unreal struct for a derivative. More...
 
int ast_unreal_answer (struct ast_channel *ast)
 
void ast_unreal_call_setup (struct ast_channel *semi1, struct ast_channel *semi2)
 Setup unreal owner and chan channels before initiating call. More...
 
int ast_unreal_channel_push_to_bridge (struct ast_channel *ast, struct ast_bridge *bridge, unsigned int flags)
 Push the semi2 unreal channel into a bridge from either member of the unreal pair. More...
 
void ast_unreal_destructor (void *vdoomed)
 struct ast_unreal_pvt destructor. More...
 
int ast_unreal_digit_begin (struct ast_channel *ast, char digit)
 
int ast_unreal_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
 
int ast_unreal_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 
int ast_unreal_hangup (struct ast_unreal_pvt *p, struct ast_channel *ast)
 Hangup one end (maybe both ends) of an unreal channel derivative. More...
 
int ast_unreal_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 
void ast_unreal_lock_all (struct ast_unreal_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
 Send an unreal pvt in with no locks held and get all locks. More...
 
struct ast_channelast_unreal_new_channels (struct ast_unreal_pvt *p, const struct ast_channel_tech *tech, int semi1_state, int semi2_state, const char *exten, const char *context, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid)
 Create the semi1 and semi2 unreal channels. More...
 
int ast_unreal_queryoption (struct ast_channel *ast, int option, void *data, int *datalen)
 
struct ast_frameast_unreal_read (struct ast_channel *ast)
 
int ast_unreal_sendhtml (struct ast_channel *ast, int subclass, const char *data, int datalen)
 
int ast_unreal_sendtext (struct ast_channel *ast, const char *text)
 
int ast_unreal_setoption (struct ast_channel *chan, int option, void *data, int datalen)
 
int ast_unreal_write (struct ast_channel *ast, struct ast_frame *f)
 
int ast_unreal_write_stream (struct ast_channel *ast, int stream_num, struct ast_frame *f)
 

Detailed Description

Unreal channel derivative framework.

Author
Richard Mudgett rmudg.nosp@m.ett@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

See Also:

Definition in file core_unreal.h.

Macro Definition Documentation

◆ AST_UNREAL_CARETAKER_THREAD

#define AST_UNREAL_CARETAKER_THREAD   (1 << 0)

The ;2 side launched a PBX, was pushed into a bridge, or was masqueraded into an application.

Definition at line 107 of file core_unreal.h.

Referenced by ast_local_setup_bridge(), ast_local_setup_masquerade(), ast_unreal_channel_push_to_bridge(), ast_unreal_hangup(), conf_announce_channel_push(), local_call(), and local_devicestate().

◆ AST_UNREAL_IS_OUTBOUND

#define AST_UNREAL_IS_OUTBOUND (   a,
  b 
)    ((a) == (b)->chan ? 1 : 0)

◆ AST_UNREAL_MOH_INTERCEPT

#define AST_UNREAL_MOH_INTERCEPT   (1 << 2)

Intercept and act on hold/unhold control frames

Definition at line 109 of file core_unreal.h.

Referenced by ast_unreal_indicate(), and local_alloc().

◆ AST_UNREAL_NO_OPTIMIZATION

#define AST_UNREAL_NO_OPTIMIZATION   (1 << 1)

◆ AST_UNREAL_OPTIMIZE_BEGUN

#define AST_UNREAL_OPTIMIZE_BEGUN   (1 << 3)

Indicates that an optimization attempt has been started

Definition at line 110 of file core_unreal.h.

Referenced by try_merge_optimize_out(), and try_swap_optimize_out().

Enumeration Type Documentation

◆ ast_unreal_channel_indicator

Enumerator
AST_UNREAL_OWNER 
AST_UNREAL_CHAN 

Definition at line 49 of file core_unreal.h.

Function Documentation

◆ ast_unreal_alloc()

struct ast_unreal_pvt* ast_unreal_alloc ( size_t  size,
ao2_destructor_fn  destructor,
struct ast_format_cap cap 
)

Allocate the base unreal struct for a derivative.

Since
12.0.0
Parameters
sizeSize of the unreal struct to allocate.
destructorDestructor callback.
capFormat capabilities to give the unreal private struct.
Return values
pvton success.
NULLon error.

Definition at line 1109 of file core_unreal.c.

References ast_stream_topology_create_from_format_cap(), ast_stream_topology_free(), ast_unreal_alloc_stream_topology(), and NULL.

Referenced by announce_request(), and media_request_helper().

1110 {
1111  struct ast_stream_topology *topology;
1112  struct ast_unreal_pvt *unreal;
1113 
1115  if (!topology) {
1116  return NULL;
1117  }
1118 
1119  unreal = ast_unreal_alloc_stream_topology(size, destructor, topology);
1120 
1121  ast_stream_topology_free(topology);
1122 
1123  return unreal;
1124 }
struct ast_unreal_pvt * ast_unreal_alloc_stream_topology(size_t size, ao2_destructor_fn destructor, struct ast_stream_topology *topology)
Allocate the base unreal struct for a derivative.
Definition: core_unreal.c:1126
struct ast_stream_topology * ast_stream_topology_create_from_format_cap(struct ast_format_cap *cap)
A helper function that, given a format capabilities structure, creates a topology and separates the m...
Definition: stream.c:848
#define NULL
Definition: resample.c:96
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743

◆ ast_unreal_alloc_stream_topology()

struct ast_unreal_pvt* ast_unreal_alloc_stream_topology ( size_t  size,
ao2_destructor_fn  destructor,
struct ast_stream_topology topology 
)

Allocate the base unreal struct for a derivative.

Since
16.12.0
17.6.0
Parameters
sizeSize of the unreal struct to allocate.
destructorDestructor callback.
capFormat capabilities to give the unreal private struct.
Return values
pvton success.
NULLon error.

Definition at line 1126 of file core_unreal.c.

References ao2_alloc, ao2_ref, ast_stream_topology_clone(), ast_stream_topology_get_formats(), ast_jb_conf::flags, ast_unreal_pvt::jb_conf, NULL, ast_unreal_pvt::reqcap, and ast_unreal_pvt::reqtopology.

Referenced by ast_unreal_alloc(), and local_alloc().

1127 {
1128  struct ast_unreal_pvt *unreal;
1129 
1130  static const struct ast_jb_conf jb_conf = {
1131  .flags = 0,
1132  .max_size = -1,
1133  .resync_threshold = -1,
1134  .impl = "",
1135  .target_extra = -1,
1136  };
1137 
1138  unreal = ao2_alloc(size, destructor);
1139  if (!unreal) {
1140  return NULL;
1141  }
1142 
1143  unreal->reqtopology = ast_stream_topology_clone(topology);
1144  if (!unreal->reqtopology) {
1145  ao2_ref(unreal, -1);
1146  return NULL;
1147  }
1148 
1149  unreal->reqcap = ast_stream_topology_get_formats(topology);
1150  if (!unreal->reqcap) {
1151  ao2_ref(unreal, -1);
1152  return NULL;
1153  }
1154 
1155  memcpy(&unreal->jb_conf, &jb_conf, sizeof(unreal->jb_conf));
1156 
1157  return unreal;
1158 }
struct ast_format_cap * ast_stream_topology_get_formats(struct ast_stream_topology *topology)
Create a format capabilities structure representing the topology.
Definition: stream.c:930
struct ast_jb_conf jb_conf
Definition: core_unreal.h:96
#define NULL
Definition: resample.c:96
long resync_threshold
Definition: jitterbuf.h:68
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_format_cap * reqcap
Definition: core_unreal.h:95
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
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
struct ast_stream_topology * reqtopology
Definition: core_unreal.h:100
General jitterbuffer configuration.
Definition: abstract_jb.h:69

◆ ast_unreal_answer()

int ast_unreal_answer ( struct ast_channel ast)

Unreal channel framework struct ast_channel_tech.answer callback

Definition at line 254 of file core_unreal.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_name(), ast_channel_tech_pvt(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log, AST_UNREAL_IS_OUTBOUND, LOG_WARNING, and unreal_queue_frame().

255 {
256  struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
257  int isoutbound;
258  int res = -1;
259 
260  if (!p) {
261  return -1;
262  }
263 
264  ao2_ref(p, 1);
265  ao2_lock(p);
266  isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
267  if (isoutbound) {
268  /* Pass along answer since somebody answered us */
270 
271  res = unreal_queue_frame(p, isoutbound, &answer, ast, 1);
272  } else {
273  ast_log(LOG_WARNING, "Huh? %s is being asked to answer?\n",
274  ast_channel_name(ast));
275  }
276  ao2_unlock(p);
277  ao2_ref(p, -1);
278  return res;
279 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int unreal_queue_frame(struct ast_unreal_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame onto either the p->owner or p->chan
Definition: core_unreal.c:213
#define LOG_WARNING
Definition: logger.h:274
#define AST_UNREAL_IS_OUTBOUND(a, b)
Definition: core_unreal.h:105
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static int answer(void *data)
Definition: chan_pjsip.c:682
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
const char * ast_channel_name(const struct ast_channel *chan)
Data structure associated with a single frame of data.

◆ ast_unreal_call_setup()

void ast_unreal_call_setup ( struct ast_channel semi1,
struct ast_channel semi2 
)

Setup unreal owner and chan channels before initiating call.

Since
12.0.0
Parameters
semi1Owner channel of unreal channel pair.
semi2Outgoing channel of unreal channel pair.
Note
On entry, the semi1 and semi2 channels are already locked.
Returns
Nothing

Definition at line 870 of file core_unreal.c.

References AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_accountcode(), ast_channel_caller(), ast_channel_cc_params_init(), ast_channel_connected(), ast_channel_datastore_inherit(), ast_channel_dialed(), ast_channel_get_cc_config_params(), ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_language(), ast_channel_musicclass(), ast_channel_parkinglot(), ast_channel_peeraccount(), ast_channel_publish_varset(), ast_channel_redirecting(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_varshead(), ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_party_dialed_copy(), ast_party_redirecting_copy(), ast_var_assign, ast_var_full_name(), ast_var_value(), ast_var_t::entries, ast_var_t::name, and ast_var_t::value.

Referenced by local_call().

871 {
872  struct ast_var_t *varptr;
873  struct ast_var_t *clone_var;
874 
876 
877  /*
878  * Note that cid_num and cid_name aren't passed in the
879  * ast_channel_alloc calls in ast_unreal_new_channels(). It's
880  * done here instead.
881  */
883 
885 
886  /* Crossover the CallerID and conected-line to cross the unreal bridge. */
889 
890  ast_channel_language_set(semi2, ast_channel_language(semi1));
891  ast_channel_musicclass_set(semi2, ast_channel_musicclass(semi1));
892  ast_channel_parkinglot_set(semi2, ast_channel_parkinglot(semi1));
893 
894  /* Crossover the accountcode and peeraccount to cross the unreal bridge. */
895  ast_channel_accountcode_set(semi2, ast_channel_peeraccount(semi1));
896  ast_channel_peeraccount_set(semi2, ast_channel_accountcode(semi1));
897 
899 
900  /*
901  * Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's
902  * set on the queue/dial call request in the dialplan.
903  */
906  }
907 
908  /*
909  * Copy the channel variables from the semi1 channel to the
910  * outgoing channel.
911  *
912  * Note that due to certain assumptions, they MUST be in the
913  * same order.
914  */
916  clone_var = ast_var_assign(varptr->name, varptr->value);
917  if (clone_var) {
920  ast_var_value(clone_var));
921  }
922  }
923  ast_channel_datastore_inherit(semi1, semi2);
924 
926 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
struct varshead * ast_channel_varshead(struct ast_channel *chan)
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Definition: channel.c:10586
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2369
const char * ast_channel_accountcode(const struct ast_channel *chan)
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
struct ast_var_t::@243 entries
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
int ast_channel_cc_params_init(struct ast_channel *chan, const struct ast_cc_config_params *base_params)
Set up datastore with CCSS parameters for a channel.
Definition: channel.c:10563
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
char name[0]
Definition: chanvars.h:31
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
void ast_channel_publish_varset(struct ast_channel *chan, const char *variable, const char *value)
Publish a ast_channel_varset for a channel.
char * value
Definition: chanvars.h:30
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
const char * ast_channel_peeraccount(const struct ast_channel *chan)
const char * ast_var_full_name(const struct ast_var_t *var)
Definition: chanvars.c:75
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_var_assign(name, value)
Definition: chanvars.h:40
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
int ast_channel_hangupcause(const struct ast_channel *chan)
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8300
const char * ast_channel_language(const struct ast_channel *chan)
void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
Copy the connected line information to the caller information.
Definition: channel.c:8307
const char * ast_channel_parkinglot(const struct ast_channel *chan)
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2131
const char * ast_channel_musicclass(const struct ast_channel *chan)
void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
Copy the source dialed party information to the destination dialed party.
Definition: channel.c:1932

◆ ast_unreal_channel_push_to_bridge()

int ast_unreal_channel_push_to_bridge ( struct ast_channel ast,
struct ast_bridge bridge,
unsigned int  flags 
)

Push the semi2 unreal channel into a bridge from either member of the unreal pair.

Since
12.0.0
Parameters
astA member of the unreal channel being pushed
bridgeWhich bridge we want to push the channel to
flagsFeature flags to be set on the bridge channel.
Return values
0if the channel is successfully imparted onto the bridge
-1on failure
Note
This is equivalent to ast_call() on unreal based channel drivers that are designed to use it instead.

Definition at line 928 of file core_unreal.c.

References ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, ast_bridge_features_new(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_bridge_lock, ast_bridge_unlock, ast_channel_callid(), ast_channel_callid_set(), ast_channel_lock, ast_channel_ref, ast_channel_tech_pvt(), ast_channel_unlock, ast_channel_unref, ast_set_flag, AST_UNREAL_CARETAKER_THREAD, ast_bridge::callid, ast_bridge_features::feature_flags, lock, NULL, RAII_VAR, SCOPED_AO2LOCK, and SCOPED_CHANNELLOCK.

Referenced by ari_bridges_play_new(), ast_ari_bridges_record(), and bridge_moh_create().

929 {
930  struct ast_bridge_features *features;
931  struct ast_channel *chan;
932  struct ast_channel *owner;
933  ast_callid bridge_callid;
934  RAII_VAR(struct ast_unreal_pvt *, p, NULL, ao2_cleanup);
935 
936  ast_bridge_lock(bridge);
937  bridge_callid = bridge->callid;
938  ast_bridge_unlock(bridge);
939 
940  {
941  SCOPED_CHANNELLOCK(lock, ast);
942  p = ast_channel_tech_pvt(ast);
943  if (!p) {
944  return -1;
945  }
946  ao2_ref(p, +1);
947  }
948 
949  {
950  SCOPED_AO2LOCK(lock, p);
951  chan = p->chan;
952  if (!chan) {
953  return -1;
954  }
955 
956  owner = p->owner;
957  if (!owner) {
958  return -1;
959  }
960 
961  ast_channel_ref(chan);
962  ast_channel_ref(owner);
963  }
964 
965  if (bridge_callid) {
966  ast_callid chan_callid;
967  ast_callid owner_callid;
968 
969  /* chan side call ID setting */
970  ast_channel_lock(chan);
971 
972  chan_callid = ast_channel_callid(chan);
973  if (!chan_callid) {
974  ast_channel_callid_set(chan, bridge_callid);
975  }
976  ast_channel_unlock(chan);
977 
978  /* owner side call ID setting */
979  ast_channel_lock(owner);
980 
981  owner_callid = ast_channel_callid(owner);
982  if (!owner_callid) {
983  ast_channel_callid_set(owner, bridge_callid);
984  }
985 
986  ast_channel_unlock(owner);
987  }
988 
989  /* We are done with the owner now that its call ID matches the bridge */
990  ast_channel_unref(owner);
991  owner = NULL;
992 
993  features = ast_bridge_features_new();
994  if (!features) {
995  ast_channel_unref(chan);
996  return -1;
997  }
998 
999  ast_set_flag(&features->feature_flags, flags);
1000 
1001  /* Impart the semi2 channel into the bridge */
1002  if (ast_bridge_impart(bridge, chan, NULL, features,
1004  ast_channel_unref(chan);
1005  return -1;
1006  }
1007 
1008  /* The bridge thread now controls the chan ref from the ast_unreal_pvt */
1009  ao2_lock(p);
1011  ao2_unlock(p);
1012 
1013  ast_channel_unref(chan);
1014 
1015  return 0;
1016 }
#define ast_channel_lock(chan)
Definition: channel.h:2913
Main Channel structure associated with a channel.
Structure that contains features information.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
#define ast_set_flag(p, flag)
Definition: utils.h:70
ast_callid callid
Definition: bridge.h:369
#define AST_UNREAL_CARETAKER_THREAD
Definition: core_unreal.h:107
unsigned int ast_callid
Definition: logger.h:87
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct ast_flags feature_flags
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1924
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
#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
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
#define ast_channel_unlock(chan)
Definition: channel.h:2914
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3750
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2938
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
ast_callid ast_channel_callid(const struct ast_channel *chan)

◆ ast_unreal_destructor()

void ast_unreal_destructor ( void *  vdoomed)

struct ast_unreal_pvt destructor.

Since
12.0.0
Parameters
vdoomedObject to destroy.
Returns
Nothing

Definition at line 1097 of file core_unreal.c.

References ao2_cleanup, ast_stream_topology_free(), ast_unreal_pvt::chan_old_topology, NULL, ast_unreal_pvt::owner_old_topology, ast_unreal_pvt::reqcap, and ast_unreal_pvt::reqtopology.

Referenced by announce_pvt_destructor(), local_pvt_destructor(), and media_request_helper().

1098 {
1099  struct ast_unreal_pvt *doomed = vdoomed;
1100 
1101  ao2_cleanup(doomed->reqcap);
1102  doomed->reqcap = NULL;
1104  doomed->reqtopology = NULL;
1106  ao2_cleanup(doomed->chan_old_topology);
1107 }
#define NULL
Definition: resample.c:96
struct ast_stream_topology * chan_old_topology
Definition: core_unreal.h:102
struct ast_stream_topology * owner_old_topology
Definition: core_unreal.h:101
struct ast_format_cap * reqcap
Definition: core_unreal.h:95
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
struct ast_stream_topology * reqtopology
Definition: core_unreal.h:100

◆ ast_unreal_digit_begin()

int ast_unreal_digit_begin ( struct ast_channel ast,
char  digit 
)

Unreal channel framework struct ast_channel_tech.send_digit_begin callback

Definition at line 779 of file core_unreal.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_tech_pvt(), AST_FRAME_DTMF_BEGIN, AST_UNREAL_IS_OUTBOUND, digit, ast_frame_subclass::integer, ast_frame::subclass, and unreal_queue_frame().

780 {
781  struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
782  int res = -1;
783  struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
784  int isoutbound;
785 
786  if (!p) {
787  return -1;
788  }
789 
790  ao2_ref(p, 1); /* ref for unreal_queue_frame */
791  ao2_lock(p);
792  isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
793  f.subclass.integer = digit;
794  res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
795  ao2_unlock(p);
796  ao2_ref(p, -1);
797 
798  return res;
799 }
char digit
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int unreal_queue_frame(struct ast_unreal_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame onto either the p->owner or p->chan
Definition: core_unreal.c:213
#define AST_UNREAL_IS_OUTBOUND(a, b)
Definition: core_unreal.h:105
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_frame_subclass subclass
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
Data structure associated with a single frame of data.

◆ ast_unreal_digit_end()

int ast_unreal_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
)

Unreal channel framework struct ast_channel_tech.send_digit_end callback

Definition at line 801 of file core_unreal.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_tech_pvt(), AST_FRAME_DTMF_END, AST_UNREAL_IS_OUTBOUND, digit, ast_frame_subclass::integer, ast_frame::len, ast_frame::subclass, and unreal_queue_frame().

802 {
803  struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
804  int res = -1;
805  struct ast_frame f = { AST_FRAME_DTMF_END, };
806  int isoutbound;
807 
808  if (!p) {
809  return -1;
810  }
811 
812  ao2_ref(p, 1); /* ref for unreal_queue_frame */
813  ao2_lock(p);
814  isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
815  f.subclass.integer = digit;
816  f.len = duration;
817  res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
818  ao2_unlock(p);
819  ao2_ref(p, -1);
820 
821  return res;
822 }
char digit
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int unreal_queue_frame(struct ast_unreal_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame onto either the p->owner or p->chan
Definition: core_unreal.c:213
#define AST_UNREAL_IS_OUTBOUND(a, b)
Definition: core_unreal.h:105
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_frame_subclass subclass
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
Data structure associated with a single frame of data.

◆ ast_unreal_fixup()

int ast_unreal_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
)

Unreal channel framework struct ast_channel_tech.fixup callback

Definition at line 369 of file core_unreal.c.

References ao2_lock, ao2_unlock, ast_channel_internal_bridge(), ast_channel_name(), ast_channel_tech_pvt(), ast_check_hangup(), ast_log, ast_queue_hangup(), ast_unreal_pvt::chan, LOG_WARNING, and ast_unreal_pvt::owner.

370 {
371  struct ast_unreal_pvt *p = ast_channel_tech_pvt(newchan);
372  struct ast_bridge *bridge_owner;
373  struct ast_bridge *bridge_chan;
374 
375  if (!p) {
376  return -1;
377  }
378 
379  ao2_lock(p);
380 
381  if ((p->owner != oldchan) && (p->chan != oldchan)) {
382  ast_log(LOG_WARNING, "Old channel %p wasn't %p or %p\n", oldchan, p->owner, p->chan);
383  ao2_unlock(p);
384  return -1;
385  }
386  if (p->owner == oldchan) {
387  p->owner = newchan;
388  } else {
389  p->chan = newchan;
390  }
391 
392  if (ast_check_hangup(newchan) || !p->owner || !p->chan) {
393  ao2_unlock(p);
394  return 0;
395  }
396 
397  /* Do not let a masquerade cause an unreal channel to be bridged to itself! */
398  bridge_owner = ast_channel_internal_bridge(p->owner);
399  bridge_chan = ast_channel_internal_bridge(p->chan);
400  if (bridge_owner && bridge_owner == bridge_chan) {
401  ast_log(LOG_WARNING, "You can not bridge an unreal channel (%s) to itself!\n",
402  ast_channel_name(newchan));
403  ao2_unlock(p);
404  ast_queue_hangup(newchan);
405  return -1;
406  }
407 
408  ao2_unlock(p);
409  return 0;
410 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1146
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: core_unreal.h:93
struct ast_bridge * ast_channel_internal_bridge(const struct ast_channel *chan)
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_log
Definition: astobj2.c:42
#define ao2_lock(a)
Definition: astobj2.h:718
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:441
struct ast_channel * chan
Definition: core_unreal.h:94
Structure that contains information about a bridge.
Definition: bridge.h:357
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
const char * ast_channel_name(const struct ast_channel *chan)

◆ ast_unreal_hangup()

int ast_unreal_hangup ( struct ast_unreal_pvt p,
struct ast_channel ast 
)

Hangup one end (maybe both ends) of an unreal channel derivative.

Since
12.0.0
Parameters
pPrivate channel struct (reffed)
astChannel being hung up. (locked)
Note
Common hangup code for unreal channels. Derived channels will need to deal with any additional resources.
Return values
0on success.
-1on error.

Definition at line 1018 of file core_unreal.c.

References ao2_ref, ao2_unlock, AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_hangupcause(), ast_channel_hangupcause_set(), ast_channel_lock, ast_channel_name(), ast_channel_tech_pvt_set(), ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_debug, ast_hangup(), ast_queue_hangup_with_cause(), ast_test_flag, AST_UNREAL_CARETAKER_THREAD, ast_unreal_lock_all(), ast_unreal_pvt::chan, hangup_chan(), NULL, ast_unreal_pvt::owner, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and status.

Referenced by announce_hangup(), local_hangup(), and media_hangup().

1019 {
1020  int hangup_chan = 0;
1021  int res = 0;
1022  int cause;
1023  struct ast_channel *owner = NULL;
1024  struct ast_channel *chan = NULL;
1025 
1026  /* the pvt isn't going anywhere, it has a ref */
1027  ast_channel_unlock(ast);
1028 
1029  /* lock everything */
1030  ast_unreal_lock_all(p, &chan, &owner);
1031 
1032  if (ast != chan && ast != owner) {
1033  res = -1;
1034  goto unreal_hangup_cleanup;
1035  }
1036 
1037  cause = ast_channel_hangupcause(ast);
1038 
1039  if (ast == p->chan) {
1040  /* Outgoing side is hanging up. */
1042  p->chan = NULL;
1043  if (p->owner) {
1044  const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
1045 
1046  if (status) {
1048  pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
1049  }
1051  }
1052  } else {
1053  /* Owner side is hanging up. */
1054  p->owner = NULL;
1055  if (p->chan) {
1056  if (cause == AST_CAUSE_ANSWERED_ELSEWHERE) {
1058  ast_debug(2, "%s has AST_CAUSE_ANSWERED_ELSEWHERE set.\n",
1059  ast_channel_name(p->chan));
1060  }
1062  /*
1063  * Need to actually hangup p->chan since nothing else is taking
1064  * care of it.
1065  */
1066  hangup_chan = 1;
1067  } else {
1068  ast_queue_hangup_with_cause(p->chan, cause);
1069  }
1070  }
1071  }
1072 
1073  /* this is one of our locked channels, doesn't matter which */
1075  ao2_ref(p, -1);
1076 
1077 unreal_hangup_cleanup:
1078  ao2_unlock(p);
1079  if (owner) {
1080  ast_channel_unlock(owner);
1081  ast_channel_unref(owner);
1082  }
1083  if (chan) {
1084  ast_channel_unlock(chan);
1085  if (hangup_chan) {
1086  ast_hangup(chan);
1087  }
1088  ast_channel_unref(chan);
1089  }
1090 
1091  /* leave with the channel locked that came in */
1092  ast_channel_lock(ast);
1093 
1094  return res;
1095 }
#define ast_channel_lock(chan)
Definition: channel.h:2913
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
struct ast_channel * owner
Definition: core_unreal.h:93
#define AST_UNREAL_CARETAKER_THREAD
Definition: core_unreal.h:107
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1162
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * chan
Definition: core_unreal.h:94
#define ast_channel_unlock(chan)
Definition: channel.h:2914
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2544
#define ast_clear_flag(p, flag)
Definition: utils.h:77
int cause
Definition: bridge.h:394
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8447
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
int ast_channel_hangupcause(const struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)
void ast_unreal_lock_all(struct ast_unreal_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
Send an unreal pvt in with no locks held and get all locks.
Definition: core_unreal.c:47
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
jack_status_t status
Definition: app_jack.c:146

◆ ast_unreal_indicate()

int ast_unreal_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
)

Unreal channel framework struct ast_channel_tech.indicate callback

Definition at line 622 of file core_unreal.c.

References ao2_bump, ao2_ref, ao2_unlock, ast_channel_get_stream_topology(), ast_channel_is_multistream(), ast_channel_lock, ast_channel_set_stream_topology(), ast_channel_tech_pvt(), ast_channel_unlock, ast_channel_unref, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, ast_free, ast_log, AST_MEDIA_TYPE_IMAGE, ast_moh_start(), ast_moh_stop(), AST_STATE_RING, ast_stream_alloc(), ast_stream_topology_alloc(), ast_stream_topology_append_stream(), AST_T38_NEGOTIATED, AST_T38_TERMINATED, ast_test_flag, ast_unreal_lock_all(), AST_UNREAL_MOH_INTERCEPT, ast_unreal_pvt::chan_old_topology, LOG_ERROR, NULL, ast_unreal_pvt::owner_old_topology, ast_control_t38_parameters::request_response, unreal_colp_redirect_indicate(), unreal_colp_stream_topology_request_change(), and unreal_queue_indicate().

623 {
624  struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
625  int res = 0;
626  struct ast_channel *chan = NULL;
627  struct ast_channel *owner = NULL;
628  const struct ast_control_t38_parameters *parameters;
629 
630  if (!p) {
631  return -1;
632  }
633 
634  ao2_ref(p, 1); /* ref for unreal_queue_frame */
635 
636  switch (condition) {
638  /*
639  * Always block this because this is the channel being
640  * masqueraded; not anything down the chain.
641  */
642  break;
645  res = unreal_colp_redirect_indicate(p, ast, condition);
646  break;
647  case AST_CONTROL_HOLD:
649  ast_moh_start(ast, data, NULL);
650  break;
651  }
652  res = unreal_queue_indicate(p, ast, condition, data, datalen);
653  break;
654  case AST_CONTROL_UNHOLD:
656  ast_moh_stop(ast);
657  break;
658  }
659  res = unreal_queue_indicate(p, ast, condition, data, datalen);
660  break;
661  case AST_CONTROL_RINGING:
662  /* Don't queue ringing frames if the channel is not in a "ring" state. Otherwise,
663  * the real channel on the other end will likely start a playtones generator. It is
664  * possible that this playtones generator will never be stopped under certain
665  * circumstances.
666  */
667  if (ast_channel_state(ast) == AST_STATE_RING) {
668  res = unreal_queue_indicate(p, ast, condition, data, datalen);
669  } else {
670  res = -1;
671  }
672  break;
674  /* Return -1 so that asterisk core will correctly set up hangupcauses. */
675  unreal_queue_indicate(p, ast, condition, data, datalen);
676  res = -1;
677  break;
679  if (ast_channel_is_multistream(ast)) {
680  res = unreal_colp_stream_topology_request_change(p, ast, data);
681  }
682  break;
684  parameters = data;
685  if (parameters->request_response == AST_T38_NEGOTIATED) {
686  struct ast_stream *stream;
687  struct ast_stream_topology *new_topology;
688 
689  stream = ast_stream_alloc("local_fax", AST_MEDIA_TYPE_IMAGE);
690  if (!stream) {
691  ast_log(LOG_ERROR, "Failed to allocate memory for stream.\n");
692  res = -1;
693  break;
694  }
695  new_topology = ast_stream_topology_alloc();
696  if (!new_topology) {
697  ast_log(LOG_ERROR, "Failed to allocate memory for stream topology.\n");
698  ast_free(stream);
699  res = -1;
700  break;
701  }
702  ast_stream_topology_append_stream(new_topology, stream);
703 
704  /*
705  * Lock both parts of the local channel so we can store their topologies and replace them with
706  * one that has a stream with type IMAGE. We can just hold the reference on the unreal_pvt
707  * structure and bump it, then steal the ref later when we are restoring the topology.
708  *
709  * We use ast_unreal_lock_all here because we don't know if the ;1 or ;2 side will get the
710  * signaling and we need to be sure that the locking order is the same to prevent possible
711  * deadlocks.
712  */
713  ast_channel_unlock(ast);
714  ast_unreal_lock_all(p, &chan, &owner);
715 
716  if (owner) {
718  ast_channel_set_stream_topology(owner, new_topology);
719  }
720 
721  if (chan) {
723 
724  /* Bump the ref for new_topology, since it will be used by both sides of the local channel */
725  ao2_ref(new_topology, +1);
726  ast_channel_set_stream_topology(chan, new_topology);
727  }
728 
729  ao2_unlock(p);
730  ast_channel_lock(ast);
731  } else if (parameters->request_response == AST_T38_TERMINATED) {
732  /*
733  * Lock both parts of the local channel so we can restore their topologies to the original.
734  * The topology should be on the unreal_pvt structure, with a ref that we can steal. Same
735  * conditions as above.
736  */
737  ast_channel_unlock(ast);
738  ast_unreal_lock_all(p, &chan, &owner);
739 
740  if (owner) {
743  }
744 
745  if (chan) {
747  p->chan_old_topology = NULL;
748  }
749 
750  ao2_unlock(p);
751  ast_channel_lock(ast);
752  }
753 
754  /*
755  * We unlock ast_unreal_pvt in the above conditionals since there's no way to
756  * tell if it's been unlocked already or not when we get to this point, but
757  * if either of these are not NULL, we know that they are locked and need to
758  * unlock them.
759  */
760  if (owner) {
761  ast_channel_unlock(owner);
762  ast_channel_unref(owner);
763  }
764 
765  if (chan) {
766  ast_channel_unlock(chan);
767  ast_channel_unref(chan);
768  }
769  /* Fall through for all T38 conditions */
770  default:
771  res = unreal_queue_indicate(p, ast, condition, data, datalen);
772  break;
773  }
774 
775  ao2_ref(p, -1);
776  return res;
777 }
#define ast_channel_lock(chan)
Definition: channel.h:2913
Main Channel structure associated with a channel.
static int unreal_colp_stream_topology_request_change(struct ast_unreal_pvt *p, struct ast_channel *ast, const struct ast_stream_topology *topology)
Definition: core_unreal.c:555
int ast_channel_is_multistream(struct ast_channel *chan)
Determine if a channel is multi-stream capable.
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
#define ast_test_flag(p, flag)
Definition: utils.h:63
enum ast_control_t38 request_response
ast_channel_state
ast_channel states
Definition: channelstate.h:35
static int unreal_colp_redirect_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition)
Definition: core_unreal.c:477
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
int ast_stream_topology_append_stream(struct ast_stream_topology *topology, struct ast_stream *stream)
Append a stream to the topology.
Definition: stream.c:748
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7793
#define AST_UNREAL_MOH_INTERCEPT
Definition: core_unreal.h:109
#define ao2_bump(obj)
Definition: astobj2.h:491
struct ast_stream_topology * chan_old_topology
Definition: core_unreal.h:102
#define ast_log
Definition: astobj2.c:42
static int unreal_queue_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition, const void *data, size_t datalen)
Definition: core_unreal.c:427
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_stream_topology * owner_old_topology
Definition: core_unreal.h:101
#define LOG_ERROR
Definition: logger.h:285
struct ast_stream_topology * ast_channel_set_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Set the topology of streams on a channel.
struct ast_stream_topology * ast_stream_topology_alloc(void)
Create a stream topology.
Definition: stream.c:650
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7783
#define ast_channel_unlock(chan)
Definition: channel.h:2914
#define ast_free(a)
Definition: astmm.h:182
struct ast_stream * ast_stream_alloc(const char *name, enum ast_media_type type)
Create a new media stream representation.
Definition: stream.c:233
void ast_unreal_lock_all(struct ast_unreal_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
Send an unreal pvt in with no locks held and get all locks.
Definition: core_unreal.c:47

◆ ast_unreal_lock_all()

void ast_unreal_lock_all ( struct ast_unreal_pvt p,
struct ast_channel **  outchan,
struct ast_channel **  outowner 
)

Send an unreal pvt in with no locks held and get all locks.

Note
NO locks should be held prior to calling this function
The pvt must have a ref held before calling this function
if outchan or outowner is set != NULL after calling this function those channels are locked and reffed.
Batman.

Definition at line 47 of file core_unreal.c.

References ao2_lock, ao2_unlock, ast_channel_lock, ast_channel_lock_both, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_unreal_pvt::chan, NULL, and ast_unreal_pvt::owner.

Referenced by ast_local_lock_all(), ast_unreal_hangup(), ast_unreal_indicate(), local_call(), publish_local_bridge_message(), stasis_app_channel_unreal_set_internal(), unreal_colp_redirect_indicate(), and unreal_colp_stream_topology_request_change().

48 {
49  struct ast_channel *chan = NULL;
50  struct ast_channel *owner = NULL;
51 
52  ao2_lock(p);
53  for (;;) {
54  if (p->chan) {
55  chan = p->chan;
56  ast_channel_ref(chan);
57  }
58  if (p->owner) {
59  owner = p->owner;
60  ast_channel_ref(owner);
61  }
62  ao2_unlock(p);
63 
64  /* if we don't have both channels, then this is very easy */
65  if (!owner || !chan) {
66  if (owner) {
67  ast_channel_lock(owner);
68  } else if(chan) {
69  ast_channel_lock(chan);
70  }
71  } else {
72  /* lock both channels first, then get the pvt lock */
73  ast_channel_lock_both(chan, owner);
74  }
75  ao2_lock(p);
76 
77  /* Now that we have all the locks, validate that nothing changed */
78  if (p->owner != owner || p->chan != chan) {
79  if (owner) {
80  ast_channel_unlock(owner);
81  owner = ast_channel_unref(owner);
82  }
83  if (chan) {
84  ast_channel_unlock(chan);
85  chan = ast_channel_unref(chan);
86  }
87  continue;
88  }
89 
90  break;
91  }
92  *outowner = p->owner;
93  *outchan = p->chan;
94 }
#define ast_channel_lock(chan)
Definition: channel.h:2913
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
struct ast_channel * owner
Definition: core_unreal.h:93
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ao2_lock(a)
Definition: astobj2.h:718
struct ast_channel * chan
Definition: core_unreal.h:94
#define ast_channel_unlock(chan)
Definition: channel.h:2914
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2920
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2938

◆ ast_unreal_new_channels()

struct ast_channel* ast_unreal_new_channels ( struct ast_unreal_pvt p,
const struct ast_channel_tech tech,
int  semi1_state,
int  semi2_state,
const char *  exten,
const char *  context,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
ast_callid  callid 
)

Create the semi1 and semi2 unreal channels.

Since
12.0.0
Parameters
pUnreal channel private struct.
techChannel technology to use.
semi1_stateState to start the semi1(owner) channel in.
semi2_stateState to start the semi2(outgoing chan) channel in.
extenExten to start the chennels in. (NULL if s)
contextContext to start the channels in. (NULL if default)
requestorChannel requesting creation. (NULL if none)
callidThread callid to use.
Return values
semi1_channelon success.
NULLon error.

Definition at line 1160 of file core_unreal.c.

References ao2_cleanup, ao2_ref, ast_alloca, ast_atomic_fetchadd_int(), ast_channel_alloc, ast_channel_callid_set(), ast_channel_cc_params_init(), ast_channel_flags(), ast_channel_get_cc_config_params(), ast_channel_is_multistream(), ast_channel_nativeformats_set(), ast_channel_release(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_stream_topology(), ast_channel_set_writeformat(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unlock, AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_format_cap_get_format(), ast_jb_configure(), ast_log, ast_set_flag, ast_stream_topology_clone(), ast_stream_topology_free(), ast_strlen_zero, ast_unreal_pvt::chan, ast_unreal_pvt::jb_conf, LOG_WARNING, ast_unreal_pvt::name, name_sequence, NULL, ast_unreal_pvt::owner, RAII_VAR, ast_unreal_pvt::reqcap, ast_unreal_pvt::reqtopology, ast_channel_tech::type, ast_assigned_ids::uniqueid, and ast_assigned_ids::uniqueid2.

Referenced by announce_request(), local_request_with_stream_topology(), and media_request_helper().

1164 {
1165  struct ast_channel *owner;
1166  struct ast_channel *chan;
1167  RAII_VAR(struct ast_format *, fmt, NULL, ao2_cleanup);
1168  struct ast_assigned_ids id1 = {NULL, NULL};
1169  struct ast_assigned_ids id2 = {NULL, NULL};
1170  int generated_seqno = ast_atomic_fetchadd_int((int *) &name_sequence, +1);
1171  struct ast_stream_topology *topology;
1172 
1173  /* set unique ids for the two channels */
1174  if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
1175  id1.uniqueid = assignedids->uniqueid;
1176  id2.uniqueid = assignedids->uniqueid2;
1177  }
1178 
1179  /* if id1 given but not id2, use default of id1;2 */
1180  if (id1.uniqueid && ast_strlen_zero(id2.uniqueid)) {
1181  char *uniqueid2;
1182 
1183  uniqueid2 = ast_alloca(strlen(id1.uniqueid) + 3);
1184  strcpy(uniqueid2, id1.uniqueid);/* Safe */
1185  strcat(uniqueid2, ";2");/* Safe */
1186  id2.uniqueid = uniqueid2;
1187  }
1188 
1189  /* We need to create a topology to place on the first channel, as we can't
1190  * share a single one between both.
1191  */
1192  topology = ast_stream_topology_clone(p->reqtopology);
1193  if (!topology) {
1194  return NULL;
1195  }
1196 
1197  /*
1198  * Allocate two new Asterisk channels
1199  *
1200  * Make sure that the ;2 channel gets the same linkedid as ;1.
1201  * You can't pass linkedid to both allocations since if linkedid
1202  * isn't set, then each channel will generate its own linkedid.
1203  */
1204  owner = ast_channel_alloc(1, semi1_state, NULL, NULL, NULL,
1205  exten, context, &id1, requestor, 0,
1206  "%s/%s-%08x;1", tech->type, p->name, (unsigned)generated_seqno);
1207  if (!owner) {
1208  ast_log(LOG_WARNING, "Unable to allocate owner channel structure\n");
1209  ast_stream_topology_free(topology);
1210  return NULL;
1211  }
1212 
1213  if (callid) {
1214  ast_channel_callid_set(owner, callid);
1215  }
1216 
1217  ast_channel_tech_set(owner, tech);
1218  ao2_ref(p, +1);
1219  ast_channel_tech_pvt_set(owner, p);
1220 
1222 
1223  if (ast_channel_is_multistream(owner)) {
1224  ast_channel_set_stream_topology(owner, topology);
1225  }
1226 
1227  /* Determine our read/write format and set it on each channel */
1228  fmt = ast_format_cap_get_format(p->reqcap, 0);
1229  if (!fmt) {
1230  ast_channel_tech_pvt_set(owner, NULL);
1231  ao2_ref(p, -1);
1232  ast_channel_unlock(owner);
1233  ast_channel_release(owner);
1234  return NULL;
1235  }
1236 
1237  ast_channel_set_writeformat(owner, fmt);
1238  ast_channel_set_rawwriteformat(owner, fmt);
1239  ast_channel_set_readformat(owner, fmt);
1240  ast_channel_set_rawreadformat(owner, fmt);
1241 
1243 
1244  ast_jb_configure(owner, &p->jb_conf);
1245 
1246  if (ast_channel_cc_params_init(owner, requestor
1247  ? ast_channel_get_cc_config_params((struct ast_channel *) requestor) : NULL)) {
1248  ast_channel_tech_pvt_set(owner, NULL);
1249  ao2_ref(p, -1);
1250  ast_channel_tech_pvt_set(owner, NULL);
1251  ast_channel_unlock(owner);
1252  ast_channel_release(owner);
1253  return NULL;
1254  }
1255 
1256  p->owner = owner;
1257  ast_channel_unlock(owner);
1258 
1259  chan = ast_channel_alloc(1, semi2_state, NULL, NULL, NULL,
1260  exten, context, &id2, owner, 0,
1261  "%s/%s-%08x;2", tech->type, p->name, (unsigned)generated_seqno);
1262  if (!chan) {
1263  ast_log(LOG_WARNING, "Unable to allocate chan channel structure\n");
1264  ast_channel_tech_pvt_set(owner, NULL);
1265  ao2_ref(p, -1);
1266  ast_channel_tech_pvt_set(owner, NULL);
1267  ast_channel_release(owner);
1268  return NULL;
1269  }
1270 
1271  if (callid) {
1272  ast_channel_callid_set(chan, callid);
1273  }
1274 
1275  ast_channel_tech_set(chan, tech);
1276  ao2_ref(p, +1);
1277  ast_channel_tech_pvt_set(chan, p);
1278 
1280 
1281  if (ast_channel_is_multistream(chan)) {
1283  p->reqtopology = NULL;
1284  }
1285 
1286  /* Format was already determined when setting up owner */
1287  ast_channel_set_writeformat(chan, fmt);
1288  ast_channel_set_rawwriteformat(chan, fmt);
1289  ast_channel_set_readformat(chan, fmt);
1290  ast_channel_set_rawreadformat(chan, fmt);
1291 
1293 
1294  p->chan = chan;
1295  ast_channel_unlock(chan);
1296 
1297  return owner;
1298 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
const char *const type
Definition: channel.h:630
int ast_channel_is_multistream(struct ast_channel *chan)
Determine if a channel is multi-stream capable.
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1580
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: core_unreal.h:93
struct ast_jb_conf jb_conf
Definition: core_unreal.h:96
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:605
Definition of a media format.
Definition: format.c:43
const char * uniqueid
Definition: channel.h:606
#define NULL
Definition: resample.c:96
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
static unsigned int name_sequence
Definition: core_unreal.c:45
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Definition: channel.c:10586
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
#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
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
int ast_channel_cc_params_init(struct ast_channel *chan, const struct ast_cc_config_params *base_params)
Set up datastore with CCSS parameters for a channel.
Definition: channel.c:10563
struct ast_channel * chan
Definition: core_unreal.h:94
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
struct ast_format_cap * reqcap
Definition: core_unreal.h:95
struct ast_stream_topology * ast_channel_set_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Set the topology of streams on a channel.
char name[AST_MAX_EXTENSION+AST_MAX_CONTEXT+2]
Definition: core_unreal.h:99
#define ast_strlen_zero(a)
Definition: muted.c:73
#define ast_channel_unlock(chan)
Definition: channel.h:2914
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:593
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
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
struct ast_stream_topology * reqtopology
Definition: core_unreal.h:100
const char * uniqueid2
Definition: channel.h:607
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)

◆ ast_unreal_queryoption()

int ast_unreal_queryoption ( struct ast_channel ast,
int  option,
void *  data,
int *  datalen 
)

Unreal channel framework struct ast_channel_tech.queryoption callback

Definition at line 166 of file core_unreal.c.

References ao2_lock, ao2_unlock, ast_channel_bridge_peer(), ast_channel_lock, ast_channel_queryoption(), ast_channel_ref, ast_channel_tech_pvt(), ast_channel_unlock, ast_channel_unref, AST_OPTION_T38_STATE, AST_UNREAL_IS_OUTBOUND, ast_unreal_pvt::chan, and ast_unreal_pvt::owner.

167 {
168  struct ast_unreal_pvt *p;
169  struct ast_channel *peer;
170  struct ast_channel *other;
171  int res = 0;
172 
173  if (option != AST_OPTION_T38_STATE) {
174  /* AST_OPTION_T38_STATE is the only supported option at this time */
175  return -1;
176  }
177 
178  /* for some reason the channel is not locked in channel.c when this function is called */
179  if (!(p = ast_channel_tech_pvt(ast))) {
180  return -1;
181  }
182 
183  ao2_lock(p);
184  other = AST_UNREAL_IS_OUTBOUND(ast, p) ? p->owner : p->chan;
185  if (!other) {
186  ao2_unlock(p);
187  return -1;
188  }
189  ast_channel_ref(other);
190  ao2_unlock(p);
191  ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
192 
193  peer = ast_channel_bridge_peer(other);
194  if (peer) {
195  res = ast_channel_queryoption(peer, option, data, datalen, 0);
196  ast_channel_unref(peer);
197  }
198  ast_channel_unref(other);
199  ast_channel_lock(ast); /* Lock back before we leave */
200 
201  return res;
202 }
#define ast_channel_lock(chan)
Definition: channel.h:2913
Main Channel structure associated with a channel.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
int ast_channel_queryoption(struct ast_channel *channel, int option, void *data, int *datalen, int block)
Checks the value of an option.
Definition: channel.c:7459
struct ast_channel * owner
Definition: core_unreal.h:93
#define AST_UNREAL_IS_OUTBOUND(a, b)
Definition: core_unreal.h:105
#define ao2_unlock(a)
Definition: astobj2.h:730
const char * data
#define ao2_lock(a)
Definition: astobj2.h:718
struct ast_channel * chan
Definition: core_unreal.h:94
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
#define ast_channel_unlock(chan)
Definition: channel.h:2914
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2938
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10676
#define AST_OPTION_T38_STATE

◆ ast_unreal_read()

struct ast_frame* ast_unreal_read ( struct ast_channel ast)

Unreal channel framework struct ast_channel_tech.read and struct ast_channel_tech.exception callback

Definition at line 313 of file core_unreal.c.

References ast_null_frame.

314 {
315  return &ast_null_frame;
316 }
struct ast_frame ast_null_frame
Definition: main/frame.c:79

◆ ast_unreal_sendhtml()

int ast_unreal_sendhtml ( struct ast_channel ast,
int  subclass,
const char *  data,
int  datalen 
)

Unreal channel framework struct ast_channel_tech.send_html callback

Definition at line 846 of file core_unreal.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_tech_pvt(), AST_FRAME_HTML, AST_UNREAL_IS_OUTBOUND, ast_frame::data, ast_frame::datalen, ast_frame_subclass::integer, ast_frame::ptr, ast_frame::subclass, and unreal_queue_frame().

847 {
848  struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
849  int res = -1;
850  struct ast_frame f = { AST_FRAME_HTML, };
851  int isoutbound;
852 
853  if (!p) {
854  return -1;
855  }
856 
857  ao2_ref(p, 1); /* ref for unreal_queue_frame */
858  ao2_lock(p);
859  isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
861  f.data.ptr = (char *)data;
862  f.datalen = datalen;
863  res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
864  ao2_unlock(p);
865  ao2_ref(p, -1);
866 
867  return res;
868 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int unreal_queue_frame(struct ast_unreal_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame onto either the p->owner or p->chan
Definition: core_unreal.c:213
union ast_frame::@257 data
#define AST_UNREAL_IS_OUTBOUND(a, b)
Definition: core_unreal.h:105
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_frame_subclass subclass
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
Data structure associated with a single frame of data.

◆ ast_unreal_sendtext()

int ast_unreal_sendtext ( struct ast_channel ast,
const char *  text 
)

Unreal channel framework struct ast_channel_tech.send_text callback

Definition at line 824 of file core_unreal.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_tech_pvt(), AST_FRAME_TEXT, AST_UNREAL_IS_OUTBOUND, ast_frame::data, ast_frame::datalen, ast_frame::ptr, and unreal_queue_frame().

825 {
826  struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
827  int res = -1;
828  struct ast_frame f = { AST_FRAME_TEXT, };
829  int isoutbound;
830 
831  if (!p) {
832  return -1;
833  }
834 
835  ao2_ref(p, 1); /* ref for unreal_queue_frame */
836  ao2_lock(p);
837  isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
838  f.data.ptr = (char *) text;
839  f.datalen = strlen(text) + 1;
840  res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
841  ao2_unlock(p);
842  ao2_ref(p, -1);
843  return res;
844 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int unreal_queue_frame(struct ast_unreal_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame onto either the p->owner or p->chan
Definition: core_unreal.c:213
union ast_frame::@257 data
#define AST_UNREAL_IS_OUTBOUND(a, b)
Definition: core_unreal.h:105
#define ao2_unlock(a)
Definition: astobj2.h:730
char * text
Definition: app_queue.c:1508
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
Data structure associated with a single frame of data.

◆ ast_unreal_setoption()

int ast_unreal_setoption ( struct ast_channel chan,
int  option,
void *  data,
int  datalen 
)

Unreal channel framework struct ast_channel_tech.setoption callback

Definition at line 97 of file core_unreal.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_CHAN_WRITE_INFO_T_VERSION, ast_channel_lock, ast_channel_ref, ast_channel_tech_pvt(), ast_channel_unlock, ast_channel_unref, ast_log, AST_OPTION_CHANNEL_WRITE, ast_unreal_pvt::chan, ast_chan_write_info_t::chan, ast_channel::data, ast_chan_write_info_t::data, ast_chan_write_info_t::function, if(), LOG_ERROR, NULL, ast_unreal_pvt::owner, ast_chan_write_info_t::value, ast_chan_write_info_t::version, and ast_chan_write_info_t::write_fn.

Referenced by local_setoption().

98 {
99  int res = 0;
100  struct ast_unreal_pvt *p;
101  struct ast_channel *otherchan = NULL;
102  ast_chan_write_info_t *write_info;
103  char *info_data;
104 
105  if (option != AST_OPTION_CHANNEL_WRITE) {
106  return -1;
107  }
108 
109  write_info = data;
110 
111  if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
112  ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
113  return -1;
114  }
115 
116  info_data = write_info->data;
117  if (!strcmp(write_info->function, "CHANNEL")) {
118  if (!strncasecmp(info_data, "hangup_handler_", 15)) {
119  /* Block CHANNEL(hangup_handler_xxx) writes to the other unreal channel. */
120  return 0;
121  }
122 
123  /* Crossover the accountcode and peeraccount to cross the unreal bridge. */
124  if (!strcasecmp(info_data, "accountcode")) {
125  info_data = "peeraccount";
126  } else if (!strcasecmp(info_data, "peeraccount")) {
127  info_data = "accountcode";
128  }
129  }
130 
131  /* get the tech pvt */
132  if (!(p = ast_channel_tech_pvt(ast))) {
133  return -1;
134  }
135  ao2_ref(p, 1);
136  ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
137 
138  /* get the channel we are supposed to write to */
139  ao2_lock(p);
140  otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
141  if (!otherchan || otherchan == write_info->chan) {
142  res = -1;
143  otherchan = NULL;
144  ao2_unlock(p);
145  goto setoption_cleanup;
146  }
147  ast_channel_ref(otherchan);
148 
149  /* clear the pvt lock before grabbing the channel */
150  ao2_unlock(p);
151 
152  ast_channel_lock(otherchan);
153  res = write_info->write_fn(otherchan, write_info->function, info_data, write_info->value);
154  ast_channel_unlock(otherchan);
155 
156 setoption_cleanup:
157  ao2_ref(p, -1);
158  if (otherchan) {
159  ast_channel_unref(otherchan);
160  }
161  ast_channel_lock(ast); /* Lock back before we leave */
162  return res;
163 }
#define ast_channel_lock(chan)
Definition: channel.h:2913
const char * function
Definition: channel.h:596
Main Channel structure associated with a channel.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2949
struct ast_channel * owner
Definition: core_unreal.h:93
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
const char * data
const char * value
Definition: channel.h:598
#define ast_log
Definition: astobj2.c:42
struct ast_channel * chan
Definition: channel.h:595
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
struct ast_channel * chan
Definition: core_unreal.h:94
ast_acf_write_fn_t write_fn
Definition: channel.h:594
#define LOG_ERROR
Definition: logger.h:285
#define AST_CHAN_WRITE_INFO_T_VERSION
ast_chan_write_info_t version. Must be incremented if structure is changed
Definition: channel.h:592
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
#define ast_channel_unlock(chan)
Definition: channel.h:2914
#define AST_OPTION_CHANNEL_WRITE
Handle channel write data If a channel needs to process the data from a func_channel write operation ...
Structure to handle passing func_channel_write info to channels via setoption.
Definition: channel.h:590
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2938

◆ ast_unreal_write()

int ast_unreal_write ( struct ast_channel ast,
struct ast_frame f 
)

Unreal channel framework struct ast_channel_tech.write callback

Definition at line 318 of file core_unreal.c.

References ast_unreal_write_stream().

319 {
320  return ast_unreal_write_stream(ast, -1, f);
321 }
int ast_unreal_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f)
Definition: core_unreal.c:323

◆ ast_unreal_write_stream()

int ast_unreal_write_stream ( struct ast_channel ast,
int  stream_num,
struct ast_frame f 
)

Unreal channel framework struct ast_channel_tech.write_stream callback

Definition at line 323 of file core_unreal.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_get_default_stream(), ast_channel_tech_pvt(), AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, AST_UNREAL_IS_OUTBOUND, ast_frame::frametype, got_optimized_out(), ast_frame_subclass::integer, ast_frame::stream_num, ast_frame::subclass, and unreal_queue_frame().

Referenced by ast_unreal_write().

324 {
325  struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
326  int res = -1;
327 
328  if (!p) {
329  return -1;
330  }
331 
332  /* If we are told to write a frame with a type that has no corresponding
333  * stream on the channel then drop it.
334  */
335  if (f->frametype == AST_FRAME_VOICE) {
337  return 0;
338  }
339  } else if (f->frametype == AST_FRAME_VIDEO ||
342  return 0;
343  }
344  }
345 
346  /* Update the frame to reflect the stream */
347  f->stream_num = stream_num;
348 
349  /* Just queue for delivery to the other side */
350  ao2_ref(p, 1);
351  ao2_lock(p);
352  switch (f->frametype) {
353  case AST_FRAME_VOICE:
354  case AST_FRAME_VIDEO:
355  if (got_optimized_out(ast, p)) {
356  break;
357  }
358  /* fall through */
359  default:
360  res = unreal_queue_frame(p, AST_UNREAL_IS_OUTBOUND(ast, p), f, ast, 1);
361  break;
362  }
363  ao2_unlock(p);
364  ao2_ref(p, -1);
365 
366  return res;
367 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int unreal_queue_frame(struct ast_unreal_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame onto either the p->owner or p->chan
Definition: core_unreal.c:213
#define AST_UNREAL_IS_OUTBOUND(a, b)
Definition: core_unreal.h:105
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_frame_subclass subclass
struct ast_stream * ast_channel_get_default_stream(struct ast_channel *chan, enum ast_media_type type)
Retrieve the default stream of a specific media type on a channel.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static int got_optimized_out(struct ast_channel *ast, struct ast_unreal_pvt *p)
Definition: core_unreal.c:295
#define ao2_lock(a)
Definition: astobj2.h:718
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
enum ast_frame_type frametype