48 #include "asterisk/stasis_channels.h"
50 #include "asterisk/stasis_channels.h"
136 static const char tdesc[] =
"Local Proxy Channel Driver";
146 enum ast_unreal_channel_indicator dest,
unsigned int id);
148 static int local_setoption(
struct ast_channel *chan,
int option,
void *
data,
int datalen);
156 .to_ami = local_message_to_ami,
159 .to_ami = local_message_to_ami,
162 .to_ami = local_message_to_ami,
175 .description = tdesc,
193 .setoption = local_setoption,
199 LOCAL_CALL_ACTION_DIALPLAN,
201 LOCAL_CALL_ACTION_BRIDGE,
203 LOCAL_CALL_ACTION_MASQUERADE,
244 struct local_pvt *p = ast_channel_tech_pvt(chan);
260 ast_channel_unlock(base_chan);
265 ast_channel_unlock(base_owner);
271 ao2_unlock(&p->
base);
278 struct local_pvt *p = ast_channel_tech_pvt(ast);
286 found = p ? ao2_find(locals, p, 0) : NULL;
318 context = strchr(exten,
'@');
321 "Someone used Local/%s somewhere without a @context. This is bad.\n", data);
331 opts = strchr(context,
'/');
337 for (; (lp = ao2_iterator_next(&it));
ao2_ref(lp, -1)) {
339 if (!strcmp(exten, lp->
exten)
340 && !strcmp(context, lp->
context)) {
357 ast_debug(3,
"Checking if extension %s@%s exists (devicestate)\n", exten, context);
374 if (!local_one_snapshot) {
379 if (!local_two_snapshot) {
395 enum ast_unreal_channel_indicator dest,
unsigned int id)
413 payload = local_channel_optimization_blob(p, json_object);
421 if (!source_snapshot) {
454 payload = local_channel_optimization_blob(p, json_object);
480 if (!local_snapshot_one || !local_snapshot_two) {
487 if (!event_buffer || !local_channel_one || !local_channel_two) {
494 const char *dest_uniqueid;
497 if (source_snapshot) {
507 event =
"LocalOptimizationBegin";
511 ast_str_append(&event_buffer, 0,
"DestUniqueId: %s\r\n", dest_uniqueid);
514 event =
"LocalOptimizationEnd";
518 event =
"LocalBridge";
542 static void publish_local_bridge_message(
struct local_pvt *p)
592 ast_channel_unlock(owner);
595 ast_channel_unlock(chan);
598 ao2_unlock(&p->
base);
608 if (!ast || !bridge) {
613 ast_channel_lock(ast);
614 p = ast_channel_tech_pvt(ast);
615 ast_channel_unlock(ast);
617 found = p ? ao2_find(locals, p, 0) : NULL;
620 if (found->
type == LOCAL_CALL_ACTION_DIALPLAN
628 found->
type = LOCAL_CALL_ACTION_BRIDGE;
654 ast_channel_lock(ast);
655 p = ast_channel_tech_pvt(ast);
656 ast_channel_unlock(ast);
658 found = p ? ao2_find(locals, p, 0) : NULL;
661 if (found->
type == LOCAL_CALL_ACTION_DIALPLAN
666 found->
type = LOCAL_CALL_ACTION_MASQUERADE;
681 struct local_pvt *p = ast_channel_tech_pvt(ast);
689 const char *chan_cid;
698 ast_channel_unlock(ast);
708 if (!owner || !chan) {
720 if ((slash = strrchr(reduced_dest,
'/'))) {
728 ast_channel_unlock(owner);
730 chan_cid =
S_COR(ast_channel_caller(chan)->
id.
number.valid,
731 ast_channel_caller(chan)->
id.
number.str, NULL);
735 ast_channel_unlock(chan);
739 case LOCAL_CALL_ACTION_DIALPLAN:
741 ast_log(LOG_NOTICE,
"No such extension/context %s@%s while calling Local channel\n",
744 publish_local_bridge_message(p);
750 case LOCAL_CALL_ACTION_BRIDGE:
751 publish_local_bridge_message(p);
761 case LOCAL_CALL_ACTION_MASQUERADE:
762 publish_local_bridge_message(p);
790 ast_channel_unlock(chan);
800 ast_channel_unlock(owner);
801 ast_channel_lock(ast);
806 ast_channel_lock(ast);
815 struct local_pvt *p = ast_channel_tech_pvt(ast);
846 static void local_pvt_destructor(
void *vdoomed)
850 switch (doomed->
type) {
851 case LOCAL_CALL_ACTION_DIALPLAN:
853 case LOCAL_CALL_ACTION_BRIDGE:
858 case LOCAL_CALL_ACTION_MASQUERADE:
893 if ((opts = strrchr(parse,
'/'))) {
895 if (strchr(opts,
'n')) {
898 if (strchr(opts,
'j')) {
902 ast_log(LOG_ERROR,
"You must use the 'n' option with the 'j' option to enable the jitter buffer\n");
905 if (strchr(opts,
'm')) {
911 if ((context = strchr(parse,
'@'))) {
953 if (!audio_filtered_topology) {
981 ao2_ref(audio_filtered_topology, -1);
989 &tmp_fmt, &best_audio_fmt);
994 ast_log(LOG_WARNING,
"No translator path exists for channel type %s (native %s) to %s\n", type,
1000 ao2_ref(audio_filtered_topology, -1);
1014 ao2_ref(audio_filtered_topology, -1);
1038 e->
command =
"local show channels";
1040 "Usage: local show channels\n"
1041 " Provides summary information on active local proxy channels.\n";
1048 return CLI_SHOWUSAGE;
1052 ast_cli(a->fd,
"No local channels in use\n");
1053 return RESULT_SUCCESS;
1057 while ((p = ao2_iterator_next(&it))) {
1059 ast_cli(a->fd,
"%s -- %s\n",
1071 AST_CLI_DEFINE(
locals_show,
"List status of local channels"),
1074 static int manager_optimize_away(
struct mansession *s,
const struct message *m)
1076 const char *channel;
1082 if (ast_strlen_zero(channel)) {
1093 p = ast_channel_tech_pvt(chan);
1096 found = p ? ao2_find(locals, p, 0) : NULL;
1111 static int locals_cmp_cb(
void *obj,
void *arg,
int flags)
1121 static void local_shutdown(
void)
1165 ast_log(LOG_ERROR,
"Unable to register channel class 'Local'\n");
1176 int local_setoption(
struct ast_channel *ast,
int option,
void *
data,
int datalen)
1180 case AST_OPTION_SECURE_MEDIA:
Struct containing info for an AMI event to send out.
Main Channel structure associated with a channel.
Local proxy channel special access.
struct ast_channel_snapshot_base * base
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static void local_optimization_finished_cb(struct ast_unreal_pvt *base, int success, unsigned int id)
Callback for ast_unreal_pvt_callbacks optimization_finished.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
char context[AST_MAX_CONTEXT]
Structure that contains features information.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define ast_channel_unref(c)
Decrease channel reference count.
Support for translation of data formats. translate.c.
struct ast_channel * ast_local_get_peer(struct ast_channel *ast)
Get the other local channel in the pair.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
struct ast_unreal_pvt_callbacks * callbacks
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
char context[AST_MAX_CONTEXT]
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
descriptor for a cli entry.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
struct ast_channel * owner
int ast_unreal_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
int ast_json_is_true(const struct ast_json *value)
Check if value is JSON true.
Structure representing a snapshot of channel state.
#define AST_UNREAL_NO_OPTIMIZATION
Set when the stream has been removed/declined.
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.
struct ast_jb_conf jb_conf
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
Structure to pass both assignedid values to channel drivers.
struct ast_channel * swap
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.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
#define AST_UNREAL_CARETAKER_THREAD
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
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...
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
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 ...
static int local_hangup(struct ast_channel *ast)
Hangup a call through the local proxy channel.
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.
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
int ast_unreal_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
Move a channel from its current location to a new location.
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
void ast_stream_set_formats(struct ast_stream *stream, struct ast_format_cap *caps)
Set the current negotiated formats of a stream.
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
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.
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...
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.
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.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
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)
Part of PBX interface.
int ast_unreal_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
#define AST_UNREAL_MOH_INTERCEPT
struct ast_json * ast_json_null(void)
Get the JSON null value.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
int ast_local_init(void)
Initialize the local proxy channel.
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().
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)
General Asterisk PBX channel definitions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
struct ast_unreal_pvt base
void(*const optimization_started)(struct ast_unreal_pvt *p, struct ast_channel *source, enum ast_unreal_channel_indicator dest, unsigned int id)
Called when an optimization attempt has started.
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_unreal_destructor(void *vdoomed)
struct ast_unreal_pvt destructor.
static char * locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command "local show channels".
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.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
struct ast_bridge_features * features
#define AST_MAX_EXTENSION
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
int ast_unreal_setoption(struct ast_channel *chan, int option, void *data, int datalen)
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
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.
#define ast_debug(level,...)
Log a DEBUG message.
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Core PBX routines and definitions.
struct ast_channel * chan
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
Setup unreal owner and chan channels before initiating call.
struct ast_unreal_pvt_callbacks local_unreal_callbacks
Callbacks from the unreal core when channel optimization occurs.
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.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
enum local_call_action type
Structure that contains information about a bridge.
int ast_unreal_write(struct ast_channel *ast, struct ast_frame *f)
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 privat...
Support for dynamic strings.
int ast_unreal_digit_begin(struct ast_channel *ast, char digit)
#define ao2_unlink(container, obj)
Remove an object from a container.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
union local_pvt::@342 action
char name[AST_MAX_EXTENSION+AST_MAX_CONTEXT+2]
The base pvt structure for local channel derivatives.
STASIS_MESSAGE_TYPE_DEFN(ast_local_bridge_type,.to_ami=local_message_to_ami,)
Define local channel message types.
int ast_unreal_write_stream(struct ast_channel *ast, int stream_num, struct ast_frame *f)
struct ast_format_cap * capabilities
struct ast_bridge * bridge
int ast_unreal_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
#define AST_OPTION_SECURE_SIGNALING
static int local_devicestate(const char *data)
Adds devicestate to local channels.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
static struct local_pvt * local_alloc(const char *data, struct ast_stream_topology *topology)
Create a call structure.
struct ast_frame * ast_unreal_read(struct ast_channel *ast)
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().
Prototypes for public functions only of internal interest,.
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
struct stasis_message_type * ast_local_bridge_type(void)
Message type for when two local channel halves are bridged together.
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
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.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
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...
int ast_unreal_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
#define ast_channel_ref(c)
Increase channel reference count.
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...
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
the local pvt structure for all channels
Standard Command Line Interface.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
int ast_unreal_answer(struct ast_channel *ast)
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.
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.
A multi channel blob data structure for multi_channel_blob stasis messages.
int ast_answer(struct ast_channel *chan)
Answer a channel.
char exten[AST_MAX_EXTENSION]
Abstract JSON element (object, array, string, int, ...).
struct ast_channel * masq
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Callbacks that can be provided by concrete implementations of the unreal channel driver that will be ...
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
struct local_bridge bridge
int ast_unreal_hangup(struct ast_unreal_pvt *p, struct ast_channel *ast)
Hangup one end (maybe both ends) of an unreal channel derivative.
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
char exten[AST_MAX_EXTENSION]
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.
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.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_unreal_sendtext(struct ast_channel *ast, const char *text)
#define ao2_link(container, obj)
Add an object to a container.
Unreal channel derivative framework.