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

Local proxy channel driver. More...

#include "asterisk.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/devicestate.h"
#include "asterisk/astobj2.h"
#include "asterisk/bridge.h"
#include "asterisk/core_unreal.h"
#include "asterisk/core_local.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/_private.h"
#include "asterisk/stream.h"
#include "asterisk/translate.h"
Include dependency graph for core_local.c:

Go to the source code of this file.

Data Structures

struct  local_bridge
 
struct  local_pvt
 the local pvt structure for all channels More...
 

Enumerations

enum  local_call_action { LOCAL_CALL_ACTION_DIALPLAN, LOCAL_CALL_ACTION_BRIDGE, LOCAL_CALL_ACTION_MASQUERADE }
 

Functions

struct ast_channelast_local_get_peer (struct ast_channel *ast)
 Get the other local channel in the pair. More...
 
int ast_local_init (void)
 Initialize the local proxy channel. More...
 
void ast_local_lock_all (struct ast_channel *chan, void **tech_pvt, struct ast_channel **base_chan, struct ast_channel **base_owner)
 Add a reference to the local channel's private tech, lock the local channel's private base, and add references and lock both sides of the local channel. More...
 
int ast_local_setup_bridge (struct ast_channel *ast, struct ast_bridge *bridge, struct ast_channel *swap, struct ast_bridge_features *features)
 Setup the outgoing local channel to join a bridge on ast_call(). More...
 
int ast_local_setup_masquerade (struct ast_channel *ast, struct ast_channel *masq)
 Setup the outgoing local channel to masquerade into a channel on ast_call(). More...
 
void ast_local_unlock_all (void *tech_pvt, struct ast_channel *base_chan, struct ast_channel *base_owner)
 Remove a reference to the given local channel's private tech, unlock the given local channel's private base, and remove references and unlock both sides of given the local channel. More...
 
static struct local_pvtlocal_alloc (const char *data, struct ast_stream_topology *topology)
 Create a call structure. More...
 
static int local_call (struct ast_channel *ast, const char *dest, int timeout)
 Initiate new call, part of PBX interface dest is the dial string. More...
 
static struct ast_multi_channel_bloblocal_channel_optimization_blob (struct local_pvt *p, struct ast_json *json_object)
 
static int local_devicestate (const char *data)
 Adds devicestate to local channels. More...
 
static int local_hangup (struct ast_channel *ast)
 Hangup a call through the local proxy channel. More...
 
static struct ast_manager_event_bloblocal_message_to_ami (struct stasis_message *msg)
 
static void local_optimization_finished_cb (struct ast_unreal_pvt *base, int success, unsigned int id)
 Callback for ast_unreal_pvt_callbacks optimization_finished_cb. More...
 
static void local_optimization_started_cb (struct ast_unreal_pvt *base, struct ast_channel *source, enum ast_unreal_channel_indicator dest, unsigned int id)
 Callback for ast_unreal_pvt_callbacks optimization_started_cb. More...
 
static void local_pvt_destructor (void *vdoomed)
 
static struct ast_channellocal_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 Part of PBX interface. More...
 
static struct ast_channellocal_request_with_stream_topology (const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
 Part of PBX interface. More...
 
static int local_setoption (struct ast_channel *chan, int option, void *data, int datalen)
 
static void local_shutdown (void)
 
static int locals_cmp_cb (void *obj, void *arg, int flags)
 
static char * locals_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command "local show channels". More...
 
static int manager_optimize_away (struct mansession *s, const struct message *m)
 
static void publish_local_bridge_message (struct local_pvt *p)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_local_bridge_type,.to_ami=local_message_to_ami,)
 Define local channel message types. More...
 
 STASIS_MESSAGE_TYPE_DEFN (ast_local_optimization_begin_type,.to_ami=local_message_to_ami,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_local_optimization_end_type,.to_ami=local_message_to_ami,)
 

Variables

static struct ast_cli_entry cli_local []
 
static struct ast_channel_tech local_tech
 
struct ast_unreal_pvt_callbacks local_unreal_callbacks
 Callbacks from the unreal core when channel optimization occurs. More...
 
static struct ao2_containerlocals
 
static const char tdesc [] = "Local Proxy Channel Driver"
 

Detailed Description

Local proxy channel driver.

Author
Richard Mudgett rmudg[email protected][email protected][email protected]digiu[email protected]m.co[email protected]m

See Also:

Definition in file core_local.c.

Enumeration Type Documentation

◆ local_call_action

What to do with the ;2 channel when ast_call() happens.

Enumerator
LOCAL_CALL_ACTION_DIALPLAN 
LOCAL_CALL_ACTION_BRIDGE 
LOCAL_CALL_ACTION_MASQUERADE 

Definition at line 197 of file core_local.c.

197  {
198  /* The ast_call() will run dialplan on the ;2 channel. */
200  /* The ast_call() will impart the ;2 channel into a bridge. */
202  /* The ast_call() will masquerade the ;2 channel into a channel. */
204 };

Function Documentation

◆ ast_local_get_peer()

struct ast_channel* ast_local_get_peer ( struct ast_channel ast)

Get the other local channel in the pair.

Since
12.0.0
Parameters
astLocal channel to get peer.
Note
On entry, ast must be locked.
Return values
peerreffed on success.
NULLif no peer or error.

Definition at line 276 of file core_local.c.

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_channel_ref, ast_channel_tech_pvt(), local_pvt::base, ast_unreal_pvt::chan, NULL, and ast_unreal_pvt::owner.

Referenced by ari_channels_handle_originate_with_id(), and park_local_transfer().

277 {
278  struct local_pvt *p = ast_channel_tech_pvt(ast);
279  struct local_pvt *found;
280  struct ast_channel *peer;
281 
282  if (!p) {
283  return NULL;
284  }
285 
286  found = p ? ao2_find(locals, p, 0) : NULL;
287  if (!found) {
288  /* ast is either not a local channel or it has alredy been hungup */
289  return NULL;
290  }
291  ao2_lock(found);
292  if (ast == p->base.owner) {
293  peer = p->base.chan;
294  } else if (ast == p->base.chan) {
295  peer = p->base.owner;
296  } else {
297  peer = NULL;
298  }
299  if (peer) {
300  ast_channel_ref(peer);
301  }
302  ao2_unlock(found);
303  ao2_ref(found, -1);
304  return peer;
305 }
Main Channel structure associated with a channel.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_channel * owner
Definition: core_unreal.h:93
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
struct ast_unreal_pvt base
Definition: core_local.c:225
#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
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
the local pvt structure for all channels
Definition: core_local.c:223
static struct ao2_container * locals
Definition: core_local.c:138

◆ ast_local_init()

int ast_local_init ( void  )

Initialize the local proxy channel.

Since
12.0.0
Return values
0on success.
-1on error.

Definition at line 1140 of file core_local.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple, ast_format_cap_alloc, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_local_bridge_type(), ast_local_optimization_begin_type(), ast_local_optimization_end_type(), ast_log, ast_manager_register_xml_core, AST_MEDIA_TYPE_UNKNOWN, ast_register_cleanup(), ast_channel_tech::capabilities, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, local_shutdown(), locals_cmp_cb(), LOG_ERROR, manager_optimize_away(), NULL, and STASIS_MESSAGE_TYPE_INIT.

Referenced by asterisk_daemon().

1141 {
1143  return -1;
1144  }
1145 
1147  return -1;
1148  }
1149 
1151  return -1;
1152  }
1153 
1155  return -1;
1156  }
1158 
1160  if (!locals) {
1161  return -1;
1162  }
1163 
1164  /* Make sure we can register our channel type */
1166  ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
1167 
1168  return -1;
1169  }
1172 
1174  return 0;
1175 }
static int manager_optimize_away(struct mansession *s, const struct message *m)
Definition: core_local.c:1073
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int locals_cmp_cb(void *obj, void *arg, int flags)
Definition: core_local.c:1110
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1501
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
#define NULL
Definition: resample.c:96
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:197
static struct ast_cli_entry cli_local[]
Definition: core_local.c:1069
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_log
Definition: astobj2.c:42
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
#define LOG_ERROR
Definition: logger.h:285
static struct ast_channel_tech local_tech
Definition: core_local.c:173
struct ast_format_cap * capabilities
Definition: channel.h:633
struct stasis_message_type * ast_local_bridge_type(void)
Message type for when two local channel halves are bridged together.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
static struct ao2_container * locals
Definition: core_local.c:138
static void local_shutdown(void)
Definition: core_local.c:1122

◆ ast_local_lock_all()

void ast_local_lock_all ( struct ast_channel chan,
void **  tech_pvt,
struct ast_channel **  base_chan,
struct ast_channel **  base_owner 
)

Add a reference to the local channel's private tech, lock the local channel's private base, and add references and lock both sides of the local channel.

Note
None of these locks should be held prior to calling this function.
To undo this process call ast_local_unlock_all2.
Since
13.17.0, 14.6.0
Parameters
chanMust be a local channel
tech_pvt[out] channel's private tech (ref and lock added)
base_chan[out] One side of the local channel (ref and lock added)
base_owner[out] Other side of the local channel (ref and lock added)

Definition at line 241 of file core_local.c.

References ao2_bump, ast_channel_tech_pvt(), ast_unreal_lock_all(), local_pvt::base, and NULL.

Referenced by attended_transfer_bridge().

243 {
244  struct local_pvt *p = ast_channel_tech_pvt(chan);
245 
246  *tech_pvt = NULL;
247  *base_chan = NULL;
248  *base_owner = NULL;
249 
250  if (p) {
251  *tech_pvt = ao2_bump(p);
252  ast_unreal_lock_all(&p->base, base_chan, base_owner);
253  }
254 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
struct ast_unreal_pvt base
Definition: core_local.c:225
the local pvt structure for all channels
Definition: core_local.c:223
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_local_setup_bridge()

int ast_local_setup_bridge ( struct ast_channel ast,
struct ast_bridge bridge,
struct ast_channel swap,
struct ast_bridge_features features 
)

Setup the outgoing local channel to join a bridge on ast_call().

Since
12.0.0
Parameters
astEither channel of a local channel pair.
bridgeBridge to join.
swapChannel to swap with when joining.
featuresBridge features structure.
Note
The features parameter must be NULL or obtained by ast_bridge_features_new(). You must not dereference features after calling even if the call fails.
Intended to be called after ast_request() and before ast_call() on a local channel.
Return values
0on success.
-1on error.

Definition at line 599 of file core_local.c.

References local_pvt::action, ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_bridge_features_destroy(), ast_channel_lock, ast_channel_ref, ast_channel_tech_pvt(), ast_channel_unlock, ast_test_flag, AST_UNREAL_CARETAKER_THREAD, local_pvt::base, local_pvt::bridge, ast_unreal_pvt::chan, local_bridge::features, local_bridge::join, LOCAL_CALL_ACTION_BRIDGE, LOCAL_CALL_ACTION_DIALPLAN, NULL, ast_unreal_pvt::owner, local_bridge::swap, and local_pvt::type.

Referenced by attended_transfer_bridge().

600 {
601  struct local_pvt *p;
602  struct local_pvt *found;
603  int res = -1;
604 
605  /* Sanity checks. */
606  if (!ast || !bridge) {
607  ast_bridge_features_destroy(features);
608  return -1;
609  }
610 
611  ast_channel_lock(ast);
612  p = ast_channel_tech_pvt(ast);
613  ast_channel_unlock(ast);
614 
615  found = p ? ao2_find(locals, p, 0) : NULL;
616  if (found) {
617  ao2_lock(found);
618  if (found->type == LOCAL_CALL_ACTION_DIALPLAN
619  && found->base.owner
620  && found->base.chan
622  ao2_ref(bridge, +1);
623  if (swap) {
624  ast_channel_ref(swap);
625  }
627  found->action.bridge.join = bridge;
628  found->action.bridge.swap = swap;
629  found->action.bridge.features = features;
630  res = 0;
631  } else {
632  ast_bridge_features_destroy(features);
633  }
634  ao2_unlock(found);
635  ao2_ref(found, -1);
636  }
637 
638  return res;
639 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_channel * owner
Definition: core_unreal.h:93
struct ast_channel * swap
Definition: core_local.c:211
#define AST_UNREAL_CARETAKER_THREAD
Definition: core_unreal.h:107
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
struct ast_unreal_pvt base
Definition: core_local.c:225
struct ast_bridge_features * features
Definition: core_local.c:213
#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
enum local_call_action type
Definition: core_local.c:234
union local_pvt::@376 action
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge * join
Definition: core_local.c:209
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
the local pvt structure for all channels
Definition: core_local.c:223
static struct ao2_container * locals
Definition: core_local.c:138
struct local_bridge bridge
Definition: core_local.c:229

◆ ast_local_setup_masquerade()

int ast_local_setup_masquerade ( struct ast_channel ast,
struct ast_channel masq 
)

Setup the outgoing local channel to masquerade into a channel on ast_call().

Since
12.0.0
Parameters
astEither channel of a local channel pair.
masqChannel to masquerade into.
Note
Intended to be called after ast_request() and before ast_call() on a local channel.
Return values
0on success.
-1on error.

Definition at line 641 of file core_local.c.

References local_pvt::action, ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_channel_lock, ast_channel_ref, ast_channel_tech_pvt(), ast_channel_unlock, ast_test_flag, AST_UNREAL_CARETAKER_THREAD, local_pvt::base, ast_unreal_pvt::chan, LOCAL_CALL_ACTION_DIALPLAN, LOCAL_CALL_ACTION_MASQUERADE, local_pvt::masq, NULL, ast_unreal_pvt::owner, and local_pvt::type.

Referenced by attended_transfer_bridge().

642 {
643  struct local_pvt *p;
644  struct local_pvt *found;
645  int res = -1;
646 
647  /* Sanity checks. */
648  if (!ast || !masq) {
649  return -1;
650  }
651 
652  ast_channel_lock(ast);
653  p = ast_channel_tech_pvt(ast);
654  ast_channel_unlock(ast);
655 
656  found = p ? ao2_find(locals, p, 0) : NULL;
657  if (found) {
658  ao2_lock(found);
659  if (found->type == LOCAL_CALL_ACTION_DIALPLAN
660  && found->base.owner
661  && found->base.chan
663  ast_channel_ref(masq);
665  found->action.masq = masq;
666  res = 0;
667  }
668  ao2_unlock(found);
669  ao2_ref(found, -1);
670  }
671 
672  return res;
673 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_test_flag(p, flag)
Definition: utils.h:63
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
struct ast_unreal_pvt base
Definition: core_local.c:225
#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
enum local_call_action type
Definition: core_local.c:234
union local_pvt::@376 action
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
the local pvt structure for all channels
Definition: core_local.c:223
struct ast_channel * masq
Definition: core_local.c:231
static struct ao2_container * locals
Definition: core_local.c:138

◆ ast_local_unlock_all()

void ast_local_unlock_all ( void *  tech_pvt,
struct ast_channel base_chan,
struct ast_channel base_owner 
)

Remove a reference to the given local channel's private tech, unlock the given local channel's private base, and remove references and unlock both sides of given the local channel.

Note
This function should be used in conjunction with ast_local_lock_all2.
Since
13.17.0, 14.6.0
Parameters
tech_pvtchannel's private tech (ref and lock removed)
base_chanOne side of the local channel (ref and lock removed)
base_ownerOther side of the local channel (ref and lock removed)

Definition at line 256 of file core_local.c.

References ao2_ref, ao2_unlock, ast_channel_unlock, ast_channel_unref, and local_pvt::base.

Referenced by attended_transfer_bridge().

258 {
259  if (base_chan) {
260  ast_channel_unlock(base_chan);
261  ast_channel_unref(base_chan);
262  }
263 
264  if (base_owner) {
265  ast_channel_unlock(base_owner);
266  ast_channel_unref(base_owner);
267  }
268 
269  if (tech_pvt) {
270  struct local_pvt *p = tech_pvt;
271  ao2_unlock(&p->base);
272  ao2_ref(tech_pvt, -1);
273  }
274 }
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_unreal_pvt base
Definition: core_local.c:225
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_channel_unlock(chan)
Definition: channel.h:2946
the local pvt structure for all channels
Definition: core_local.c:223

◆ local_alloc()

static struct local_pvt* local_alloc ( const char *  data,
struct ast_stream_topology topology 
)
static

Create a call structure.

Definition at line 866 of file core_local.c.

References ast_clear_flag, ast_copy_string(), AST_JB_ENABLED, ast_log, ast_set_flag, ast_strdupa, ast_test_flag, ast_unreal_alloc_stream_topology(), AST_UNREAL_MOH_INTERCEPT, AST_UNREAL_NO_OPTIMIZATION, local_pvt::base, ast_unreal_pvt::callbacks, context, local_pvt::context, local_pvt::exten, ast_unreal_pvt::jb_conf, local_pvt_destructor(), local_unreal_callbacks, LOG_ERROR, ast_unreal_pvt::name, NULL, parse(), and S_OR.

Referenced by local_request_with_stream_topology().

867 {
868  struct local_pvt *pvt;
869  char *parse;
870  char *context;
871  char *opts;
872 
873  pvt = (struct local_pvt *) ast_unreal_alloc_stream_topology(sizeof(*pvt), local_pvt_destructor, topology);
874  if (!pvt) {
875  return NULL;
876  }
878 
879  parse = ast_strdupa(data);
880 
881  /*
882  * Local channels intercept MOH by default.
883  *
884  * This is a silly default because it represents state held by
885  * the local channels. Unless local channel optimization is
886  * disabled, the state will dissapear when the local channels
887  * optimize out.
888  */
890 
891  /* Look for options */
892  if ((opts = strchr(parse, '/'))) {
893  *opts++ = '\0';
894  if (strchr(opts, 'n')) {
896  }
897  if (strchr(opts, 'j')) {
900  } else {
901  ast_log(LOG_ERROR, "You must use the 'n' option with the 'j' option to enable the jitter buffer\n");
902  }
903  }
904  if (strchr(opts, 'm')) {
906  }
907  }
908 
909  /* Look for a context */
910  if ((context = strchr(parse, '@'))) {
911  *context++ = '\0';
912  }
913 
914  ast_copy_string(pvt->context, S_OR(context, "default"), sizeof(pvt->context));
915  ast_copy_string(pvt->exten, parse, sizeof(pvt->exten));
916  snprintf(pvt->base.name, sizeof(pvt->base.name), "%[email protected]%s", pvt->exten, pvt->context);
917 
918  return pvt; /* this is returned with a ref */
919 }
char context[AST_MAX_CONTEXT]
Definition: core_local.c:236
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_unreal_pvt_callbacks * callbacks
Definition: core_unreal.h:92
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define AST_UNREAL_NO_OPTIMIZATION
Definition: core_unreal.h:108
struct ast_jb_conf jb_conf
Definition: core_unreal.h:96
#define NULL
Definition: resample.c:96
#define AST_UNREAL_MOH_INTERCEPT
Definition: core_unreal.h:109
#define ast_log
Definition: astobj2.c:42
struct ast_unreal_pvt base
Definition: core_local.c:225
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_unreal_pvt_callbacks local_unreal_callbacks
Callbacks from the unreal core when channel optimization occurs.
Definition: core_local.c:167
#define LOG_ERROR
Definition: logger.h:285
char name[AST_MAX_EXTENSION+AST_MAX_CONTEXT+2]
Definition: core_unreal.h:99
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define ast_clear_flag(p, flag)
Definition: utils.h:77
the local pvt structure for all channels
Definition: core_local.c:223
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
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:1128
static void local_pvt_destructor(void *vdoomed)
Definition: core_local.c:846
char exten[AST_MAX_EXTENSION]
Definition: core_local.c:238
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ local_call()

static int local_call ( struct ast_channel ast,
const char *  dest,
int  timeout 
)
static

Initiate new call, part of PBX interface dest is the dial string.

Definition at line 677 of file core_local.c.

References local_pvt::action, ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, ast_answer(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_channel_caller(), ast_channel_lock, ast_channel_move(), ast_channel_tech_pvt(), ast_channel_unlock, ast_channel_unref, ast_exists_extension(), ast_hangup(), ast_log, ast_pbx_start(), ast_set_cc_interfaces_chanvar(), ast_set_flag, ast_strdupa, ast_unreal_call_setup(), AST_UNREAL_CARETAKER_THREAD, ast_unreal_lock_all(), local_pvt::base, local_pvt::bridge, local_pvt::context, local_pvt::exten, local_bridge::features, local_bridge::join, LOCAL_CALL_ACTION_BRIDGE, LOCAL_CALL_ACTION_DIALPLAN, LOCAL_CALL_ACTION_MASQUERADE, LOG_NOTICE, local_pvt::masq, NULL, publish_local_bridge_message(), S_COR, local_bridge::swap, and local_pvt::type.

678 {
679  struct local_pvt *p = ast_channel_tech_pvt(ast);
680  int pvt_locked = 0;
681 
682  struct ast_channel *owner = NULL;
683  struct ast_channel *chan = NULL;
684  int res;
685  char *reduced_dest = ast_strdupa(dest);
686  char *slash;
687  const char *chan_cid;
688 
689  if (!p) {
690  return -1;
691  }
692 
693  /* since we are letting go of channel locks that were locked coming into
694  * this function, then we need to give the tech pvt a ref */
695  ao2_ref(p, 1);
696  ast_channel_unlock(ast);
697 
698  ast_unreal_lock_all(&p->base, &chan, &owner);
699  pvt_locked = 1;
700 
701  if (owner != ast) {
702  res = -1;
703  goto return_cleanup;
704  }
705 
706  if (!owner || !chan) {
707  res = -1;
708  goto return_cleanup;
709  }
710 
711  ast_unreal_call_setup(owner, chan);
712 
713  /*
714  * If the local channel has /n on the end of it, we need to lop
715  * that off for our argument to setting up the CC_INTERFACES
716  * variable.
717  */
718  if ((slash = strrchr(reduced_dest, '/'))) {
719  *slash = '\0';
720  }
721  ast_set_cc_interfaces_chanvar(chan, reduced_dest);
722 
723  ao2_unlock(p);
724  pvt_locked = 0;
725 
726  ast_channel_unlock(owner);
727 
728  chan_cid = S_COR(ast_channel_caller(chan)->id.number.valid,
729  ast_channel_caller(chan)->id.number.str, NULL);
730  if (chan_cid) {
731  chan_cid = ast_strdupa(chan_cid);
732  }
733  ast_channel_unlock(chan);
734 
735  res = -1;
736  switch (p->type) {
738  if (!ast_exists_extension(NULL, p->context, p->exten, 1, chan_cid)) {
739  ast_log(LOG_NOTICE, "No such extension/context %[email protected]%s while calling Local channel\n",
740  p->exten, p->context);
741  } else {
743 
744  /* Start switch on sub channel */
745  res = ast_pbx_start(chan);
746  }
747  break;
750  ast_answer(chan);
751  res = ast_bridge_impart(p->action.bridge.join, chan, p->action.bridge.swap,
753  ao2_ref(p->action.bridge.join, -1);
754  p->action.bridge.join = NULL;
756  p->action.bridge.swap = NULL;
757  p->action.bridge.features = NULL;
758  break;
761  ast_answer(chan);
762  res = ast_channel_move(p->action.masq, chan);
763  if (!res) {
764  /* Chan is now an orphaned zombie. Destroy it. */
765  ast_hangup(chan);
766  }
768  break;
769  }
770  if (!res) {
771  ao2_lock(p);
773  ao2_unlock(p);
774  }
775 
776  /* we already unlocked them, clear them here so the cleanup label won't touch them. */
777  owner = ast_channel_unref(owner);
778  chan = ast_channel_unref(chan);
779 
780 return_cleanup:
781  if (p) {
782  if (pvt_locked) {
783  ao2_unlock(p);
784  }
785  ao2_ref(p, -1);
786  }
787  if (chan) {
788  ast_channel_unlock(chan);
789  ast_channel_unref(chan);
790  }
791 
792  /*
793  * owner is supposed to be == to ast, if it is, don't unlock it
794  * because ast must exit locked
795  */
796  if (owner) {
797  if (owner != ast) {
798  ast_channel_unlock(owner);
799  ast_channel_lock(ast);
800  }
801  ast_channel_unref(owner);
802  } else {
803  /* we have to exit with ast locked */
804  ast_channel_lock(ast);
805  }
806 
807  return res;
808 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
char context[AST_MAX_CONTEXT]
Definition: core_local.c:236
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define ast_set_flag(p, flag)
Definition: utils.h:70
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4712
struct ast_channel * swap
Definition: core_local.c:211
#define AST_UNREAL_CARETAKER_THREAD
Definition: core_unreal.h:107
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
Move a channel from its current location to a new location.
Definition: channel.c:10867
Number structure.
Definition: app_followme.c:154
#define ast_log
Definition: astobj2.c:42
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
struct ast_unreal_pvt base
Definition: core_local.c:225
struct ast_bridge_features * features
Definition: core_local.c:213
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
Setup unreal owner and chan channels before initiating call.
Definition: core_unreal.c:870
enum local_call_action type
Definition: core_local.c:234
static void publish_local_bridge_message(struct local_pvt *p)
Definition: core_local.c:540
union local_pvt::@376 action
#define LOG_NOTICE
Definition: logger.h:263
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge * join
Definition: core_local.c:209
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
the local pvt structure for all channels
Definition: core_local.c:223
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
char exten[AST_MAX_EXTENSION]
Definition: core_local.c:238
struct ast_channel * masq
Definition: core_local.c:231
struct local_bridge bridge
Definition: core_local.c:229
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
int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char *const extension)
Set the CC_INTERFACES channel variable for a channel using an.
Definition: ccss.c:3668

◆ local_channel_optimization_blob()

static struct ast_multi_channel_blob* local_channel_optimization_blob ( struct local_pvt p,
struct ast_json json_object 
)
static

Definition at line 362 of file core_local.c.

References ao2_cleanup, ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), ast_multi_channel_blob_add_channel(), ast_multi_channel_blob_create(), local_pvt::base, ast_unreal_pvt::chan, NULL, ast_unreal_pvt::owner, and RAII_VAR.

Referenced by local_optimization_finished_cb(), and local_optimization_started_cb().

364 {
365  struct ast_multi_channel_blob *payload;
366  RAII_VAR(struct ast_channel_snapshot *, local_one_snapshot, NULL, ao2_cleanup);
367  RAII_VAR(struct ast_channel_snapshot *, local_two_snapshot, NULL, ao2_cleanup);
368 
370  if (!local_one_snapshot) {
371  return NULL;
372  }
373 
375  if (!local_two_snapshot) {
376  return NULL;
377  }
378 
379  payload = ast_multi_channel_blob_create(json_object);
380  if (!payload) {
381  return NULL;
382  }
383  ast_multi_channel_blob_add_channel(payload, "1", local_one_snapshot);
384  ast_multi_channel_blob_add_channel(payload, "2", local_two_snapshot);
385 
386  return payload;
387 }
struct ast_channel * owner
Definition: core_unreal.h:93
Structure representing a snapshot of channel state.
#define NULL
Definition: resample.c:96
struct ast_unreal_pvt base
Definition: core_local.c:225
#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_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
Add a ast_channel_snapshot to a ast_multi_channel_blob object.
struct ast_channel * chan
Definition: core_unreal.h:94
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A multi channel blob data structure for multi_channel_blob stasis messages.
struct ast_multi_channel_blob * ast_multi_channel_blob_create(struct ast_json *blob)
Create a ast_multi_channel_blob suitable for a stasis_message.

◆ local_devicestate()

static int local_devicestate ( const char *  data)
static

Adds devicestate to local channels.

Definition at line 308 of file core_local.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_debug, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, ast_exists_extension(), ast_log, ast_strdupa, ast_test_flag, AST_UNREAL_CARETAKER_THREAD, local_pvt::base, context, local_pvt::context, exten, local_pvt::exten, LOG_WARNING, NULL, and ast_unreal_pvt::owner.

309 {
310  int is_inuse = 0;
311  int res = AST_DEVICE_INVALID;
312  char *exten = ast_strdupa(data);
313  char *context;
314  char *opts;
315  struct local_pvt *lp;
316  struct ao2_iterator it;
317 
318  /* Strip options if they exist */
319  opts = strchr(exten, '/');
320  if (opts) {
321  *opts = '\0';
322  }
323 
324  context = strchr(exten, '@');
325  if (!context) {
327  "Someone used Local/%s somewhere without a @context. This is bad.\n", data);
328  return AST_DEVICE_INVALID;
329  }
330  *context++ = '\0';
331 
332  it = ao2_iterator_init(locals, 0);
333  for (; (lp = ao2_iterator_next(&it)); ao2_ref(lp, -1)) {
334  ao2_lock(lp);
335  if (!strcmp(exten, lp->exten)
336  && !strcmp(context, lp->context)) {
337  res = AST_DEVICE_NOT_INUSE;
338  if (lp->base.owner
340  is_inuse = 1;
341  }
342  }
343  ao2_unlock(lp);
344  if (is_inuse) {
345  res = AST_DEVICE_INUSE;
346  ao2_ref(lp, -1);
347  break;
348  }
349  }
351 
352  if (res == AST_DEVICE_INVALID) {
353  ast_debug(3, "Checking if extension %[email protected]%s exists (devicestate)\n", exten, context);
354  if (ast_exists_extension(NULL, context, exten, 1, NULL)) {
355  res = AST_DEVICE_NOT_INUSE;
356  }
357  }
358 
359  return res;
360 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
char context[AST_MAX_CONTEXT]
Definition: core_local.c:236
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
struct ast_channel * owner
Definition: core_unreal.h:93
#define AST_UNREAL_CARETAKER_THREAD
Definition: core_unreal.h:107
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct ast_unreal_pvt base
Definition: core_local.c:225
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
the local pvt structure for all channels
Definition: core_local.c:223
char exten[AST_MAX_EXTENSION]
Definition: core_local.c:238
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static struct ao2_container * locals
Definition: core_local.c:138
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ local_hangup()

static int local_hangup ( struct ast_channel ast)
static

Hangup a call through the local proxy channel.

Definition at line 811 of file core_local.c.

References ao2_lock, ao2_ref, ao2_unlink, ao2_unlock, ast_channel_tech_pvt(), ast_unreal_hangup(), local_pvt::base, ast_unreal_pvt::chan, and ast_unreal_pvt::owner.

812 {
813  struct local_pvt *p = ast_channel_tech_pvt(ast);
814  int res;
815 
816  if (!p) {
817  return -1;
818  }
819 
820  /* give the pvt a ref to fulfill calling requirements. */
821  ao2_ref(p, +1);
822  res = ast_unreal_hangup(&p->base, ast);
823  if (!res) {
824  int unlink;
825 
826  ao2_lock(p);
827  unlink = !p->base.owner && !p->base.chan;
828  ao2_unlock(p);
829  if (unlink) {
830  ao2_unlink(locals, p);
831  }
832  }
833  ao2_ref(p, -1);
834 
835  return res;
836 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_channel * owner
Definition: core_unreal.h:93
#define ao2_unlock(a)
Definition: astobj2.h:730
struct ast_unreal_pvt base
Definition: core_local.c:225
#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
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
the local pvt structure for all channels
Definition: core_local.c:223
static struct ao2_container * locals
Definition: core_local.c:138
int ast_unreal_hangup(struct ast_unreal_pvt *p, struct ast_channel *ast)
Hangup one end (maybe both ends) of an unreal channel derivative.
Definition: core_unreal.c:1018

◆ local_message_to_ami()

static struct ast_manager_event_blob * local_message_to_ami ( struct stasis_message msg)
static

Definition at line 463 of file core_local.c.

References ast_free, ast_json_integer_get(), ast_json_is_true(), ast_json_object_get(), ast_json_string_get(), ast_local_bridge_type(), ast_local_optimization_begin_type(), ast_local_optimization_end_type(), ast_manager_build_channel_state_string_prefix(), ast_manager_event_blob_create(), ast_multi_channel_blob_get_channel(), ast_multi_channel_blob_get_json(), ast_str_append(), ast_str_buffer(), ast_str_create, AST_UNREAL_OWNER, ast_channel_snapshot::base, EVENT_FLAG_CALL, NULL, RAII_VAR, stasis_message_data(), stasis_message_type(), and ast_channel_snapshot_base::uniqueid.

464 {
466  struct ast_json *blob = ast_multi_channel_blob_get_json(obj);
467  struct ast_channel_snapshot *local_snapshot_one;
468  struct ast_channel_snapshot *local_snapshot_two;
469  RAII_VAR(struct ast_str *, local_channel_one, NULL, ast_free);
470  RAII_VAR(struct ast_str *, local_channel_two, NULL, ast_free);
471  RAII_VAR(struct ast_str *, event_buffer, NULL, ast_free);
472  const char *event;
473 
474  local_snapshot_one = ast_multi_channel_blob_get_channel(obj, "1");
475  local_snapshot_two = ast_multi_channel_blob_get_channel(obj, "2");
476  if (!local_snapshot_one || !local_snapshot_two) {
477  return NULL;
478  }
479 
480  event_buffer = ast_str_create(1024);
481  local_channel_one = ast_manager_build_channel_state_string_prefix(local_snapshot_one, "LocalOne");
482  local_channel_two = ast_manager_build_channel_state_string_prefix(local_snapshot_two, "LocalTwo");
483  if (!event_buffer || !local_channel_one || !local_channel_two) {
484  return NULL;
485  }
486 
488  struct ast_channel_snapshot *source_snapshot;
489  RAII_VAR(struct ast_str *, source_str, NULL, ast_free);
490  const char *dest_uniqueid;
491 
492  source_snapshot = ast_multi_channel_blob_get_channel(obj, "source");
493  if (source_snapshot) {
494  source_str = ast_manager_build_channel_state_string_prefix(source_snapshot, "Source");
495  if (!source_str) {
496  return NULL;
497  }
498  }
499 
500  dest_uniqueid = ast_json_object_get(blob, "dest") == AST_UNREAL_OWNER ?
501  local_snapshot_one->base->uniqueid : local_snapshot_two->base->uniqueid;
502 
503  event = "LocalOptimizationBegin";
504  if (source_str) {
505  ast_str_append(&event_buffer, 0, "%s", ast_str_buffer(source_str));
506  }
507  ast_str_append(&event_buffer, 0, "DestUniqueId: %s\r\n", dest_uniqueid);
508  ast_str_append(&event_buffer, 0, "Id: %u\r\n", (unsigned int) ast_json_integer_get(ast_json_object_get(blob, "id")));
510  event = "LocalOptimizationEnd";
511  ast_str_append(&event_buffer, 0, "Success: %s\r\n", ast_json_integer_get(ast_json_object_get(blob, "success")) ? "Yes" : "No");
512  ast_str_append(&event_buffer, 0, "Id: %u\r\n", (unsigned int) ast_json_integer_get(ast_json_object_get(blob, "id")));
514  event = "LocalBridge";
515  ast_str_append(&event_buffer, 0, "Context: %s\r\n", ast_json_string_get(ast_json_object_get(blob, "context")));
516  ast_str_append(&event_buffer, 0, "Exten: %s\r\n", ast_json_string_get(ast_json_object_get(blob, "exten")));
517  ast_str_append(&event_buffer, 0, "LocalOptimization: %s\r\n", ast_json_is_true(ast_json_object_get(blob, "can_optimize")) ? "Yes" : "No");
518  } else {
519  return NULL;
520  }
521 
523  "%s"
524  "%s"
525  "%s",
526  ast_str_buffer(local_channel_one),
527  ast_str_buffer(local_channel_two),
528  ast_str_buffer(event_buffer));
529 }
struct ast_channel_snapshot_base * base
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_json_is_true(const struct ast_json *value)
Check if value is JSON true.
Definition: json.c:253
Structure representing a snapshot of channel state.
struct ast_str * ast_manager_build_channel_state_string_prefix(const struct ast_channel_snapshot *snapshot, const char *prefix)
Generate the AMI message body from a channel snapshot.
#define EVENT_FLAG_CALL
Definition: manager.h:72
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
Definition: astman.c:222
const ast_string_field uniqueid
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define NULL
Definition: resample.c:96
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
Definition: manager.c:9727
struct ast_json * ast_multi_channel_blob_get_json(struct ast_multi_channel_blob *obj)
Retrieve the JSON blob from a ast_multi_channel_blob. Returned ast_json is still owned by obj...
#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
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
#define ast_free(a)
Definition: astmm.h:182
struct stasis_message_type * ast_local_bridge_type(void)
Message type for when two local channel halves are bridged together.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
A multi channel blob data structure for multi_channel_blob stasis messages.
Abstract JSON element (object, array, string, int, ...).
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:322
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:620

◆ local_optimization_finished_cb()

static void local_optimization_finished_cb ( struct ast_unreal_pvt base,
int  success,
unsigned int  id 
)
static

Callback for ast_unreal_pvt_callbacks optimization_finished_cb.

Definition at line 433 of file core_local.c.

References ao2_cleanup, ast_channel_topic(), ast_json_null(), ast_json_pack(), ast_json_unref(), ast_local_optimization_end_type(), local_pvt::base, local_channel_optimization_blob(), NULL, ast_unreal_pvt::owner, RAII_VAR, stasis_message_create(), and stasis_publish().

434 {
435  RAII_VAR(struct ast_json *, json_object, ast_json_null(), ast_json_unref);
436  RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
437  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
438  struct local_pvt *p = (struct local_pvt *)base;
439 
441  return;
442  }
443 
444  json_object = ast_json_pack("{s: i, s: I}", "success", success, "id", (ast_json_int_t)id);
445 
446  if (!json_object) {
447  return;
448  }
449 
450  payload = local_channel_optimization_blob(p, json_object);
451  if (!payload) {
452  return;
453  }
454 
456  if (!msg) {
457  return;
458  }
459 
461 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
Definition: json.h:87
struct ast_channel * owner
Definition: core_unreal.h:93
static struct ast_multi_channel_blob * local_channel_optimization_blob(struct local_pvt *p, struct ast_json *json_object)
Definition: core_local.c:362
#define NULL
Definition: resample.c:96
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
struct ast_unreal_pvt base
Definition: core_local.c:225
#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
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
the local pvt structure for all channels
Definition: core_local.c:223
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A multi channel blob data structure for multi_channel_blob stasis messages.
Abstract JSON element (object, array, string, int, ...).

◆ local_optimization_started_cb()

static void local_optimization_started_cb ( struct ast_unreal_pvt base,
struct ast_channel source,
enum ast_unreal_channel_indicator  dest,
unsigned int  id 
)
static

Callback for ast_unreal_pvt_callbacks optimization_started_cb.

Definition at line 390 of file core_local.c.

References ao2_cleanup, ast_channel_snapshot_get_latest(), ast_channel_topic(), ast_channel_uniqueid(), ast_json_null(), ast_json_pack(), ast_json_unref(), ast_local_optimization_begin_type(), ast_multi_channel_blob_add_channel(), local_pvt::base, local_channel_optimization_blob(), NULL, ast_unreal_pvt::owner, RAII_VAR, stasis_message_create(), and stasis_publish().

392 {
393  RAII_VAR(struct ast_json *, json_object, ast_json_null(), ast_json_unref);
394  RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
395  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
396  struct local_pvt *p = (struct local_pvt *)base;
397 
399  return;
400  }
401 
402  json_object = ast_json_pack("{s: i, s: I}",
403  "dest", dest, "id", (ast_json_int_t)id);
404 
405  if (!json_object) {
406  return;
407  }
408 
409  payload = local_channel_optimization_blob(p, json_object);
410  if (!payload) {
411  return;
412  }
413 
414  if (source) {
415  RAII_VAR(struct ast_channel_snapshot *, source_snapshot, NULL, ao2_cleanup);
416  source_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(source));
417  if (!source_snapshot) {
418  return;
419  }
420 
421  ast_multi_channel_blob_add_channel(payload, "source", source_snapshot);
422  }
423 
425  if (!msg) {
426  return;
427  }
428 
430 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
Definition: json.h:87
struct ast_channel * owner
Definition: core_unreal.h:93
Structure representing a snapshot of channel state.
static struct ast_multi_channel_blob * local_channel_optimization_blob(struct local_pvt *p, struct ast_json *json_object)
Definition: core_local.c:362
#define NULL
Definition: resample.c:96
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
struct ast_unreal_pvt base
Definition: core_local.c:225
#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_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
Add a ast_channel_snapshot to a ast_multi_channel_blob object.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
the local pvt structure for all channels
Definition: core_local.c:223
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A multi channel blob data structure for multi_channel_blob stasis messages.
Abstract JSON element (object, array, string, int, ...).

◆ local_pvt_destructor()

static void local_pvt_destructor ( void *  vdoomed)
static

Definition at line 846 of file core_local.c.

References local_pvt::action, ao2_cleanup, ast_bridge_features_destroy(), ast_unreal_destructor(), local_pvt::base, local_pvt::bridge, local_bridge::features, local_bridge::join, LOCAL_CALL_ACTION_BRIDGE, LOCAL_CALL_ACTION_DIALPLAN, LOCAL_CALL_ACTION_MASQUERADE, local_pvt::masq, local_bridge::swap, and local_pvt::type.

Referenced by local_alloc().

847 {
848  struct local_pvt *doomed = vdoomed;
849 
850  switch (doomed->type) {
852  break;
854  ao2_cleanup(doomed->action.bridge.join);
855  ao2_cleanup(doomed->action.bridge.swap);
857  break;
859  ao2_cleanup(doomed->action.masq);
860  break;
861  }
862  ast_unreal_destructor(&doomed->base);
863 }
struct ast_channel * swap
Definition: core_local.c:211
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
struct ast_unreal_pvt base
Definition: core_local.c:225
void ast_unreal_destructor(void *vdoomed)
struct ast_unreal_pvt destructor.
Definition: core_unreal.c:1099
struct ast_bridge_features * features
Definition: core_local.c:213
enum local_call_action type
Definition: core_local.c:234
union local_pvt::@376 action
struct ast_bridge * join
Definition: core_local.c:209
the local pvt structure for all channels
Definition: core_local.c:223
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_channel * masq
Definition: core_local.c:231
struct local_bridge bridge
Definition: core_local.c:229

◆ local_request()

static struct ast_channel * local_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  data,
int *  cause 
)
static

Part of PBX interface.

Definition at line 922 of file core_local.c.

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

923 {
924  struct ast_stream_topology *topology;
925  struct ast_channel *chan;
926 
928  if (!topology) {
929  return NULL;
930  }
931 
932  chan = local_request_with_stream_topology(type, topology, assignedids, requestor, data, cause);
933 
934  ast_stream_topology_free(topology);
935 
936  return chan;
937 }
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
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
const char * data
static struct ast_channel * local_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
Part of PBX interface.
Definition: core_local.c:940
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743

◆ local_request_with_stream_topology()

static struct ast_channel * local_request_with_stream_topology ( const char *  type,
struct ast_stream_topology topology,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  data,
int *  cause 
)
static

Part of PBX interface.

Definition at line 940 of file core_local.c.

References ao2_link, ao2_ref, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_log, AST_MEDIA_TYPE_AUDIO, ast_read_threadstorage_callid(), AST_STATE_DOWN, AST_STATE_RING, ast_str_alloca, ast_stream_get_formats(), ast_stream_get_state(), ast_stream_get_type(), ast_stream_set_formats(), AST_STREAM_STATE_REMOVED, ast_stream_topology_clone(), ast_stream_topology_get_count(), ast_stream_topology_get_stream(), ast_translator_best_choice(), ast_unreal_new_channels(), local_pvt::base, ast_channel::callid, ast_channel_tech::capabilities, local_pvt::context, local_pvt::exten, local_alloc(), LOG_WARNING, and NULL.

Referenced by local_request().

941 {
942  struct ast_stream_topology *audio_filtered_topology;
943  int i;
944  struct local_pvt *p;
945  struct ast_channel *chan;
947 
948  /* Create a copy of the requested topology as we don't have ownership over
949  * the one that is passed in.
950  */
951  audio_filtered_topology = ast_stream_topology_clone(topology);
952  if (!audio_filtered_topology) {
953  return NULL;
954  }
955 
956  /* Some users of Local channels request every known format in the
957  * universe. The core itself automatically pruned this list down to a single
958  * "best" format for audio in non-multistream. We replicate the logic here to
959  * do the same thing.
960  */
961  for (i = 0; i < ast_stream_topology_get_count(audio_filtered_topology); ++i) {
962  struct ast_stream *stream;
963  int res;
964  struct ast_format *tmp_fmt = NULL;
965  struct ast_format *best_audio_fmt = NULL;
966  struct ast_format_cap *caps;
967 
968  stream = ast_stream_topology_get_stream(audio_filtered_topology, i);
969 
970  if (ast_stream_get_type(stream) != AST_MEDIA_TYPE_AUDIO ||
972  continue;
973  }
974 
975  /* Respect the immutable state of formats on the stream and create a new
976  * format capabilities to replace the existing one.
977  */
979  if (!caps) {
980  ao2_ref(audio_filtered_topology, -1);
981  return NULL;
982  }
983 
984  /* The ast_translator_best_choice function treats both caps as const
985  * but does not declare it in the API.
986  */
988  &tmp_fmt, &best_audio_fmt);
989  if (res < 0) {
990  struct ast_str *tech_codecs = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
991  struct ast_str *request_codecs = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
992 
993  ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
995  ast_format_cap_get_names(ast_stream_get_formats(stream), &request_codecs));
996 
997  /* If there are no formats then we abort */
998  ao2_ref(caps, -1);
999  ao2_ref(audio_filtered_topology, -1);
1000  return NULL;
1001  }
1002 
1003  ast_format_cap_append(caps, best_audio_fmt, 0);
1004  ast_stream_set_formats(stream, caps);
1005 
1006  ao2_ref(caps, -1);
1007  ao2_ref(tmp_fmt, -1);
1008  ao2_ref(best_audio_fmt, -1);
1009  }
1010 
1011  /* Allocate a new private structure and then Asterisk channels */
1012  p = local_alloc(data, audio_filtered_topology);
1013  ao2_ref(audio_filtered_topology, -1);
1014  if (!p) {
1015  return NULL;
1016  }
1017  callid = ast_read_threadstorage_callid();
1019  p->exten, p->context, assignedids, requestor, callid);
1020  if (chan) {
1021  ao2_link(locals, p);
1022  }
1023  ao2_ref(p, -1); /* kill the ref from the alloc */
1024 
1025  return chan;
1026 }
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
char context[AST_MAX_CONTEXT]
Definition: core_local.c:236
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
#define LOG_WARNING
Definition: logger.h:274
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
Set when the stream has been removed/declined.
Definition: stream.h:78
Definition of a media format.
Definition: format.c:43
unsigned int ast_callid
Definition: logger.h:87
#define ast_str_alloca(init_len)
Definition: strings.h:800
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.
Definition: core_unreal.c:1162
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
int ast_translator_best_choice(struct ast_format_cap *dst_cap, struct ast_format_cap *src_cap, struct ast_format **dst_fmt_out, struct ast_format **src_fmt_out)
Chooses the best translation path.
Definition: translate.c:1385
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:1962
#define ast_log
Definition: astobj2.c:42
struct ast_unreal_pvt base
Definition: core_local.c:225
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
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
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
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
static struct ast_channel_tech local_tech
Definition: core_local.c:173
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_format_cap * capabilities
Definition: channel.h:633
static struct local_pvt * local_alloc(const char *data, struct ast_stream_topology *topology)
Create a call structure.
Definition: core_local.c:866
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
the local pvt structure for all channels
Definition: core_local.c:223
char exten[AST_MAX_EXTENSION]
Definition: core_local.c:238
static struct ao2_container * locals
Definition: core_local.c:138
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ local_setoption()

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

Definition at line 1177 of file core_local.c.

References AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, and ast_unreal_setoption().

1178 {
1179  switch (option) {
1182  return 0; /* local calls (like forwardings) are secure always */
1183  default:
1184  return ast_unreal_setoption(ast, option, data, datalen);
1185  }
1186 }
#define AST_OPTION_SECURE_MEDIA
int ast_unreal_setoption(struct ast_channel *chan, int option, void *data, int datalen)
Definition: core_unreal.c:97
#define AST_OPTION_SECURE_SIGNALING

◆ local_shutdown()

static void local_shutdown ( void  )
static

Definition at line 1122 of file core_local.c.

References ao2_cleanup, ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_local_bridge_type(), ast_local_optimization_begin_type(), ast_local_optimization_end_type(), ast_manager_unregister(), ast_channel_tech::capabilities, NULL, and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by ast_local_init().

1123 {
1124  /* First, take us out of the channel loop */
1126  ast_manager_unregister("LocalOptimizeAway");
1128 
1129  ao2_ref(locals, -1);
1130  locals = NULL;
1131 
1134 
1138 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1523
#define NULL
Definition: resample.c:96
static struct ast_cli_entry cli_local[]
Definition: core_local.c:1069
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static struct ast_channel_tech local_tech
Definition: core_local.c:173
struct ast_format_cap * capabilities
Definition: channel.h:633
struct stasis_message_type * ast_local_bridge_type(void)
Message type for when two local channel halves are bridged together.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct ao2_container * locals
Definition: core_local.c:138

◆ locals_cmp_cb()

static int locals_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1110 of file core_local.c.

References CMP_MATCH.

Referenced by ast_local_init().

1111 {
1112  return (obj == arg) ? CMP_MATCH : 0;
1113 }

◆ locals_show()

static char* locals_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

CLI command "local show channels".

Definition at line 1030 of file core_local.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli_args::argc, ast_channel_name(), ast_cli(), local_pvt::base, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_unreal_pvt::name, NULL, ast_unreal_pvt::owner, RESULT_SUCCESS, and ast_cli_entry::usage.

1031 {
1032  struct local_pvt *p;
1033  struct ao2_iterator it;
1034 
1035  switch (cmd) {
1036  case CLI_INIT:
1037  e->command = "local show channels";
1038  e->usage =
1039  "Usage: local show channels\n"
1040  " Provides summary information on active local proxy channels.\n";
1041  return NULL;
1042  case CLI_GENERATE:
1043  return NULL;
1044  }
1045 
1046  if (a->argc != 3) {
1047  return CLI_SHOWUSAGE;
1048  }
1049 
1050  if (ao2_container_count(locals) == 0) {
1051  ast_cli(a->fd, "No local channels in use\n");
1052  return RESULT_SUCCESS;
1053  }
1054 
1055  it = ao2_iterator_init(locals, 0);
1056  while ((p = ao2_iterator_next(&it))) {
1057  ao2_lock(p);
1058  ast_cli(a->fd, "%s -- %s\n",
1059  p->base.owner ? ast_channel_name(p->base.owner) : "<unowned>",
1060  p->base.name);
1061  ao2_unlock(p);
1062  ao2_ref(p, -1);
1063  }
1064  ao2_iterator_destroy(&it);
1065 
1066  return CLI_SUCCESS;
1067 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
const int argc
Definition: cli.h:160
struct ast_channel * owner
Definition: core_unreal.h:93
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct ast_unreal_pvt base
Definition: core_local.c:225
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define CLI_SHOWUSAGE
Definition: cli.h:45
char name[AST_MAX_EXTENSION+AST_MAX_CONTEXT+2]
Definition: core_unreal.h:99
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
the local pvt structure for all channels
Definition: core_local.c:223
const char * ast_channel_name(const struct ast_channel *chan)
static struct ao2_container * locals
Definition: core_local.c:138
#define RESULT_SUCCESS
Definition: cli.h:40
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ manager_optimize_away()

static int manager_optimize_away ( struct mansession s,
const struct message m 
)
static

Definition at line 1073 of file core_local.c.

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_channel_get_by_name(), ast_channel_tech_pvt(), ast_channel_unref, ast_clear_flag, ast_strlen_zero, AST_UNREAL_NO_OPTIMIZATION, astman_get_header(), astman_send_ack(), astman_send_error(), local_pvt::base, and NULL.

Referenced by ast_local_init().

1074 {
1075  const char *channel;
1076  struct local_pvt *p;
1077  struct local_pvt *found;
1078  struct ast_channel *chan;
1079 
1080  channel = astman_get_header(m, "Channel");
1081  if (ast_strlen_zero(channel)) {
1082  astman_send_error(s, m, "'Channel' not specified.");
1083  return 0;
1084  }
1085 
1086  chan = ast_channel_get_by_name(channel);
1087  if (!chan) {
1088  astman_send_error(s, m, "Channel does not exist.");
1089  return 0;
1090  }
1091 
1092  p = ast_channel_tech_pvt(chan);
1093  ast_channel_unref(chan);
1094 
1095  found = p ? ao2_find(locals, p, 0) : NULL;
1096  if (found) {
1097  ao2_lock(found);
1099  ao2_unlock(found);
1100  ao2_ref(found, -1);
1101  astman_send_ack(s, m, "Queued channel to be optimized away");
1102  } else {
1103  astman_send_error(s, m, "Unable to find channel");
1104  }
1105 
1106  return 0;
1107 }
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:2981
#define AST_UNREAL_NO_OPTIMIZATION
Definition: core_unreal.h:108
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define ao2_unlock(a)
Definition: astobj2.h:730
Definition: muted.c:95
#define NULL
Definition: resample.c:96
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_unreal_pvt base
Definition: core_local.c:225
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define ast_clear_flag(p, flag)
Definition: utils.h:77
the local pvt structure for all channels
Definition: core_local.c:223
static struct ao2_container * locals
Definition: core_local.c:138
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ publish_local_bridge_message()

static void publish_local_bridge_message ( struct local_pvt p)
static

Definition at line 540 of file core_local.c.

References ao2_cleanup, ao2_unlock, ast_channel_snapshot_get_latest(), ast_channel_topic(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_json_pack(), ast_json_unref(), ast_local_bridge_type(), ast_multi_channel_blob_add_channel(), ast_multi_channel_blob_create(), ast_test_flag, ast_unreal_lock_all(), AST_UNREAL_NO_OPTIMIZATION, local_pvt::base, local_pvt::context, end, local_pvt::exten, NULL, RAII_VAR, stasis_message_create(), and stasis_publish().

Referenced by local_call().

541 {
542  RAII_VAR(struct ast_multi_channel_blob *, multi_blob, NULL, ao2_cleanup);
543  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
544  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
545  RAII_VAR(struct ast_channel_snapshot *, one_snapshot, NULL, ao2_cleanup);
546  RAII_VAR(struct ast_channel_snapshot *, two_snapshot, NULL, ao2_cleanup);
547  struct ast_channel *owner;
548  struct ast_channel *chan;
549 
550  if (!ast_local_bridge_type()) {
551  return;
552  }
553 
554  ast_unreal_lock_all(&p->base, &chan, &owner);
555 
556  blob = ast_json_pack("{s: s, s: s, s: b}",
557  "context", p->context,
558  "exten", p->exten,
559  "can_optimize", !ast_test_flag(&p->base, AST_UNREAL_NO_OPTIMIZATION));
560  if (!blob) {
561  goto end;
562  }
563 
564  multi_blob = ast_multi_channel_blob_create(blob);
565  if (!multi_blob) {
566  goto end;
567  }
568 
570  if (!one_snapshot) {
571  goto end;
572  }
573 
575  if (!two_snapshot) {
576  goto end;
577  }
578 
579  ast_multi_channel_blob_add_channel(multi_blob, "1", one_snapshot);
580  ast_multi_channel_blob_add_channel(multi_blob, "2", two_snapshot);
581 
582  msg = stasis_message_create(ast_local_bridge_type(), multi_blob);
583  if (!msg) {
584  goto end;
585  }
586 
587  stasis_publish(ast_channel_topic(owner), msg);
588 
589 end:
590  ast_channel_unlock(owner);
591  ast_channel_unref(owner);
592 
593  ast_channel_unlock(chan);
594  ast_channel_unref(chan);
595 
596  ao2_unlock(&p->base);
597 }
Main Channel structure associated with a channel.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
char context[AST_MAX_CONTEXT]
Definition: core_local.c:236
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define ast_test_flag(p, flag)
Definition: utils.h:63
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Structure representing a snapshot of channel state.
#define AST_UNREAL_NO_OPTIMIZATION
Definition: core_unreal.h:108
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
struct ast_unreal_pvt base
Definition: core_local.c:225
#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_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
Add a ast_channel_snapshot to a ast_multi_channel_blob object.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
struct stasis_message_type * ast_local_bridge_type(void)
Message type for when two local channel halves are bridged together.
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A multi channel blob data structure for multi_channel_blob stasis messages.
char exten[AST_MAX_EXTENSION]
Definition: core_local.c:238
Abstract JSON element (object, array, string, int, ...).
struct ast_multi_channel_blob * ast_multi_channel_blob_create(struct ast_json *blob)
Create a ast_multi_channel_blob suitable for a stasis_message.
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

◆ STASIS_MESSAGE_TYPE_DEFN() [1/3]

STASIS_MESSAGE_TYPE_DEFN ( ast_local_bridge_type  ,
to_ami = local_message_to_ami 
)

Define local channel message types.

◆ STASIS_MESSAGE_TYPE_DEFN() [2/3]

STASIS_MESSAGE_TYPE_DEFN ( ast_local_optimization_begin_type  ,
to_ami = local_message_to_ami 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [3/3]

STASIS_MESSAGE_TYPE_DEFN ( ast_local_optimization_end_type  ,
to_ami = local_message_to_ami 
)

Variable Documentation

◆ cli_local

struct ast_cli_entry cli_local[]
static
Initial value:
= {
{ .handler = locals_show , .summary = "List status of local channels" ,},
}
static char * locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command "local show channels".
Definition: core_local.c:1030

Definition at line 1069 of file core_local.c.

◆ local_tech

struct ast_channel_tech local_tech
static

Definition at line 173 of file core_local.c.

◆ local_unreal_callbacks

struct ast_unreal_pvt_callbacks local_unreal_callbacks
Initial value:
= {
.optimization_started = local_optimization_started_cb,
.optimization_finished = local_optimization_finished_cb,
}
static void local_optimization_finished_cb(struct ast_unreal_pvt *base, int success, unsigned int id)
Callback for ast_unreal_pvt_callbacks optimization_finished_cb.
Definition: core_local.c:433
static void local_optimization_started_cb(struct ast_unreal_pvt *base, struct ast_channel *source, enum ast_unreal_channel_indicator dest, unsigned int id)
Callback for ast_unreal_pvt_callbacks optimization_started_cb.
Definition: core_local.c:390

Callbacks from the unreal core when channel optimization occurs.

Definition at line 167 of file core_local.c.

Referenced by local_alloc().

◆ locals

struct ao2_container* locals
static

Definition at line 138 of file core_local.c.

Referenced by attended_transfer_bridge().

◆ tdesc

const char tdesc[] = "Local Proxy Channel Driver"
static

Definition at line 136 of file core_local.c.