Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Macros | Functions | Variables
stasis_channels.c File Reference

Stasis Messages and Data Types for Channel Objects. More...

#include "asterisk.h"
#include "asterisk/astobj2.h"
#include "asterisk/json.h"
#include "asterisk/pbx.h"
#include "asterisk/bridge.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/translate.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/dial.h"
#include "asterisk/linkedlists.h"
#include "asterisk/utf8.h"
#include "asterisk/vector.h"
Include dependency graph for stasis_channels.c:

Go to the source code of this file.

Data Structures

struct  ast_multi_channel_blob
 A multi channel blob data structure for multi_channel_blob stasis messages. More...
 
struct  channel_role_snapshot
 A channel snapshot wrapper object used in ast_multi_channel_blob objects. More...
 
struct  dial_masquerade_datastore
 
struct  dial_target
 

Macros

#define NUM_MULTI_CHANNEL_BLOB_BUCKETS   7
 

Functions

static struct ast_manager_event_blobagent_login_to_ami (struct stasis_message *msg)
 
static struct ast_manager_event_blobagent_logoff_to_ami (struct stasis_message *msg)
 
static void ari_transfer_dtor (void *obj)
 
static struct ast_jsonari_transfer_to_json (struct stasis_message *msg, const struct stasis_message_sanitizer *sanitize)
 
struct ast_ari_transfer_messageast_ari_transfer_message_create (struct ast_channel *originating_chan, const char *referred_by, const char *exten, const char *protocol_id, struct ast_channel *dest, struct ast_refer_params *params, enum ast_control_transfer state)
 
struct stasis_messageast_channel_blob_create (struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
 Creates a ast_channel_blob message. More...
 
struct stasis_messageast_channel_blob_create_from_cache (const char *channel_id, struct stasis_message_type *type, struct ast_json *blob)
 Create a ast_channel_blob message, pulling channel state from the cache. More...
 
struct ao2_containerast_channel_cache_all (void)
 
struct ao2_containerast_channel_cache_by_name (void)
 Secondary channel cache, indexed by name. More...
 
void ast_channel_publish_blob (struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
 Publish a channel blob message. More...
 
void ast_channel_publish_cached_blob (struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
 Publish a channel blob message using the latest snapshot from the cache. More...
 
void ast_channel_publish_dial (struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
 Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels involved in a dial operation. More...
 
void ast_channel_publish_dial_forward (struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
 Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels involved in a dial operation that is forwarded. More...
 
static void ast_channel_publish_dial_internal (struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
 
void ast_channel_publish_final_snapshot (struct ast_channel *chan)
 Send the final channel snapshot for a channel, thus removing it from cache. More...
 
void ast_channel_publish_snapshot (struct ast_channel *chan)
 Publish a ast_channel_snapshot for a channel. More...
 
void ast_channel_publish_varset (struct ast_channel *chan, const char *name, const char *value)
 Publish a ast_channel_publish_varset for a channel. More...
 
int ast_channel_snapshot_caller_id_equal (const struct ast_channel_snapshot *old_snapshot, const struct ast_channel_snapshot *new_snapshot)
 Compares the callerid info of two snapshots. More...
 
int ast_channel_snapshot_cep_equal (const struct ast_channel_snapshot *old_snapshot, const struct ast_channel_snapshot *new_snapshot)
 Compares the context, exten and priority of two snapshots. More...
 
int ast_channel_snapshot_connected_line_equal (const struct ast_channel_snapshot *old_snapshot, const struct ast_channel_snapshot *new_snapshot)
 Compares the connected line info of two snapshots. More...
 
struct ast_channel_snapshotast_channel_snapshot_create (struct ast_channel *chan)
 Generate a snapshot of the channel state. This is an ao2 object, so ao2_cleanup() to deallocate. More...
 
struct ast_channel_snapshotast_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, so use ao2_cleanup() to deallocate. More...
 
struct ast_channel_snapshotast_channel_snapshot_get_latest_by_name (const char *name)
 Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object, so use ao2_cleanup() to deallocate. More...
 
void ast_channel_snapshot_invalidate_segment (struct ast_channel *chan, enum ast_channel_snapshot_segment_invalidation segment)
 Invalidate a channel snapshot segment from being reused. More...
 
struct ast_jsonast_channel_snapshot_to_json (const struct ast_channel_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
 Build a JSON object from a ast_channel_snapshot. More...
 
void ast_channel_stage_snapshot (struct ast_channel *chan)
 Set flag to indicate channel snapshot is being staged. More...
 
void ast_channel_stage_snapshot_done (struct ast_channel *chan)
 Clear flag to indicate channel snapshot is being staged, and publish snapshot. More...
 
struct stasis_topicast_channel_topic_all (void)
 A topic which publishes the events for all channels. More...
 
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. More...
 
struct ast_multi_channel_blobast_multi_channel_blob_create (struct ast_json *blob)
 Create a ast_multi_channel_blob suitable for a stasis_message. More...
 
struct ast_channel_snapshotast_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. More...
 
struct ao2_containerast_multi_channel_blob_get_channels (struct ast_multi_channel_blob *obj, const char *role)
 Retrieve all channel snapshots associated with a specific role from a ast_multi_channel_blob. More...
 
struct ast_jsonast_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. More...
 
int ast_stasis_channels_init (void)
 Initialize the stasis channel topic and message types. More...
 
static void channel_blob_dtor (void *obj)
 
static struct ast_jsonchannel_blob_to_json (struct stasis_message *message, const char *type, const struct stasis_message_sanitizer *sanitize)
 
static int channel_role_cmp_cb (void *obj, void *arg, int flags)
 
static int channel_role_hash_cb (const void *obj, const int flags)
 
static void channel_role_snapshot_dtor (void *obj)
 
static struct ast_channel_snapshot_basechannel_snapshot_base_create (struct ast_channel *chan)
 
static void channel_snapshot_base_dtor (void *obj)
 
static struct ast_channel_snapshot_bridgechannel_snapshot_bridge_create (struct ast_channel *chan)
 
static struct ast_channel_snapshot_callerchannel_snapshot_caller_create (struct ast_channel *chan)
 
static void channel_snapshot_caller_dtor (void *obj)
 
static int channel_snapshot_cmp_cb (void *obj, void *arg, int flags)
 
static struct ast_channel_snapshot_connectedchannel_snapshot_connected_create (struct ast_channel *chan)
 
static struct ast_channel_snapshot_dialplanchannel_snapshot_dialplan_create (struct ast_channel *chan)
 
static void channel_snapshot_dialplan_dtor (void *obj)
 
static void channel_snapshot_dtor (void *obj)
 
static struct ast_channel_snapshot_hangupchannel_snapshot_hangup_create (struct ast_channel *chan)
 
static int channel_snapshot_hash_cb (const void *obj, const int flags)
 
static struct ast_channel_snapshot_peerchannel_snapshot_peer_create (struct ast_channel *chan)
 
static int channel_snapshot_uniqueid_cmp_cb (void *obj, void *arg, int flags)
 
static int channel_snapshot_uniqueid_hash_cb (const void *obj, const int flags)
 
static struct ast_channel_snapshot_updatechannel_snapshot_update_create (struct ast_channel *chan)
 
static void channel_snapshot_update_dtor (void *obj)
 
static struct stasis_messagecreate_channel_blob_message (struct ast_channel_snapshot *snapshot, struct stasis_message_type *type, struct ast_json *blob)
 
static void dial_masquerade_breakdown (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
 
static void dial_masquerade_caller_datastore_destroy (void *data)
 
static struct dial_masquerade_datastoredial_masquerade_datastore_add (struct ast_channel *chan, struct dial_masquerade_datastore *masq_data)
 
static struct dial_masquerade_datastoredial_masquerade_datastore_alloc (void)
 
static void dial_masquerade_datastore_cleanup (struct dial_masquerade_datastore *masq_data)
 
static void dial_masquerade_datastore_destroy (void *data)
 
static void dial_masquerade_datastore_dtor (void *vdoomed)
 
static struct ast_datastoredial_masquerade_datastore_find (struct ast_channel *chan)
 
static void dial_masquerade_datastore_remove_chan (struct dial_masquerade_datastore *masq_data, struct ast_channel *chan)
 
static void dial_masquerade_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
 
static void dial_target_free (struct dial_target *doomed)
 
static struct ast_jsondial_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static struct ast_jsondtmf_end_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static struct ast_jsonhangup_request_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static struct ast_jsonhold_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static void multi_channel_blob_dtor (void *obj)
 
static void publish_message_for_channel_topics (struct stasis_message *message, struct ast_channel *chan)
 
static void remove_dial_masquerade (struct ast_channel *peer)
 
static void remove_dial_masquerade_caller (struct ast_channel *caller)
 
static int set_dial_masquerade (struct ast_channel *caller, struct ast_channel *peer, const char *dialstring)
 
static void stasis_channels_cleanup (void)
 
static const char * state2str (enum ast_control_transfer state)
 
static struct ast_manager_event_blobtalking_start_to_ami (struct stasis_message *msg)
 
static struct ast_jsontalking_start_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static struct ast_manager_event_blobtalking_stop_to_ami (struct stasis_message *msg)
 
static struct ast_jsontalking_stop_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static struct ast_jsontone_detect_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static struct ast_jsonunhold_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
static struct ast_manager_event_blobvarset_to_ami (struct stasis_message *msg)
 
static struct ast_jsonvarset_to_json (struct stasis_message *message, const struct stasis_message_sanitizer *sanitize)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_agent_login_type,.to_ami=agent_login_to_ami,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_agent_logoff_type,.to_ami=agent_logoff_to_ami,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_chanspy_start_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_chanspy_stop_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_dial_type,.to_json=dial_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_dtmf_begin_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_dtmf_end_type,.to_json=dtmf_end_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_fax_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_flash_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_hangup_handler_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_hangup_request_type,.to_json=hangup_request_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_hold_type,.to_json=hold_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_masquerade_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_mixmonitor_mute_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_mixmonitor_start_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_mixmonitor_stop_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_moh_start_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_moh_stop_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_snapshot_type)
 Define channel message types. More...
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_talking_start,.to_ami=talking_start_to_ami,.to_json=talking_start_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_talking_stop,.to_ami=talking_stop_to_ami,.to_json=talking_stop_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_tone_detect,.to_json=tone_detect_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_transfer_request_type,.to_json=ari_transfer_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_unhold_type,.to_json=unhold_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_varset_type,.to_ami=varset_to_ami,.to_json=varset_to_json,)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_channel_wink_type)
 

Variables

static struct ao2_containerchannel_cache
 
static struct ao2_containerchannel_cache_by_name
 
static struct stasis_topicchannel_topic_all
 
static const struct ast_datastore_info dial_masquerade_caller_info
 
static const struct ast_datastore_info dial_masquerade_info
 

Detailed Description

Stasis Messages and Data Types for Channel Objects.

Author
Matt Jordan <mjordan@digium.com> 

Definition in file stasis_channels.c.

Macro Definition Documentation

◆ NUM_MULTI_CHANNEL_BLOB_BUCKETS

#define NUM_MULTI_CHANNEL_BLOB_BUCKETS   7

Definition at line 138 of file stasis_channels.c.

Function Documentation

◆ agent_login_to_ami()

static struct ast_manager_event_blob * agent_login_to_ami ( struct stasis_message msg)
static

Definition at line 1267 of file stasis_channels.c.

1268{
1269 struct ast_str *channel_string;
1270 struct ast_channel_blob *obj = stasis_message_data(msg);
1271 const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));
1272 struct ast_manager_event_blob *ev;
1273
1274 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1275 if (!channel_string) {
1276 return NULL;
1277 }
1278
1280 "%s"
1281 "Agent: %s\r\n",
1282 ast_str_buffer(channel_string), agent);
1283 ast_free(channel_string);
1284 return ev;
1285}
#define ast_free(a)
Definition: astmm.h:180
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
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:10237
#define EVENT_FLAG_AGENT
Definition: manager.h:80
#define NULL
Definition: resample.c:96
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
Blob of data associated with a channel.
struct ast_channel_snapshot * snapshot
struct ast_json * blob
Struct containing info for an AMI event to send out.
Definition: manager.h:503
Support for dynamic strings.
Definition: strings.h:623

References ast_free, ast_json_object_get(), ast_json_string_get(), ast_manager_build_channel_state_string(), ast_manager_event_blob_create(), ast_str_buffer(), ast_channel_blob::blob, EVENT_FLAG_AGENT, NULL, ast_channel_blob::snapshot, and stasis_message_data().

◆ agent_logoff_to_ami()

static struct ast_manager_event_blob * agent_logoff_to_ami ( struct stasis_message msg)
static

Definition at line 1287 of file stasis_channels.c.

1288{
1289 struct ast_str *channel_string;
1290 struct ast_channel_blob *obj = stasis_message_data(msg);
1291 const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));
1292 long logintime = ast_json_integer_get(ast_json_object_get(obj->blob, "logintime"));
1293 struct ast_manager_event_blob *ev;
1294
1295 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1296 if (!channel_string) {
1297 return NULL;
1298 }
1299
1301 "%s"
1302 "Agent: %s\r\n"
1303 "Logintime: %ld\r\n",
1304 ast_str_buffer(channel_string), agent, logintime);
1305 ast_free(channel_string);
1306 return ev;
1307}
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition: json.c:332

References ast_free, ast_json_integer_get(), ast_json_object_get(), ast_json_string_get(), ast_manager_build_channel_state_string(), ast_manager_event_blob_create(), ast_str_buffer(), ast_channel_blob::blob, EVENT_FLAG_AGENT, NULL, ast_channel_blob::snapshot, and stasis_message_data().

◆ ari_transfer_dtor()

static void ari_transfer_dtor ( void *  obj)
static

Definition at line 1752 of file stasis_channels.c.

1753{
1754 struct ast_ari_transfer_message *msg = obj;
1755
1756 ao2_cleanup(msg->source);
1759 ao2_cleanup(msg->dest);
1761 ao2_cleanup(msg->dest_peer);
1763 ast_free(msg->referred_by);
1764 ast_free(msg->protocol_id);
1765}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
Message published during an "ARI" transfer.
struct ast_refer_params * refer_params
struct ast_channel_snapshot * dest_peer
struct ast_bridge_snapshot * dest_bridge
struct ast_channel_snapshot * source_peer
struct ast_bridge_snapshot * source_bridge
struct ast_channel_snapshot * dest
struct ast_channel_snapshot * source

References ao2_cleanup, ast_free, ast_ari_transfer_message::dest, ast_ari_transfer_message::dest_bridge, ast_ari_transfer_message::dest_peer, ast_ari_transfer_message::protocol_id, ast_ari_transfer_message::refer_params, ast_ari_transfer_message::referred_by, ast_ari_transfer_message::source, ast_ari_transfer_message::source_bridge, and ast_ari_transfer_message::source_peer.

Referenced by ast_ari_transfer_message_create().

◆ ari_transfer_to_json()

static struct ast_json * ari_transfer_to_json ( struct stasis_message msg,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1661 of file stasis_channels.c.

1663{
1664 struct ast_json *json_channel, *res;
1665 struct ast_json *refer_json, *referred_json, *dest_json;
1666 const struct timeval *tv = stasis_message_timestamp(msg);
1667 struct ast_ari_transfer_message *transfer_msg = stasis_message_data(msg);
1668
1669 dest_json = ast_json_pack("{s: s, s: s}",
1670 "protocol_id", transfer_msg->protocol_id,
1671 "destination", transfer_msg->destination);
1672 if (!dest_json) {
1673 return NULL;
1674 }
1675
1676 if (AST_VECTOR_SIZE(transfer_msg->refer_params) > 0) {
1677 struct ast_json *params = ast_json_array_create();
1678 if (!params) {
1679 return NULL;
1680 }
1681 for (int i = 0; i < AST_VECTOR_SIZE(transfer_msg->refer_params); ++i) {
1682 struct ast_refer_param param = AST_VECTOR_GET(transfer_msg->refer_params, i);
1683 ast_json_array_append(params, ast_json_pack("{s: s, s: s}",
1684 "parameter_name", param.param_name,
1685 "parameter_value", param.param_value));
1686 }
1687 ast_json_object_set(dest_json, "additional_protocol_params", params);
1688 }
1689
1690 refer_json = ast_json_pack("{s: o}",
1691 "requested_destination", dest_json);
1692 if (!refer_json) {
1693 return NULL;
1694 }
1695 if (transfer_msg->dest) {
1696 struct ast_json *dest_chan_json;
1697
1698 dest_chan_json = ast_channel_snapshot_to_json(transfer_msg->dest, sanitize);
1699 ast_json_object_set(refer_json, "destination_channel", dest_chan_json);
1700 }
1701 if (transfer_msg->dest_peer) {
1702 struct ast_json *peer_chan_json;
1703
1704 peer_chan_json = ast_channel_snapshot_to_json(transfer_msg->dest_peer, sanitize);
1705 ast_json_object_set(refer_json, "connected_channel", peer_chan_json);
1706 }
1707 if (transfer_msg->dest_bridge) {
1708 struct ast_json *dest_bridge_json;
1709
1710 dest_bridge_json = ast_bridge_snapshot_to_json(transfer_msg->dest_bridge, sanitize);
1711 ast_json_object_set(refer_json, "bridge", dest_bridge_json);
1712 }
1713
1714 json_channel = ast_channel_snapshot_to_json(transfer_msg->source, sanitize);
1715 if (!json_channel) {
1716 return NULL;
1717 }
1718
1719 referred_json = ast_json_pack("{s: o}",
1720 "source_channel", json_channel);
1721 if (!referred_json) {
1722 return NULL;
1723 }
1724 if (transfer_msg->source_peer) {
1725 struct ast_json *peer_chan_json;
1726
1727 peer_chan_json = ast_channel_snapshot_to_json(transfer_msg->source_peer, sanitize);
1728 ast_json_object_set(referred_json, "connected_channel", peer_chan_json);
1729 }
1730 if (transfer_msg->source_bridge) {
1731 struct ast_json *source_bridge_json;
1732
1733 source_bridge_json = ast_bridge_snapshot_to_json(transfer_msg->source_bridge, sanitize);
1734 ast_json_object_set(referred_json, "bridge", source_bridge_json);
1735 }
1736
1737 res = ast_json_pack("{s: s, s: o, s: o, s: o}",
1738 "type", "ChannelTransfer",
1739 "timestamp", ast_json_timeval(*tv, NULL),
1740 "refer_to", refer_json,
1741 "referred_by", referred_json);
1742 if (!res) {
1743 return NULL;
1744 }
1745
1746 if (transfer_msg->state != AST_TRANSFER_INVALID) {
1747 ast_json_object_set(res, "state", ast_json_string_create(state2str(transfer_msg->state)));
1748 }
1749 return res;
1750}
@ AST_TRANSFER_INVALID
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:278
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:378
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
struct ast_json * ast_json_timeval(const struct timeval tv, const char *zone)
Construct a timeval as JSON.
Definition: json.c:670
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:362
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:414
const struct timeval * stasis_message_timestamp(const struct stasis_message *msg)
Get the time when a message was created.
struct ast_json * ast_bridge_snapshot_to_json(const struct ast_bridge_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_bridge_snapshot.
struct ast_json * ast_channel_snapshot_to_json(const struct ast_channel_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_channel_snapshot.
static const char * state2str(enum ast_control_transfer state)
char destination[AST_MAX_EXTENSION]
enum ast_control_transfer state
Abstract JSON element (object, array, string, int, ...).
const char * param_value
Definition: refer.h:83
const char * param_name
Definition: refer.h:82
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

References ast_bridge_snapshot_to_json(), ast_channel_snapshot_to_json(), ast_json_array_append(), ast_json_array_create(), ast_json_object_set(), ast_json_pack(), ast_json_string_create(), ast_json_timeval(), AST_TRANSFER_INVALID, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_ari_transfer_message::dest, ast_ari_transfer_message::dest_bridge, ast_ari_transfer_message::dest_peer, ast_ari_transfer_message::destination, NULL, ast_refer_param::param_name, ast_refer_param::param_value, ast_ari_transfer_message::protocol_id, ast_ari_transfer_message::refer_params, ast_ari_transfer_message::source, ast_ari_transfer_message::source_bridge, ast_ari_transfer_message::source_peer, stasis_message_data(), stasis_message_timestamp(), ast_ari_transfer_message::state, and state2str().

◆ ast_ari_transfer_message_create()

struct ast_ari_transfer_message * ast_ari_transfer_message_create ( struct ast_channel originating_chan,
const char *  referred_by,
const char *  exten,
const char *  protocol_id,
struct ast_channel dest,
struct ast_refer_params params,
enum ast_control_transfer  state 
)

Definition at line 1767 of file stasis_channels.c.

1770{
1771 struct ast_ari_transfer_message *msg;
1772 msg = ao2_alloc(sizeof(*msg), ari_transfer_dtor);
1773 if (!msg) {
1774 return NULL;
1775 }
1776
1777 msg->refer_params = params;
1778 ao2_ref(msg->refer_params, +1);
1779
1780 msg->state = state;
1781
1782 ast_channel_lock(originating_chan);
1783 msg->source = ao2_bump(ast_channel_snapshot(originating_chan));
1784 ast_channel_unlock(originating_chan);
1785 if (!msg->source) {
1786 ao2_cleanup(msg);
1787 return NULL;
1788 }
1789
1790 if (dest) {
1794 if (!msg->dest) {
1795 ao2_cleanup(msg);
1796 return NULL;
1797 }
1798 }
1799
1801 if (!msg->referred_by) {
1802 ao2_cleanup(msg);
1803 return NULL;
1804 }
1805 ast_copy_string(msg->destination, exten, sizeof(msg->destination));
1807 if (!msg->protocol_id) {
1808 ao2_cleanup(msg);
1809 return NULL;
1810 }
1811
1812 return msg;
1813}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
enum cc_state state
Definition: ccss.c:399
#define ast_channel_lock(chan)
Definition: channel.h:2972
struct ast_channel_snapshot * ast_channel_snapshot(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2973
static void ari_transfer_dtor(void *obj)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

References ao2_alloc, ao2_bump, ao2_cleanup, ao2_ref, ari_transfer_dtor(), ast_channel_lock, ast_channel_snapshot(), ast_channel_unlock, ast_copy_string(), ast_strdup, ast_ari_transfer_message::dest, ast_ari_transfer_message::destination, NULL, ast_ari_transfer_message::protocol_id, ast_ari_transfer_message::refer_params, ast_ari_transfer_message::referred_by, ast_ari_transfer_message::source, ast_ari_transfer_message::state, and state.

Referenced by ast_refer_notify_transfer_request().

◆ ast_channel_publish_dial_internal()

static void ast_channel_publish_dial_internal ( struct ast_channel caller,
struct ast_channel peer,
struct ast_channel forwarded,
const char *  dialstring,
const char *  dialstatus,
const char *  forward 
)
static

Definition at line 628 of file stasis_channels.c.

631{
632 struct ast_multi_channel_blob *payload;
633 struct stasis_message *msg;
634 struct ast_json *blob;
635 struct ast_channel_snapshot *peer_snapshot;
636
637 if (!ast_channel_dial_type()) {
638 return;
639 }
640
641 ast_assert(peer != NULL);
642
643 blob = ast_json_pack("{s: s, s: s, s: s}",
644 "dialstatus", S_OR(dialstatus, ""),
645 "forward", S_OR(forward, ""),
646 "dialstring", S_OR(dialstring, ""));
647 if (!blob) {
648 return;
649 }
650 payload = ast_multi_channel_blob_create(blob);
651 ast_json_unref(blob);
652 if (!payload) {
653 return;
654 }
655
656 if (caller) {
657 struct ast_channel_snapshot *caller_snapshot;
658
660 if (ast_strlen_zero(dialstatus)) {
662 } else {
663 caller_snapshot = ast_channel_snapshot_create(caller);
664 }
666 if (!caller_snapshot) {
667 ao2_ref(payload, -1);
668 return;
669 }
670 ast_multi_channel_blob_add_channel(payload, "caller", caller_snapshot);
671 ao2_ref(caller_snapshot, -1);
672 }
673
675 if (ast_strlen_zero(dialstatus)) {
677 } else {
678 peer_snapshot = ast_channel_snapshot_create(peer);
679 }
681 if (!peer_snapshot) {
682 ao2_ref(payload, -1);
683 return;
684 }
685 ast_multi_channel_blob_add_channel(payload, "peer", peer_snapshot);
686 ao2_ref(peer_snapshot, -1);
687
688 if (forwarded) {
689 struct ast_channel_snapshot *forwarded_snapshot;
690
691 ast_channel_lock(forwarded);
692 forwarded_snapshot = ast_channel_snapshot_create(forwarded);
693 ast_channel_unlock(forwarded);
694 if (!forwarded_snapshot) {
695 ao2_ref(payload, -1);
696 return;
697 }
698 ast_multi_channel_blob_add_channel(payload, "forwarded", forwarded_snapshot);
699 ao2_ref(forwarded_snapshot, -1);
700 }
701
703 ao2_ref(payload, -1);
704 if (msg) {
706 ao2_ref(msg, -1);
707 }
708}
const char * ast_channel_uniqueid(const struct ast_channel *chan)
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.
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,...
struct ast_channel_snapshot * ast_channel_snapshot_create(struct ast_channel *chan)
Generate a snapshot of the channel state. This is an ao2 object, so ao2_cleanup() to deallocate.
struct stasis_message_type * ast_channel_dial_type(void)
Message type for when a channel dials another channel.
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.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
static void publish_message_for_channel_topics(struct stasis_message *message, struct ast_channel *chan)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_peer * peer
struct ast_channel_snapshot_caller * caller
A multi channel blob data structure for multi_channel_blob stasis messages.
#define ast_assert(a)
Definition: utils.h:739

References ao2_ref, ast_assert, ast_channel_dial_type(), ast_channel_lock, ast_channel_snapshot_create(), ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), ast_channel_unlock, ast_json_pack(), ast_json_unref(), ast_multi_channel_blob_add_channel(), ast_multi_channel_blob_create(), ast_strlen_zero(), ast_channel_snapshot::caller, NULL, ast_channel_snapshot::peer, publish_message_for_channel_topics(), S_OR, and stasis_message_create().

Referenced by ast_channel_publish_dial_forward(), dial_masquerade_breakdown(), and dial_masquerade_fixup().

◆ ast_channel_snapshot_caller_id_equal()

int ast_channel_snapshot_caller_id_equal ( const struct ast_channel_snapshot old_snapshot,
const struct ast_channel_snapshot new_snapshot 
)

Compares the callerid info of two snapshots.

Since
12
Parameters
old_snapshotOld snapshot
new_snapshotNew snapshot
Return values
True(non-zero) if callerid are identical.
False(zero) if callerid changed.

Definition at line 1381 of file stasis_channels.c.

1384{
1385 ast_assert(old_snapshot != NULL);
1386 ast_assert(new_snapshot != NULL);
1387 return strcmp(old_snapshot->caller->number, new_snapshot->caller->number) == 0 &&
1388 strcmp(old_snapshot->caller->name, new_snapshot->caller->name) == 0;
1389}
const ast_string_field number
const ast_string_field name

References ast_assert, ast_channel_snapshot::caller, ast_channel_snapshot_caller::name, NULL, and ast_channel_snapshot_caller::number.

Referenced by channel_callerid(), and channel_new_callerid().

◆ ast_channel_snapshot_cep_equal()

int ast_channel_snapshot_cep_equal ( const struct ast_channel_snapshot old_snapshot,
const struct ast_channel_snapshot new_snapshot 
)

Compares the context, exten and priority of two snapshots.

Since
12
Parameters
old_snapshotOld snapshot
new_snapshotNew snapshot
Return values
True(non-zero) if context, exten or priority are identical.
False(zero) if context, exten and priority changed.

Definition at line 1360 of file stasis_channels.c.

1363{
1364 ast_assert(old_snapshot != NULL);
1365 ast_assert(new_snapshot != NULL);
1366
1367 /* We actually get some snapshots with CEP set, but before the
1368 * application is set. Since empty application is invalid, we treat
1369 * setting the application from nothing as a CEP change.
1370 */
1371 if (ast_strlen_zero(old_snapshot->dialplan->appl) &&
1372 !ast_strlen_zero(new_snapshot->dialplan->appl)) {
1373 return 0;
1374 }
1375
1376 return old_snapshot->dialplan->priority == new_snapshot->dialplan->priority &&
1377 strcmp(old_snapshot->dialplan->context, new_snapshot->dialplan->context) == 0 &&
1378 strcmp(old_snapshot->dialplan->exten, new_snapshot->dialplan->exten) == 0;
1379}
const ast_string_field context
const ast_string_field exten
const ast_string_field appl
struct ast_channel_snapshot_dialplan * dialplan

References ast_channel_snapshot_dialplan::appl, ast_assert, ast_strlen_zero(), ast_channel_snapshot_dialplan::context, ast_channel_snapshot::dialplan, ast_channel_snapshot_dialplan::exten, NULL, and ast_channel_snapshot_dialplan::priority.

Referenced by channel_dialplan(), and channel_newexten().

◆ ast_channel_snapshot_connected_line_equal()

int ast_channel_snapshot_connected_line_equal ( const struct ast_channel_snapshot old_snapshot,
const struct ast_channel_snapshot new_snapshot 
)

Compares the connected line info of two snapshots.

Since
13.1.0
Parameters
old_snapshotOld snapshot
new_snapshotNew snapshot
Return values
True(non-zero) if callerid are identical.
False(zero) if callerid changed.

Definition at line 1391 of file stasis_channels.c.

1394{
1395 ast_assert(old_snapshot != NULL);
1396 ast_assert(new_snapshot != NULL);
1397 return strcmp(old_snapshot->connected->number, new_snapshot->connected->number) == 0 &&
1398 strcmp(old_snapshot->connected->name, new_snapshot->connected->name) == 0;
1399}
struct ast_channel_snapshot_connected * connected

References ast_assert, ast_channel_snapshot::connected, ast_channel_snapshot_connected::name, NULL, and ast_channel_snapshot_connected::number.

Referenced by channel_connected_line(), and channel_new_connected_line().

◆ ast_channel_snapshot_to_json()

struct ast_json * ast_channel_snapshot_to_json ( const struct ast_channel_snapshot snapshot,
const struct stasis_message_sanitizer sanitize 
)

Build a JSON object from a ast_channel_snapshot.

Parameters
snapshotThe snapshot to convert to JSON
sanitizeThe message sanitizer to use on the snapshot
Returns
JSON object representing channel snapshot.
Return values
NULLon error

Definition at line 1309 of file stasis_channels.c.

1312{
1313 struct ast_json *json_chan;
1314
1315 if (snapshot == NULL
1316 || (sanitize
1317 && sanitize->channel_snapshot
1318 && sanitize->channel_snapshot(snapshot))) {
1319 return NULL;
1320 }
1321
1322 json_chan = ast_json_pack(
1323 /* Broken up into groups for readability */
1324 "{ s: s, s: s, s: s, s: s,"
1325 " s: o, s: o, s: s,"
1326 " s: o, s: o, s: s }",
1327 /* First line */
1328 "id", snapshot->base->uniqueid,
1329 "name", snapshot->base->name,
1330 "state", ast_state2str(snapshot->state),
1331 "protocol_id", snapshot->base->protocol_id,
1332 /* Second line */
1333 "caller", ast_json_name_number(
1334 snapshot->caller->name, snapshot->caller->number),
1335 "connected", ast_json_name_number(
1336 snapshot->connected->name, snapshot->connected->number),
1337 "accountcode", snapshot->base->accountcode,
1338 /* Third line */
1339 "dialplan", ast_json_dialplan_cep_app(
1340 snapshot->dialplan->context, snapshot->dialplan->exten, snapshot->dialplan->priority,
1341 snapshot->dialplan->appl, snapshot->dialplan->data),
1342 "creationtime", ast_json_timeval(snapshot->base->creationtime, NULL),
1343 "language", snapshot->base->language);
1344
1345 if (!ast_strlen_zero(snapshot->caller->rdnis)) {
1346 ast_json_object_set(json_chan, "caller_rdnis", ast_json_string_create(snapshot->caller->rdnis));
1347 }
1348
1349 if (snapshot->ari_vars && !AST_LIST_EMPTY(snapshot->ari_vars)) {
1350 ast_json_object_set(json_chan, "channelvars", ast_json_channel_vars(snapshot->ari_vars));
1351 }
1352
1353 if (!ast_strlen_zero(snapshot->base->tenantid)) {
1354 ast_json_object_set(json_chan, "tenantid", ast_json_string_create(snapshot->base->tenantid));
1355 }
1356
1357 return json_chan;
1358}
const char * ast_state2str(enum ast_channel_state state)
Gives the string form of a given channel state.
Definition: channel.c:635
struct ast_json * ast_json_name_number(const char *name, const char *number)
Common JSON rendering functions for common 'objects'.
Definition: json.c:646
struct ast_json * ast_json_dialplan_cep_app(const char *context, const char *exten, int priority, const char *app_name, const char *app_data)
Construct a context/exten/priority/application/application_data as JSON.
Definition: json.c:653
struct ast_json * ast_json_channel_vars(struct varshead *channelvars)
Construct a JSON object from a ast_var_t list.
Definition: json.c:941
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
const ast_string_field language
const ast_string_field tenantid
const ast_string_field accountcode
const ast_string_field uniqueid
const ast_string_field name
const ast_string_field rdnis
const ast_string_field data
struct varshead * ari_vars
struct ast_channel_snapshot_base * base
enum ast_channel_state state
int(* channel_snapshot)(const struct ast_channel_snapshot *snapshot)
Callback which determines whether a channel should be sanitized from a message based on the channel's...
Definition: stasis.h:221

References ast_channel_snapshot_base::accountcode, ast_channel_snapshot_dialplan::appl, ast_channel_snapshot::ari_vars, ast_json_channel_vars(), ast_json_dialplan_cep_app(), ast_json_name_number(), ast_json_object_set(), ast_json_pack(), ast_json_string_create(), ast_json_timeval(), AST_LIST_EMPTY, ast_state2str(), ast_strlen_zero(), ast_channel_snapshot::base, ast_channel_snapshot::caller, stasis_message_sanitizer::channel_snapshot, ast_channel_snapshot::connected, ast_channel_snapshot_dialplan::context, ast_channel_snapshot_base::creationtime, ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, ast_channel_snapshot_dialplan::exten, ast_channel_snapshot_base::language, ast_channel_snapshot_caller::name, ast_channel_snapshot_connected::name, ast_channel_snapshot_base::name, NULL, ast_channel_snapshot_caller::number, ast_channel_snapshot_connected::number, ast_channel_snapshot_dialplan::priority, ast_channel_snapshot_caller::rdnis, ast_channel_snapshot::state, ast_channel_snapshot_base::tenantid, and ast_channel_snapshot_base::uniqueid.

Referenced by ari_channels_handle_originate_with_id(), ari_channels_handle_snoop_channel(), ari_transfer_to_json(), ast_ari_channels_create(), ast_ari_channels_get(), ast_ari_channels_list(), AST_TEST_DEFINE(), attended_transfer_to_json(), blind_transfer_to_json(), channel_blob_to_json(), channel_callerid(), channel_connected_line(), channel_destroyed_event(), channel_dialplan(), channel_to_json(), dial_to_json(), dtmf_end_to_json(), hold_to_json(), multi_user_event_to_json(), rtcp_report_to_json(), simple_bridge_channel_event(), simple_channel_event(), stasis_app_exec(), stasis_end_to_json(), stasis_start_to_json(), and unhold_to_json().

◆ ast_stasis_channels_init()

int ast_stasis_channels_init ( void  )

Initialize the stasis channel topic and message types.

Return values
0on success
Non-zeroon error

Definition at line 1911 of file stasis_channels.c.

1912{
1913 int res = 0;
1914
1916
1917 channel_topic_all = stasis_topic_create("channel:all");
1918 if (!channel_topic_all) {
1919 return -1;
1920 }
1921
1925 if (!channel_cache) {
1926 return -1;
1927 }
1928
1932 if (!channel_cache_by_name) {
1933 return -1;
1934 }
1935
1962
1963 return res;
1964}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition: astobj2.h:365
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
#define AST_NUM_CHANNEL_BUCKETS
Definition: channel.h:157
struct stasis_message_type * ast_channel_mixmonitor_mute_type(void)
Message type for muting or unmuting mixmonitor on a channel.
struct stasis_message_type * ast_channel_masquerade_type(void)
Message type for when a channel is being masqueraded.
struct stasis_message_type * ast_channel_hold_type(void)
Message type for when a channel is placed on hold.
struct stasis_message_type * ast_channel_talking_start(void)
Message type for a channel starting talking.
struct stasis_message_type * ast_channel_chanspy_start_type(void)
Message type for when a channel starts spying on another channel.
struct stasis_message_type * ast_channel_chanspy_stop_type(void)
Message type for when a channel stops spying on another channel.
struct stasis_message_type * ast_channel_talking_stop(void)
Message type for a channel stopping talking.
struct stasis_message_type * ast_channel_dtmf_begin_type(void)
Message type for when DTMF begins on a channel.
struct stasis_message_type * ast_channel_mixmonitor_stop_type(void)
Message type for stopping mixmonitor on a channel.
struct stasis_message_type * ast_channel_tone_detect(void)
Message type for a channel tone detection.
struct stasis_message_type * ast_channel_varset_type(void)
Message type for when a variable is set on a channel.
struct stasis_message_type * ast_channel_hangup_handler_type(void)
Message type for hangup handler related actions.
struct stasis_message_type * ast_channel_agent_logoff_type(void)
Message type for agent logoff on a channel.
struct stasis_message_type * ast_channel_moh_stop_type(void)
Message type for stopping music on hold on a channel.
struct stasis_message_type * ast_channel_unhold_type(void)
Message type for when a channel is removed from hold.
struct stasis_message_type * ast_channel_hangup_request_type(void)
Message type for when a hangup is requested on a channel.
struct stasis_message_type * ast_channel_agent_login_type(void)
Message type for agent login on a channel.
struct stasis_message_type * ast_channel_flash_type(void)
Message type for when a hook flash occurs on a channel.
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
struct stasis_message_type * ast_channel_fax_type(void)
Message type for a fax operation.
struct stasis_message_type * ast_channel_dtmf_end_type(void)
Message type for when DTMF ends on a channel.
struct stasis_message_type * ast_channel_wink_type(void)
Message type for when a wink occurs on a channel.
struct stasis_message_type * ast_channel_transfer_request_type(void)
struct stasis_message_type * ast_channel_moh_start_type(void)
Message type for starting music on hold on a channel.
struct stasis_message_type * ast_channel_mixmonitor_start_type(void)
Message type for starting mixmonitor on a channel.
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
Definition: stasis.c:644
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
static int channel_snapshot_cmp_cb(void *obj, void *arg, int flags)
static int channel_snapshot_uniqueid_cmp_cb(void *obj, void *arg, int flags)
static struct ao2_container * channel_cache_by_name
static struct stasis_topic * channel_topic_all
static int channel_snapshot_uniqueid_hash_cb(const void *obj, const int flags)
static struct ao2_container * channel_cache
static int channel_snapshot_hash_cb(const void *obj, const int flags)
static void stasis_channels_cleanup(void)

References AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_container_alloc_hash, ast_channel_agent_login_type(), ast_channel_agent_logoff_type(), ast_channel_chanspy_start_type(), ast_channel_chanspy_stop_type(), ast_channel_dial_type(), ast_channel_dtmf_begin_type(), ast_channel_dtmf_end_type(), ast_channel_fax_type(), ast_channel_flash_type(), ast_channel_hangup_handler_type(), ast_channel_hangup_request_type(), ast_channel_hold_type(), ast_channel_masquerade_type(), ast_channel_mixmonitor_mute_type(), ast_channel_mixmonitor_start_type(), ast_channel_mixmonitor_stop_type(), ast_channel_moh_start_type(), ast_channel_moh_stop_type(), ast_channel_snapshot_type(), ast_channel_talking_start(), ast_channel_talking_stop(), ast_channel_tone_detect(), ast_channel_transfer_request_type(), ast_channel_unhold_type(), ast_channel_varset_type(), ast_channel_wink_type(), AST_NUM_CHANNEL_BUCKETS, ast_register_cleanup(), channel_cache, channel_cache_by_name, channel_snapshot_cmp_cb(), channel_snapshot_hash_cb(), channel_snapshot_uniqueid_cmp_cb(), channel_snapshot_uniqueid_hash_cb(), channel_topic_all, NULL, stasis_channels_cleanup(), STASIS_MESSAGE_TYPE_INIT, and stasis_topic_create().

Referenced by ast_channels_init().

◆ channel_blob_dtor()

static void channel_blob_dtor ( void *  obj)
static

Definition at line 621 of file stasis_channels.c.

622{
623 struct ast_channel_blob *event = obj;
624 ao2_cleanup(event->snapshot);
625 ast_json_unref(event->blob);
626}
Definition: astman.c:222

References ao2_cleanup, and ast_json_unref().

Referenced by create_channel_blob_message().

◆ channel_blob_to_json()

static struct ast_json * channel_blob_to_json ( struct stasis_message message,
const char *  type,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1401 of file stasis_channels.c.

1405{
1406 struct ast_json *to_json;
1407 struct ast_channel_blob *channel_blob = stasis_message_data(message);
1408 struct ast_json *blob = channel_blob->blob;
1409 struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
1410 const struct timeval *tv = stasis_message_timestamp(message);
1411 int res = 0;
1412
1413 if (blob == NULL || ast_json_is_null(blob)) {
1414 to_json = ast_json_object_create();
1415 } else {
1416 /* blobs are immutable, so shallow copies are fine */
1417 to_json = ast_json_copy(blob);
1418 }
1419 if (!to_json) {
1420 return NULL;
1421 }
1422
1423 res |= ast_json_object_set(to_json, "type", ast_json_string_create(type));
1424 res |= ast_json_object_set(to_json, "timestamp",
1425 ast_json_timeval(*tv, NULL));
1426
1427 /* For global channel messages, the snapshot is optional */
1428 if (snapshot) {
1429 struct ast_json *json_channel;
1430
1431 json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
1432 if (!json_channel) {
1433 ast_json_unref(to_json);
1434 return NULL;
1435 }
1436
1437 res |= ast_json_object_set(to_json, "channel", json_channel);
1438 }
1439
1440 if (res != 0) {
1441 ast_json_unref(to_json);
1442 return NULL;
1443 }
1444
1445 return to_json;
1446}
static const char type[]
Definition: chan_ooh323.c:109
struct ast_json * ast_json_object_create(void)
Create a new JSON object.
Definition: json.c:399
struct ast_json * ast_json_copy(const struct ast_json *value)
Copy a JSON value, but not its children.
Definition: json.c:637
int ast_json_is_null(const struct ast_json *value)
Check if value is JSON null.
Definition: json.c:273

References ast_channel_snapshot_to_json(), ast_json_copy(), ast_json_is_null(), ast_json_object_create(), ast_json_object_set(), ast_json_string_create(), ast_json_timeval(), ast_json_unref(), ast_channel_blob::blob, NULL, ast_channel_blob::snapshot, stasis_message_data(), stasis_message_timestamp(), and type.

Referenced by hangup_request_to_json(), talking_start_to_json(), talking_stop_to_json(), tone_detect_to_json(), and varset_to_json().

◆ channel_role_cmp_cb()

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

Definition at line 846 of file stasis_channels.c.

847{
848 const struct channel_role_snapshot *object_left = obj;
849 const struct channel_role_snapshot *object_right = arg;
850 const char *right_key = arg;
851 int cmp;
852
853 switch (flags & OBJ_SEARCH_MASK) {
855 right_key = object_right->role;
856 case OBJ_SEARCH_KEY:
857 cmp = strcasecmp(object_left->role, right_key);
858 break;
860 cmp = strncasecmp(object_left->role, right_key, strlen(right_key));
861 break;
862 default:
863 cmp = 0;
864 break;
865 }
866 if (cmp) {
867 return 0;
868 }
869 return CMP_MATCH;
870}
@ CMP_MATCH
Definition: astobj2.h:1027
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
@ OBJ_SEARCH_MASK
Search option field mask.
Definition: astobj2.h:1072
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
A channel snapshot wrapper object used in ast_multi_channel_blob objects.

References CMP_MATCH, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, OBJ_SEARCH_PARTIAL_KEY, and channel_role_snapshot::role.

Referenced by ast_multi_channel_blob_create(), and ast_multi_channel_blob_get_channels().

◆ channel_role_hash_cb()

static int channel_role_hash_cb ( const void *  obj,
const int  flags 
)
static

Definition at line 876 of file stasis_channels.c.

877{
878 const struct channel_role_snapshot *object = obj;
879 const char *key;
880
881 switch (flags & OBJ_SEARCH_MASK) {
882 case OBJ_SEARCH_KEY:
883 key = obj;
884 break;
886 key = object->role;
887 break;
888 default:
889 ast_assert(0);
890 return 0;
891 }
892 return ast_str_case_hash(key);
893}
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303

References ast_assert, ast_str_case_hash(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by ast_multi_channel_blob_create().

◆ channel_role_snapshot_dtor()

static void channel_role_snapshot_dtor ( void *  obj)
static

Definition at line 975 of file stasis_channels.c.

976{
977 struct channel_role_snapshot *role_snapshot = obj;
978
979 ao2_cleanup(role_snapshot->snapshot);
980}
struct ast_channel_snapshot * snapshot

References ao2_cleanup, and channel_role_snapshot::snapshot.

Referenced by ast_multi_channel_blob_add_channel().

◆ channel_snapshot_base_create()

static struct ast_channel_snapshot_base * channel_snapshot_base_create ( struct ast_channel chan)
static

Definition at line 287 of file stasis_channels.c.

288{
289 struct ast_channel_snapshot_base *snapshot;
290
291 snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_base_dtor,
293 if (!snapshot) {
294 return NULL;
295 }
296
297 if (ast_string_field_init(snapshot, 256) || ast_string_field_init_extended(snapshot, protocol_id)) {
298 ao2_ref(snapshot, -1);
299 return NULL;
300 }
301
309
310 snapshot->creationtime = ast_channel_creationtime(chan);
312
313 if (ast_channel_tech(chan)->get_pvt_uniqueid) {
314 ast_string_field_set(snapshot, protocol_id, ast_channel_tech(chan)->get_pvt_uniqueid(chan));
315 }
316
317 return snapshot;
318}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:348
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:497
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_tenantid(const struct ast_channel *chan)
const char * ast_channel_accountcode(const struct ast_channel *chan)
const char * ast_channel_userfield(const struct ast_channel *chan)
struct timeval ast_channel_creationtime(struct ast_channel *chan)
const char * ast_channel_language(const struct ast_channel *chan)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
static const char name[]
Definition: format_mp3.c:68
static void channel_snapshot_base_dtor(void *obj)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_init_extended(x, field)
Initialize an extended string field.
Definition: stringfields.h:401
Structure containing base information for a channel snapshot.
const ast_string_field userfield

References accountcode, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_channel_accountcode(), ast_channel_creationtime(), ast_channel_language(), ast_channel_name(), ast_channel_tech(), ast_channel_tenantid(), ast_channel_uniqueid(), ast_channel_userfield(), ast_string_field_init, ast_string_field_init_extended, ast_string_field_set, channel_snapshot_base_dtor(), ast_channel_snapshot_base::creationtime, language, name, NULL, ast_channel_tech::properties, ast_channel_snapshot_base::tech_properties, ast_channel_snapshot_base::tenantid, type, ast_channel_snapshot_base::uniqueid, and ast_channel_snapshot_base::userfield.

Referenced by ast_channel_snapshot_create().

◆ channel_snapshot_base_dtor()

static void channel_snapshot_base_dtor ( void *  obj)
static

Definition at line 280 of file stasis_channels.c.

281{
282 struct ast_channel_snapshot_base *snapshot = obj;
283
285}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ast_string_field_free_memory.

Referenced by channel_snapshot_base_create().

◆ channel_snapshot_bridge_create()

static struct ast_channel_snapshot_bridge * channel_snapshot_bridge_create ( struct ast_channel chan)
static

Definition at line 404 of file stasis_channels.c.

405{
406 const char *uniqueid = "";
407 struct ast_bridge *bridge;
408 struct ast_channel_snapshot_bridge *snapshot;
409
410 bridge = ast_channel_get_bridge(chan);
411 if (bridge && !ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
412 uniqueid = bridge->uniqueid;
413 }
414 ao2_cleanup(bridge);
415
416 snapshot = ao2_alloc_options(sizeof(*snapshot) + strlen(uniqueid) + 1, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
417 if (!snapshot) {
418 return NULL;
419 }
420
421 strcpy(snapshot->id, uniqueid); /* Safe */
422
423 return snapshot;
424}
@ AST_BRIDGE_FLAG_INVISIBLE
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10539
Structure that contains information about a bridge.
Definition: bridge.h:353
const ast_string_field uniqueid
Definition: bridge.h:405
struct ast_flags feature_flags
Definition: bridge.h:373
Structure containing bridge information for a channel snapshot.
#define ast_test_flag(p, flag)
Definition: utils.h:63

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, AST_BRIDGE_FLAG_INVISIBLE, ast_channel_get_bridge(), ast_test_flag, ast_bridge::feature_flags, ast_channel_snapshot_bridge::id, NULL, and ast_bridge::uniqueid.

Referenced by ast_channel_snapshot_create().

◆ channel_snapshot_caller_create()

static struct ast_channel_snapshot_caller * channel_snapshot_caller_create ( struct ast_channel chan)
static

Definition at line 347 of file stasis_channels.c.

348{
349 struct ast_channel_snapshot_caller *snapshot;
350
351 snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_caller_dtor,
353 if (!snapshot) {
354 return NULL;
355 }
356
357 if (ast_string_field_init(snapshot, 256)) {
358 ao2_ref(snapshot, -1);
359 return NULL;
360 }
361
362 ast_string_field_set(snapshot, name,
363 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""));
365 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""));
367 S_COR(ast_channel_caller(chan)->id.subaddress.valid, ast_channel_caller(chan)->id.subaddress.str, ""));
368 ast_string_field_set(snapshot, ani,
369 S_COR(ast_channel_caller(chan)->ani.number.valid, ast_channel_caller(chan)->ani.number.str, ""));
370
371 ast_string_field_set(snapshot, rdnis,
372 S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, ""));
373
374 ast_string_field_set(snapshot, dnid,
375 S_OR(ast_channel_dialed(chan)->number.str, ""));
377 S_COR(ast_channel_dialed(chan)->subaddress.valid, ast_channel_dialed(chan)->subaddress.str, ""));
378
379 snapshot->pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
380
381 return snapshot;
382}
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1788
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void channel_snapshot_caller_dtor(void *obj)
#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:87
Structure containing caller information for a channel snapshot.
const ast_string_field dialed_subaddr
const ast_string_field ani
const ast_string_field subaddr
const ast_string_field dnid
char * str
Subscriber phone number (Malloced)
Definition: channel.h:388
Number structure.
Definition: app_followme.c:157

References ast_channel_snapshot_caller::ani, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_channel_caller(), ast_channel_dialed(), ast_channel_redirecting(), ast_party_id_presentation(), ast_string_field_init, ast_string_field_set, channel_snapshot_caller_dtor(), ast_channel_snapshot_caller::dialed_subaddr, ast_channel_snapshot_caller::dnid, name, NULL, ast_channel_snapshot_caller::pres, ast_channel_snapshot_caller::rdnis, S_COR, S_OR, ast_party_dialed::str, and ast_channel_snapshot_caller::subaddr.

Referenced by ast_channel_snapshot_create().

◆ channel_snapshot_caller_dtor()

static void channel_snapshot_caller_dtor ( void *  obj)
static

Definition at line 340 of file stasis_channels.c.

341{
342 struct ast_channel_snapshot_caller *snapshot = obj;
343
345}

References ast_string_field_free_memory.

Referenced by channel_snapshot_caller_create().

◆ channel_snapshot_cmp_cb()

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

Definition at line 186 of file stasis_channels.c.

187{
188 const struct ast_channel_snapshot *object_left = obj;
189 const struct ast_channel_snapshot *object_right = arg;
190 const char *right_key = arg;
191 int cmp;
192
193 switch (flags & OBJ_SEARCH_MASK) {
195 right_key = object_right->base->name;
196 case OBJ_SEARCH_KEY:
197 cmp = strcasecmp(object_left->base->name, right_key);
198 break;
200 cmp = strncasecmp(object_left->base->name, right_key, strlen(right_key));
201 break;
202 default:
203 cmp = 0;
204 break;
205 }
206 if (cmp) {
207 return 0;
208 }
209 return CMP_MATCH;
210}
struct ast_flags flags

References ast_channel_snapshot::base, CMP_MATCH, ast_channel_snapshot::flags, ast_channel_snapshot_base::name, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by ast_multi_channel_blob_get_channels(), and ast_stasis_channels_init().

◆ channel_snapshot_connected_create()

static struct ast_channel_snapshot_connected * channel_snapshot_connected_create ( struct ast_channel chan)
static

Definition at line 384 of file stasis_channels.c.

385{
386 const char *name = S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, "");
387 const char *number = S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, "");
388 size_t name_len = strlen(name) + 1;
389 size_t number_len = strlen(number) + 1;
390 struct ast_channel_snapshot_connected *snapshot;
391
392 snapshot = ao2_alloc_options(sizeof(*snapshot) + name_len + number_len, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
393 if (!snapshot) {
394 return NULL;
395 }
396
397 strcpy(snapshot->name, name); /* Safe */
398 snapshot->number = snapshot->name + name_len;
399 ast_copy_string(snapshot->number, number, number_len); /* Safe */
400
401 return snapshot;
402}
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
Structure containing connected information for a channel snapshot.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_channel_connected(), ast_copy_string(), ast_channel_snapshot_connected::name, name, NULL, ast_channel_snapshot_connected::number, and S_COR.

Referenced by ast_channel_snapshot_create().

◆ channel_snapshot_dialplan_create()

static struct ast_channel_snapshot_dialplan * channel_snapshot_dialplan_create ( struct ast_channel chan)
static

Definition at line 433 of file stasis_channels.c.

434{
435 struct ast_channel_snapshot_dialplan *snapshot;
436
437 snapshot = ao2_alloc_options(sizeof(*snapshot), channel_snapshot_dialplan_dtor,
439 if (!snapshot) {
440 return NULL;
441 }
442
443 if (ast_string_field_init(snapshot, 256)) {
444 ao2_ref(snapshot, -1);
445 return NULL;
446 }
447
448 if (ast_channel_appl(chan)) {
450 }
451 if (ast_channel_data(chan)) {
453 }
456 snapshot->priority = ast_channel_priority(chan);
457
458 return snapshot;
459}
const char * ast_channel_data(const struct ast_channel *chan)
int ast_channel_priority(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
const char * ast_channel_appl(const struct ast_channel *chan)
const char * ast_channel_exten(const struct ast_channel *chan)
static void channel_snapshot_dialplan_dtor(void *obj)
Structure containing dialplan information for a channel snapshot.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, ast_channel_snapshot_dialplan::appl, ast_channel_appl(), ast_channel_context(), ast_channel_data(), ast_channel_exten(), ast_channel_priority(), ast_string_field_init, ast_string_field_set, channel_snapshot_dialplan_dtor(), voicemailpwcheck::context, ast_channel_snapshot_dialplan::data, ast_channel_snapshot_dialplan::exten, NULL, and ast_channel_snapshot_dialplan::priority.

Referenced by ast_channel_snapshot_create().

◆ channel_snapshot_dialplan_dtor()

static void channel_snapshot_dialplan_dtor ( void *  obj)
static

Definition at line 426 of file stasis_channels.c.

427{
428 struct ast_channel_snapshot_dialplan *snapshot = obj;
429
431}

References ast_string_field_free_memory.

Referenced by channel_snapshot_dialplan_create().

◆ channel_snapshot_dtor()

static void channel_snapshot_dtor ( void *  obj)
static

Definition at line 265 of file stasis_channels.c.

266{
267 struct ast_channel_snapshot *snapshot = obj;
268
269 ao2_cleanup(snapshot->base);
270 ao2_cleanup(snapshot->peer);
271 ao2_cleanup(snapshot->caller);
272 ao2_cleanup(snapshot->connected);
273 ao2_cleanup(snapshot->bridge);
274 ao2_cleanup(snapshot->dialplan);
275 ao2_cleanup(snapshot->hangup);
276 ao2_cleanup(snapshot->manager_vars);
277 ao2_cleanup(snapshot->ari_vars);
278}
struct varshead * manager_vars
struct ast_channel_snapshot_bridge * bridge
struct ast_channel_snapshot_hangup * hangup

References ao2_cleanup, ast_channel_snapshot::ari_vars, ast_channel_snapshot::base, ast_channel_snapshot::bridge, ast_channel_snapshot::caller, ast_channel_snapshot::connected, ast_channel_snapshot::dialplan, ast_channel_snapshot::hangup, ast_channel_snapshot::manager_vars, and ast_channel_snapshot::peer.

Referenced by ast_channel_snapshot_create().

◆ channel_snapshot_hangup_create()

static struct ast_channel_snapshot_hangup * channel_snapshot_hangup_create ( struct ast_channel chan)
static

Definition at line 461 of file stasis_channels.c.

462{
463 const char *hangupsource = S_OR(ast_channel_hangupsource(chan), "");
464 struct ast_channel_snapshot_hangup *snapshot;
465
466 snapshot = ao2_alloc_options(sizeof(*snapshot) + strlen(hangupsource) + 1, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
467 if (!snapshot) {
468 return NULL;
469 }
470
471 snapshot->cause = ast_channel_hangupcause(chan);
472 strcpy(snapshot->source, hangupsource); /* Safe */
473
474 return snapshot;
475}
const char * ast_channel_hangupsource(const struct ast_channel *chan)
int ast_channel_hangupcause(const struct ast_channel *chan)
Structure containing hangup information for a channel snapshot.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_channel_hangupcause(), ast_channel_hangupsource(), ast_channel_snapshot_hangup::cause, NULL, S_OR, and ast_channel_snapshot_hangup::source.

Referenced by ast_channel_snapshot_create().

◆ channel_snapshot_hash_cb()

static int channel_snapshot_hash_cb ( const void *  obj,
const int  flags 
)
static

Definition at line 163 of file stasis_channels.c.

164{
165 const struct ast_channel_snapshot *object = obj;
166 const char *key;
167
168 switch (flags & OBJ_SEARCH_MASK) {
169 case OBJ_SEARCH_KEY:
170 key = obj;
171 break;
173 key = object->base->name;
174 break;
175 default:
176 ast_assert(0);
177 return 0;
178 }
179 return ast_str_case_hash(key);
180}

References ast_assert, ast_str_case_hash(), ast_channel_snapshot::flags, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by ast_multi_channel_blob_get_channels(), and ast_stasis_channels_init().

◆ channel_snapshot_peer_create()

static struct ast_channel_snapshot_peer * channel_snapshot_peer_create ( struct ast_channel chan)
static

Definition at line 320 of file stasis_channels.c.

321{
322 const char *linkedid = S_OR(ast_channel_linkedid(chan), "");
323 const char *peeraccount = S_OR(ast_channel_peeraccount(chan), "");
324 size_t linkedid_len = strlen(linkedid) + 1;
325 size_t peeraccount_len = strlen(peeraccount) + 1;
326 struct ast_channel_snapshot_peer *snapshot;
327
328 snapshot = ao2_alloc_options(sizeof(*snapshot) + linkedid_len + peeraccount_len, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
329 if (!snapshot) {
330 return NULL;
331 }
332
333 strcpy(snapshot->account, peeraccount); /* Safe */
334 snapshot->linkedid = snapshot->account + peeraccount_len;
335 ast_copy_string(snapshot->linkedid, linkedid, linkedid_len); /* Safe */
336
337 return snapshot;
338}
const char * ast_channel_linkedid(const struct ast_channel *chan)
const char * ast_channel_peeraccount(const struct ast_channel *chan)
Structure containing peer information for a channel snapshot.

References ast_channel_snapshot_peer::account, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_channel_linkedid(), ast_channel_peeraccount(), ast_copy_string(), ast_channel_snapshot_peer::linkedid, NULL, and S_OR.

Referenced by ast_channel_snapshot_create().

◆ channel_snapshot_uniqueid_cmp_cb()

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

Definition at line 239 of file stasis_channels.c.

240{
241 const struct ast_channel_snapshot *object_left = obj;
242 const struct ast_channel_snapshot *object_right = arg;
243 const char *right_key = arg;
244 int cmp;
245
246 switch (flags & OBJ_SEARCH_MASK) {
248 right_key = object_right->base->uniqueid;
249 case OBJ_SEARCH_KEY:
250 cmp = strcasecmp(object_left->base->uniqueid, right_key);
251 break;
253 cmp = strncasecmp(object_left->base->uniqueid, right_key, strlen(right_key));
254 break;
255 default:
256 cmp = 0;
257 break;
258 }
259 if (cmp) {
260 return 0;
261 }
262 return CMP_MATCH;
263}

References ast_channel_snapshot::base, CMP_MATCH, ast_channel_snapshot::flags, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, OBJ_SEARCH_PARTIAL_KEY, and ast_channel_snapshot_base::uniqueid.

Referenced by ast_stasis_channels_init().

◆ channel_snapshot_uniqueid_hash_cb()

static int channel_snapshot_uniqueid_hash_cb ( const void *  obj,
const int  flags 
)
static

Definition at line 216 of file stasis_channels.c.

217{
218 const struct ast_channel_snapshot *object = obj;
219 const char *key;
220
221 switch (flags & OBJ_SEARCH_MASK) {
222 case OBJ_SEARCH_KEY:
223 key = obj;
224 break;
226 key = object->base->uniqueid;
227 break;
228 default:
229 ast_assert(0);
230 return 0;
231 }
232 return ast_str_case_hash(key);
233}

References ast_assert, ast_str_case_hash(), ast_channel_snapshot::flags, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by ast_stasis_channels_init().

◆ channel_snapshot_update_create()

static struct ast_channel_snapshot_update * channel_snapshot_update_create ( struct ast_channel chan)
static

Definition at line 592 of file stasis_channels.c.

593{
595
598 if (!update) {
599 return NULL;
600 }
601
602 update->old_snapshot = ao2_bump(ast_channel_snapshot(chan));
603 update->new_snapshot = ast_channel_snapshot_create(chan);
604 if (!update->new_snapshot) {
605 ao2_ref(update, -1);
606 return NULL;
607 }
608
609 return update;
610}
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
Definition: codec_g726.c:367
static void channel_snapshot_update_dtor(void *obj)
Structure representing a change of snapshot of channel state.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_bump, ao2_ref, ast_channel_snapshot(), ast_channel_snapshot_create(), channel_snapshot_update_dtor(), NULL, and update().

Referenced by ast_channel_publish_final_snapshot(), and ast_channel_publish_snapshot().

◆ channel_snapshot_update_dtor()

static void channel_snapshot_update_dtor ( void *  obj)
static

Definition at line 584 of file stasis_channels.c.

585{
587
588 ao2_cleanup(update->old_snapshot);
589 ao2_cleanup(update->new_snapshot);
590}

References ao2_cleanup, and update().

Referenced by channel_snapshot_update_create().

◆ create_channel_blob_message()

static struct stasis_message * create_channel_blob_message ( struct ast_channel_snapshot snapshot,
struct stasis_message_type type,
struct ast_json blob 
)
static

Definition at line 771 of file stasis_channels.c.

774{
775 struct stasis_message *msg;
776 struct ast_channel_blob *obj;
777
778 obj = ao2_alloc(sizeof(*obj), channel_blob_dtor);
779 if (!obj) {
780 return NULL;
781 }
782
783 if (snapshot) {
784 obj->snapshot = snapshot;
785 ao2_ref(obj->snapshot, +1);
786 }
787 if (!blob) {
789 }
790 obj->blob = ast_json_ref(blob);
791
792 msg = stasis_message_create(type, obj);
793 ao2_cleanup(obj);
794 return msg;
795}
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
static void channel_blob_dtor(void *obj)

References ao2_alloc, ao2_cleanup, ao2_ref, ast_json_null(), ast_json_ref(), ast_channel_blob::blob, channel_blob_dtor(), NULL, ast_channel_blob::snapshot, stasis_message_create(), and type.

Referenced by ast_channel_blob_create(), and ast_channel_blob_create_from_cache().

◆ dial_masquerade_breakdown()

static void dial_masquerade_breakdown ( void *  data,
struct ast_channel old_chan,
struct ast_channel new_chan 
)
static

Definition at line 2128 of file stasis_channels.c.

2129{
2130 struct dial_masquerade_datastore *masq_data = data;
2131 struct dial_target *cur;
2132
2133 ao2_lock(masq_data);
2134
2135 if (!masq_data->caller) {
2136 ao2_unlock(masq_data);
2137 return;
2138 }
2139
2140 if (masq_data->caller == new_chan) {
2141 /*
2142 * The caller channel is being masqueraded into.
2143 * The masquerade is likely because of a blonde transfer.
2144 */
2145 ast_debug(1, "Caller channel %s being masqueraded into by %s (is_empty:%d)\n",
2146 ast_channel_name(old_chan), ast_channel_name(new_chan),
2147 AST_LIST_EMPTY(&masq_data->dialed_peers));
2148 AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
2150 cur->dialstring, "NOANSWER", NULL);
2152 cur->dialstring, NULL, NULL);
2153 }
2154
2155 ao2_unlock(masq_data);
2156 return;
2157 }
2158
2159 /*
2160 * One of the peer channels is being masqueraded into.
2161 * The masquerade is likely because of a call pickup.
2162 */
2163 AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
2164 if (cur->peer == new_chan) {
2165 ast_debug(1, "Peer channel %s being masqueraded into by %s\n",
2166 ast_channel_name(old_chan), ast_channel_name(new_chan));
2167 ast_channel_publish_dial_internal(masq_data->caller, old_chan, NULL,
2168 cur->dialstring, "CANCEL", NULL);
2169 ast_channel_publish_dial_internal(masq_data->caller, new_chan, NULL,
2170 cur->dialstring, NULL, NULL);
2171 break;
2172 }
2173 }
2174
2175 ao2_unlock(masq_data);
2176}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
static void ast_channel_publish_dial_internal(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
struct ast_channel * caller
struct dial_masquerade_datastore::@401 dialed_peers
struct ast_channel * peer
struct dial_target::@400 list

References ao2_lock, ao2_unlock, ast_channel_name(), ast_channel_publish_dial_internal(), ast_debug, AST_LIST_EMPTY, AST_LIST_TRAVERSE, dial_masquerade_datastore::caller, dial_masquerade_datastore::dialed_peers, dial_target::dialstring, dial_target::list, NULL, and dial_target::peer.

◆ dial_masquerade_caller_datastore_destroy()

static void dial_masquerade_caller_datastore_destroy ( void *  data)
static

Definition at line 2061 of file stasis_channels.c.

2062{
2064 ao2_ref(data, -1);
2065}
static void dial_masquerade_datastore_cleanup(struct dial_masquerade_datastore *masq_data)

References ao2_ref, and dial_masquerade_datastore_cleanup().

◆ dial_masquerade_datastore_add()

static struct dial_masquerade_datastore * dial_masquerade_datastore_add ( struct ast_channel chan,
struct dial_masquerade_datastore masq_data 
)
static

Definition at line 2223 of file stasis_channels.c.

2225{
2226 struct ast_datastore *datastore;
2227
2229 if (!datastore) {
2230 return NULL;
2231 }
2232
2233 if (!masq_data) {
2234 masq_data = dial_masquerade_datastore_alloc();
2235 if (!masq_data) {
2236 ast_datastore_free(datastore);
2237 return NULL;
2238 }
2239 masq_data->caller = chan;
2240 }
2241
2242 datastore->data = masq_data;
2243 ast_channel_datastore_add(chan, datastore);
2244
2245 return masq_data;
2246}
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2354
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
static const struct ast_datastore_info dial_masquerade_caller_info
static const struct ast_datastore_info dial_masquerade_info
static struct dial_masquerade_datastore * dial_masquerade_datastore_alloc(void)
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66

References ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), dial_masquerade_datastore::caller, ast_datastore::data, dial_masquerade_caller_info, dial_masquerade_datastore_alloc(), dial_masquerade_info, and NULL.

Referenced by set_dial_masquerade().

◆ dial_masquerade_datastore_alloc()

static struct dial_masquerade_datastore * dial_masquerade_datastore_alloc ( void  )
static

Definition at line 2035 of file stasis_channels.c.

2036{
2037 struct dial_masquerade_datastore *masq_data;
2038
2039 masq_data = ao2_alloc(sizeof(struct dial_masquerade_datastore),
2041 if (!masq_data) {
2042 return NULL;
2043 }
2045 return masq_data;
2046}
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
static void dial_masquerade_datastore_dtor(void *vdoomed)

References ao2_alloc, AST_LIST_HEAD_INIT_NOLOCK, dial_masquerade_datastore_dtor(), dial_masquerade_datastore::dialed_peers, and NULL.

Referenced by dial_masquerade_datastore_add().

◆ dial_masquerade_datastore_cleanup()

static void dial_masquerade_datastore_cleanup ( struct dial_masquerade_datastore masq_data)
static

Definition at line 2001 of file stasis_channels.c.

2002{
2003 struct dial_target *cur;
2004
2005 while ((cur = AST_LIST_REMOVE_HEAD(&masq_data->dialed_peers, list))) {
2006 dial_target_free(cur);
2007 }
2008}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
static void dial_target_free(struct dial_target *doomed)

References AST_LIST_REMOVE_HEAD, dial_target_free(), dial_masquerade_datastore::dialed_peers, and dial_target::list.

Referenced by dial_masquerade_caller_datastore_destroy(), dial_masquerade_datastore_dtor(), dial_masquerade_datastore_remove_chan(), and dial_masquerade_fixup().

◆ dial_masquerade_datastore_destroy()

static void dial_masquerade_datastore_destroy ( void *  data)
static

Definition at line 2052 of file stasis_channels.c.

2053{
2054 ao2_ref(data, -1);
2055}

References ao2_ref.

◆ dial_masquerade_datastore_dtor()

static void dial_masquerade_datastore_dtor ( void *  vdoomed)
static

Definition at line 2030 of file stasis_channels.c.

2031{
2033}

References dial_masquerade_datastore_cleanup().

Referenced by dial_masquerade_datastore_alloc().

◆ dial_masquerade_datastore_find()

static struct ast_datastore * dial_masquerade_datastore_find ( struct ast_channel chan)
static

Definition at line 2200 of file stasis_channels.c.

2201{
2202 struct ast_datastore *datastore;
2203
2205 if (!datastore) {
2207 }
2208
2209 return datastore;
2210}
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2368

References ast_channel_datastore_find(), dial_masquerade_caller_info, dial_masquerade_info, and NULL.

Referenced by dial_masquerade_fixup(), remove_dial_masquerade(), remove_dial_masquerade_caller(), and set_dial_masquerade().

◆ dial_masquerade_datastore_remove_chan()

static void dial_masquerade_datastore_remove_chan ( struct dial_masquerade_datastore masq_data,
struct ast_channel chan 
)
static

Definition at line 2010 of file stasis_channels.c.

2011{
2012 struct dial_target *cur;
2013
2014 ao2_lock(masq_data);
2015 if (masq_data->caller == chan) {
2017 } else {
2019 if (cur->peer == chan) {
2021 dial_target_free(cur);
2022 break;
2023 }
2024 }
2026 }
2027 ao2_unlock(masq_data);
2028}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557

References ao2_lock, ao2_unlock, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, dial_masquerade_datastore::caller, dial_masquerade_datastore_cleanup(), dial_target_free(), dial_masquerade_datastore::dialed_peers, dial_target::list, and dial_target::peer.

Referenced by remove_dial_masquerade(), remove_dial_masquerade_caller(), and set_dial_masquerade().

◆ dial_masquerade_fixup()

static void dial_masquerade_fixup ( void *  data,
struct ast_channel old_chan,
struct ast_channel new_chan 
)
static

Definition at line 2069 of file stasis_channels.c.

2070{
2071 struct dial_masquerade_datastore *masq_data = data;
2072 struct dial_target *cur;
2073 struct ast_datastore *datastore;
2074
2075 ao2_lock(masq_data);
2076 if (!masq_data->caller) {
2077 /* Nothing to do but remove the datastore */
2078 } else if (masq_data->caller == old_chan) {
2079 /* The caller channel is being masqueraded out. */
2080 ast_debug(1, "Caller channel %s being masqueraded out to %s (is_empty:%d)\n",
2081 ast_channel_name(new_chan), ast_channel_name(old_chan),
2082 AST_LIST_EMPTY(&masq_data->dialed_peers));
2083 AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
2085 cur->dialstring, "NOANSWER", NULL);
2087 cur->dialstring, NULL, NULL);
2088 }
2090 } else {
2091 /* One of the peer channels is being masqueraded out. */
2092 AST_LIST_TRAVERSE_SAFE_BEGIN(&masq_data->dialed_peers, cur, list) {
2093 if (cur->peer == old_chan) {
2094 ast_debug(1, "Peer channel %s being masqueraded out to %s\n",
2095 ast_channel_name(new_chan), ast_channel_name(old_chan));
2096 ast_channel_publish_dial_internal(masq_data->caller, new_chan, NULL,
2097 cur->dialstring, "CANCEL", NULL);
2098 ast_channel_publish_dial_internal(masq_data->caller, old_chan, NULL,
2099 cur->dialstring, NULL, NULL);
2100
2102 dial_target_free(cur);
2103 break;
2104 }
2105 }
2107 }
2108 ao2_unlock(masq_data);
2109
2110 /* Remove the datastore from the channel. */
2111 datastore = dial_masquerade_datastore_find(old_chan);
2112 if (!datastore) {
2113 return;
2114 }
2115 ast_channel_datastore_remove(old_chan, datastore);
2116 ast_datastore_free(datastore);
2117}
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2363
static struct ast_datastore * dial_masquerade_datastore_find(struct ast_channel *chan)

References ao2_lock, ao2_unlock, ast_channel_datastore_remove(), ast_channel_name(), ast_channel_publish_dial_internal(), ast_datastore_free(), ast_debug, AST_LIST_EMPTY, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, dial_masquerade_datastore::caller, dial_masquerade_datastore_cleanup(), dial_masquerade_datastore_find(), dial_target_free(), dial_masquerade_datastore::dialed_peers, dial_target::dialstring, NULL, and dial_target::peer.

◆ dial_target_free()

static void dial_target_free ( struct dial_target doomed)
static

Definition at line 1979 of file stasis_channels.c.

1980{
1981 if (!doomed) {
1982 return;
1983 }
1984 ast_free(doomed->dialstring);
1985 ast_channel_cleanup(doomed->peer);
1986 ast_free(doomed);
1987}
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:3019

References ast_channel_cleanup, ast_free, dial_target::dialstring, and dial_target::peer.

Referenced by dial_masquerade_datastore_cleanup(), dial_masquerade_datastore_remove_chan(), and dial_masquerade_fixup().

◆ dial_to_json()

static struct ast_json * dial_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1496 of file stasis_channels.c.

1499{
1501 struct ast_json *blob = ast_multi_channel_blob_get_json(payload);
1502 const char *dialstatus =
1503 ast_json_string_get(ast_json_object_get(blob, "dialstatus"));
1504 const char *forward =
1505 ast_json_string_get(ast_json_object_get(blob, "forward"));
1506 const char *dialstring =
1507 ast_json_string_get(ast_json_object_get(blob, "dialstring"));
1508 struct ast_json *caller_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "caller"), sanitize);
1509 struct ast_json *peer_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "peer"), sanitize);
1510 struct ast_json *forwarded_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "forwarded"), sanitize);
1511 struct ast_json *json;
1512 const struct timeval *tv = stasis_message_timestamp(message);
1513 int res = 0;
1514
1515 json = ast_json_pack("{s: s, s: o, s: s, s: s, s: s}",
1516 "type", "Dial",
1517 "timestamp", ast_json_timeval(*tv, NULL),
1518 "dialstatus", dialstatus,
1519 "forward", forward,
1520 "dialstring", dialstring);
1521 if (!json) {
1522 ast_json_unref(caller_json);
1523 ast_json_unref(peer_json);
1524 ast_json_unref(forwarded_json);
1525 return NULL;
1526 }
1527
1528 if (caller_json) {
1529 res |= ast_json_object_set(json, "caller", caller_json);
1530 }
1531 if (peer_json) {
1532 res |= ast_json_object_set(json, "peer", peer_json);
1533 }
1534 if (forwarded_json) {
1535 res |= ast_json_object_set(json, "forwarded", forwarded_json);
1536 }
1537
1538 if (res) {
1539 ast_json_unref(json);
1540 return NULL;
1541 }
1542
1543 return json;
1544}
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_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.

References ast_channel_snapshot_to_json(), ast_json_object_get(), ast_json_object_set(), ast_json_pack(), ast_json_string_get(), ast_json_timeval(), ast_json_unref(), ast_multi_channel_blob_get_channel(), ast_multi_channel_blob_get_json(), NULL, stasis_message_data(), and stasis_message_timestamp().

◆ dtmf_end_to_json()

static struct ast_json * dtmf_end_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1448 of file stasis_channels.c.

1451{
1452 struct ast_channel_blob *channel_blob = stasis_message_data(message);
1453 struct ast_json *blob = channel_blob->blob;
1454 struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
1455 const char *direction =
1456 ast_json_string_get(ast_json_object_get(blob, "direction"));
1457 const char *digit =
1459 long duration_ms =
1460 ast_json_integer_get(ast_json_object_get(blob, "duration_ms"));
1461 const struct timeval *tv = stasis_message_timestamp(message);
1462 struct ast_json *json_channel;
1463
1464 /* Only present received DTMF end events as JSON */
1465 if (strcasecmp("Received", direction) != 0) {
1466 return NULL;
1467 }
1468
1469 json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
1470 if (!json_channel) {
1471 return NULL;
1472 }
1473
1474 return ast_json_pack("{s: s, s: o, s: s, s: I, s: o}",
1475 "type", "ChannelDtmfReceived",
1476 "timestamp", ast_json_timeval(*tv, NULL),
1477 "digit", digit,
1478 "duration_ms", (ast_json_int_t)duration_ms,
1479 "channel", json_channel);
1480}
char digit
direction
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
Definition: json.h:87

References ast_channel_snapshot_to_json(), ast_json_integer_get(), ast_json_object_get(), ast_json_pack(), ast_json_string_get(), ast_json_timeval(), ast_channel_blob::blob, digit, NULL, ast_channel_blob::snapshot, stasis_message_data(), and stasis_message_timestamp().

◆ hangup_request_to_json()

static struct ast_json * hangup_request_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1489 of file stasis_channels.c.

1492{
1493 return channel_blob_to_json(message, "ChannelHangupRequest", sanitize);
1494}
static struct ast_json * channel_blob_to_json(struct stasis_message *message, const char *type, const struct stasis_message_sanitizer *sanitize)

References channel_blob_to_json().

◆ hold_to_json()

static struct ast_json * hold_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1598 of file stasis_channels.c.

1600{
1601 struct ast_channel_blob *channel_blob = stasis_message_data(message);
1602 struct ast_json *blob = channel_blob->blob;
1603 struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
1604 const char *musicclass = ast_json_string_get(ast_json_object_get(blob, "musicclass"));
1605 const struct timeval *tv = stasis_message_timestamp(message);
1606 struct ast_json *json_channel;
1607
1608 json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
1609 if (!json_channel) {
1610 return NULL;
1611 }
1612
1613 return ast_json_pack("{s: s, s: o, s: s, s: o}",
1614 "type", "ChannelHold",
1615 "timestamp", ast_json_timeval(*tv, NULL),
1616 "musicclass", S_OR(musicclass, "N/A"),
1617 "channel", json_channel);
1618}

References ast_channel_snapshot_to_json(), ast_json_object_get(), ast_json_pack(), ast_json_string_get(), ast_json_timeval(), ast_channel_blob::blob, NULL, S_OR, ast_channel_blob::snapshot, stasis_message_data(), and stasis_message_timestamp().

◆ multi_channel_blob_dtor()

static void multi_channel_blob_dtor ( void *  obj)
static

Definition at line 899 of file stasis_channels.c.

900{
901 struct ast_multi_channel_blob *multi_blob = obj;
902
903 ao2_cleanup(multi_blob->channel_snapshots);
904 ast_json_unref(multi_blob->blob);
905}
struct ast_json * blob
struct ao2_container * channel_snapshots

References ao2_cleanup, ast_json_unref(), ast_multi_channel_blob::blob, and ast_multi_channel_blob::channel_snapshots.

Referenced by ast_multi_channel_blob_create().

◆ publish_message_for_channel_topics()

static void publish_message_for_channel_topics ( struct stasis_message message,
struct ast_channel chan 
)
static

Definition at line 612 of file stasis_channels.c.

613{
614 if (chan) {
616 } else {
618 }
619}
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1538

References ast_channel_topic(), ast_channel_topic_all(), and stasis_publish().

Referenced by ast_channel_publish_dial_internal().

◆ remove_dial_masquerade()

static void remove_dial_masquerade ( struct ast_channel peer)
static

Definition at line 2327 of file stasis_channels.c.

2328{
2329 struct ast_datastore *datastore;
2330 struct dial_masquerade_datastore *masq_data;
2331
2332 datastore = dial_masquerade_datastore_find(peer);
2333 if (!datastore) {
2334 return;
2335 }
2336
2337 masq_data = datastore->data;
2338 if (masq_data) {
2340 }
2341
2342 ast_channel_datastore_remove(peer, datastore);
2343 ast_datastore_free(datastore);
2344}
static void dial_masquerade_datastore_remove_chan(struct dial_masquerade_datastore *masq_data, struct ast_channel *chan)

References ast_channel_datastore_remove(), ast_datastore_free(), ast_datastore::data, dial_masquerade_datastore_find(), and dial_masquerade_datastore_remove_chan().

Referenced by ast_channel_publish_dial_forward().

◆ remove_dial_masquerade_caller()

static void remove_dial_masquerade_caller ( struct ast_channel caller)
static

Definition at line 2346 of file stasis_channels.c.

2347{
2348 struct ast_datastore *datastore;
2349 struct dial_masquerade_datastore *masq_data;
2350
2352 if (!datastore) {
2353 return;
2354 }
2355
2356 masq_data = datastore->data;
2357 if (!masq_data || !AST_LIST_EMPTY(&masq_data->dialed_peers)) {
2358 return;
2359 }
2360
2362
2364 ast_datastore_free(datastore);
2365}

References ast_channel_datastore_remove(), ast_datastore_free(), AST_LIST_EMPTY, dial_masquerade_datastore::caller, ast_datastore::data, dial_masquerade_datastore_find(), dial_masquerade_datastore_remove_chan(), and dial_masquerade_datastore::dialed_peers.

Referenced by ast_channel_publish_dial_forward().

◆ set_dial_masquerade()

static int set_dial_masquerade ( struct ast_channel caller,
struct ast_channel peer,
const char *  dialstring 
)
static

Definition at line 2248 of file stasis_channels.c.

2249{
2250 struct ast_datastore *datastore;
2251 struct dial_masquerade_datastore *masq_data;
2252 struct dial_target *target;
2253
2254 /* Find or create caller datastore */
2255 datastore = dial_masquerade_datastore_find(caller);
2256 if (!datastore) {
2257 masq_data = dial_masquerade_datastore_add(caller, NULL);
2258 } else {
2259 masq_data = datastore->data;
2260 }
2261 if (!masq_data) {
2262 return -1;
2263 }
2264 ao2_ref(masq_data, +1);
2265
2266 /*
2267 * Someone likely forgot to do an ast_channel_publish_dial()
2268 * or ast_channel_publish_dial_forward() with a final dial
2269 * status on the channel.
2270 */
2271 ast_assert(masq_data->caller == caller);
2272
2273 /* Create peer target to put into datastore */
2274 target = ast_calloc(1, sizeof(*target));
2275 if (!target) {
2276 ao2_ref(masq_data, -1);
2277 return -1;
2278 }
2279 if (dialstring) {
2280 target->dialstring = ast_strdup(dialstring);
2281 if (!target->dialstring) {
2282 ast_free(target);
2283 ao2_ref(masq_data, -1);
2284 return -1;
2285 }
2286 }
2287 target->peer = ast_channel_ref(peer);
2288
2289 /* Put peer target into datastore */
2290 ao2_lock(masq_data);
2292 AST_LIST_INSERT_HEAD(&masq_data->dialed_peers, target, list);
2293 ao2_unlock(masq_data);
2294
2296 if (datastore) {
2297 if (datastore->data == masq_data) {
2298 /*
2299 * Peer already had the datastore for this dial masquerade.
2300 * This was a redundant peer dial masquerade setup.
2301 */
2302 ao2_ref(masq_data, -1);
2303 return 0;
2304 }
2305
2306 /* Something is wrong. Try to fix if the assert doesn't abort. */
2307 ast_assert(0);
2308
2309 /* Remove the stale dial masquerade datastore */
2312 ast_datastore_free(datastore);
2313 }
2314
2315 /* Create the peer dial masquerade datastore */
2316 if (dial_masquerade_datastore_add(peer, masq_data)) {
2317 /* Success */
2318 return 0;
2319 }
2320
2321 /* Failed to create the peer datastore */
2323 ao2_ref(masq_data, -1);
2324 return -1;
2325}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2997
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
static struct dial_masquerade_datastore * dial_masquerade_datastore_add(struct ast_channel *chan, struct dial_masquerade_datastore *masq_data)

References ao2_lock, ao2_ref, ao2_unlock, ast_assert, ast_calloc, ast_channel_datastore_remove(), ast_channel_ref, ast_datastore_free(), ast_free, AST_LIST_INSERT_HEAD, ast_strdup, dial_masquerade_datastore::caller, ast_datastore::data, dial_masquerade_datastore_add(), dial_masquerade_datastore_find(), dial_masquerade_datastore_remove_chan(), dial_masquerade_datastore::dialed_peers, dial_target::dialstring, dial_target::list, NULL, and dial_target::peer.

Referenced by ast_channel_publish_dial_forward().

◆ stasis_channels_cleanup()

static void stasis_channels_cleanup ( void  )
static

Definition at line 1874 of file stasis_channels.c.

1875{
1882
1909}
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515

References ao2_cleanup, ast_channel_agent_login_type(), ast_channel_agent_logoff_type(), ast_channel_chanspy_start_type(), ast_channel_chanspy_stop_type(), ast_channel_dial_type(), ast_channel_dtmf_begin_type(), ast_channel_dtmf_end_type(), ast_channel_fax_type(), ast_channel_flash_type(), ast_channel_hangup_handler_type(), ast_channel_hangup_request_type(), ast_channel_hold_type(), ast_channel_masquerade_type(), ast_channel_mixmonitor_mute_type(), ast_channel_mixmonitor_start_type(), ast_channel_mixmonitor_stop_type(), ast_channel_moh_start_type(), ast_channel_moh_stop_type(), ast_channel_snapshot_type(), ast_channel_talking_start(), ast_channel_talking_stop(), ast_channel_tone_detect(), ast_channel_transfer_request_type(), ast_channel_unhold_type(), ast_channel_varset_type(), ast_channel_wink_type(), channel_cache, channel_cache_by_name, channel_topic_all, NULL, and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by ast_stasis_channels_init().

◆ STASIS_MESSAGE_TYPE_DEFN() [1/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_agent_login_type  ,
to_ami = agent_login_to_ami 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [2/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_agent_logoff_type  ,
to_ami = agent_logoff_to_ami 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [3/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_chanspy_start_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [4/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_chanspy_stop_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [5/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_dial_type  ,
to_json = dial_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [6/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_dtmf_begin_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [7/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_dtmf_end_type  ,
to_json = dtmf_end_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [8/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_fax_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [9/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_flash_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [10/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_hangup_handler_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [11/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_hangup_request_type  ,
to_json = hangup_request_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [12/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_hold_type  ,
to_json = hold_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [13/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_masquerade_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [14/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_mixmonitor_mute_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [15/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_mixmonitor_start_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [16/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_mixmonitor_stop_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [17/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_moh_start_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [18/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_moh_stop_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [19/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_snapshot_type  )

Define channel message types.

◆ STASIS_MESSAGE_TYPE_DEFN() [20/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_talking_start  ,
to_ami = talking_start_to_ami,
to_json = talking_start_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [21/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_talking_stop  ,
to_ami = talking_stop_to_ami,
to_json = talking_stop_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [22/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_tone_detect  ,
to_json = tone_detect_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [23/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_transfer_request_type  ,
to_json = ari_transfer_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [24/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_unhold_type  ,
to_json = unhold_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [25/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_varset_type  ,
to_ami = varset_to_ami,
to_json = varset_to_json 
)

◆ STASIS_MESSAGE_TYPE_DEFN() [26/26]

STASIS_MESSAGE_TYPE_DEFN ( ast_channel_wink_type  )

◆ state2str()

static const char * state2str ( enum ast_control_transfer  state)
static

Definition at line 1646 of file stasis_channels.c.

1646 {
1647 switch (state) {
1649 return "channel_declined";
1651 return "channel_answered";
1653 return "channel_progress";
1655 return "channel_declined";
1656 default:
1657 return "invalid";
1658 }
1659}
@ AST_TRANSFER_FAILED
@ AST_TRANSFER_UNAVAILABLE
@ AST_TRANSFER_SUCCESS
@ AST_TRANSFER_PROGRESS

References AST_TRANSFER_FAILED, AST_TRANSFER_PROGRESS, AST_TRANSFER_SUCCESS, and AST_TRANSFER_UNAVAILABLE.

Referenced by ari_transfer_to_json().

◆ talking_start_to_ami()

static struct ast_manager_event_blob * talking_start_to_ami ( struct stasis_message msg)
static

Definition at line 1546 of file stasis_channels.c.

1547{
1548 struct ast_str *channel_string;
1549 struct ast_channel_blob *obj = stasis_message_data(msg);
1550 struct ast_manager_event_blob *blob;
1551
1552 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1553 if (!channel_string) {
1554 return NULL;
1555 }
1556
1557 blob = ast_manager_event_blob_create(EVENT_FLAG_CALL, "ChannelTalkingStart",
1558 "%s", ast_str_buffer(channel_string));
1559 ast_free(channel_string);
1560
1561 return blob;
1562}
#define EVENT_FLAG_CALL
Definition: manager.h:76

References ast_free, ast_manager_build_channel_state_string(), ast_manager_event_blob_create(), ast_str_buffer(), EVENT_FLAG_CALL, NULL, ast_channel_blob::snapshot, and stasis_message_data().

◆ talking_start_to_json()

static struct ast_json * talking_start_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1564 of file stasis_channels.c.

1566{
1567 return channel_blob_to_json(message, "ChannelTalkingStarted", sanitize);
1568}

References channel_blob_to_json().

◆ talking_stop_to_ami()

static struct ast_manager_event_blob * talking_stop_to_ami ( struct stasis_message msg)
static

Definition at line 1570 of file stasis_channels.c.

1571{
1572 struct ast_str *channel_string;
1573 struct ast_channel_blob *obj = stasis_message_data(msg);
1574 int duration = ast_json_integer_get(ast_json_object_get(obj->blob, "duration"));
1575 struct ast_manager_event_blob *blob;
1576
1577 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1578 if (!channel_string) {
1579 return NULL;
1580 }
1581
1582 blob = ast_manager_event_blob_create(EVENT_FLAG_CALL, "ChannelTalkingStop",
1583 "%s"
1584 "Duration: %d\r\n",
1585 ast_str_buffer(channel_string),
1586 duration);
1587 ast_free(channel_string);
1588
1589 return blob;
1590}

References ast_free, ast_json_integer_get(), ast_json_object_get(), ast_manager_build_channel_state_string(), ast_manager_event_blob_create(), ast_str_buffer(), ast_channel_blob::blob, EVENT_FLAG_CALL, NULL, ast_channel_blob::snapshot, and stasis_message_data().

◆ talking_stop_to_json()

static struct ast_json * talking_stop_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1592 of file stasis_channels.c.

1594{
1595 return channel_blob_to_json(message, "ChannelTalkingFinished", sanitize);
1596}

References channel_blob_to_json().

◆ tone_detect_to_json()

static struct ast_json * tone_detect_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1621 of file stasis_channels.c.

1623{
1624 return channel_blob_to_json(message, "ChannelToneDetected", sanitize);
1625}

References channel_blob_to_json().

◆ unhold_to_json()

static struct ast_json * unhold_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1627 of file stasis_channels.c.

1629{
1630 struct ast_channel_blob *channel_blob = stasis_message_data(message);
1631 struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
1632 const struct timeval *tv = stasis_message_timestamp(message);
1633 struct ast_json *json_channel;
1634
1635 json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
1636 if (!json_channel) {
1637 return NULL;
1638 }
1639
1640 return ast_json_pack("{s: s, s: o, s: o}",
1641 "type", "ChannelUnhold",
1642 "timestamp", ast_json_timeval(*tv, NULL),
1643 "channel", json_channel);
1644}

References ast_channel_snapshot_to_json(), ast_json_pack(), ast_json_timeval(), NULL, ast_channel_blob::snapshot, stasis_message_data(), and stasis_message_timestamp().

◆ varset_to_ami()

static struct ast_manager_event_blob * varset_to_ami ( struct stasis_message msg)
static

Definition at line 1229 of file stasis_channels.c.

1230{
1231 struct ast_str *channel_event_string;
1232 struct ast_channel_blob *obj = stasis_message_data(msg);
1233 const char *variable =
1234 ast_json_string_get(ast_json_object_get(obj->blob, "variable"));
1235 char *value;
1236 struct ast_manager_event_blob *ev;
1237
1239 "value")));
1240 if (!value) {
1241 return NULL;
1242 }
1243
1244 if (obj->snapshot) {
1245 channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
1246 } else {
1247 channel_event_string = ast_str_create(35);
1248 ast_str_set(&channel_event_string, 0,
1249 "Channel: none\r\n"
1250 "Uniqueid: none\r\n");
1251 }
1252 if (!channel_event_string) {
1253 ast_free(value);
1254 return NULL;
1255 }
1256
1258 "%s"
1259 "Variable: %s\r\n"
1260 "Value: %s\r\n",
1261 ast_str_buffer(channel_event_string), variable, value);
1262 ast_free(channel_event_string);
1263 ast_free(value);
1264 return ev;
1265}
#define EVENT_FLAG_DIALPLAN
Definition: manager.h:86
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
char * ast_escape_c_alloc(const char *s)
Escape standard 'C' sequences in the given string.
Definition: utils.c:2140
int value
Definition: syslog.c:37

References ast_escape_c_alloc(), ast_free, ast_json_object_get(), ast_json_string_get(), ast_manager_build_channel_state_string(), ast_manager_event_blob_create(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_channel_blob::blob, EVENT_FLAG_DIALPLAN, NULL, ast_channel_blob::snapshot, stasis_message_data(), and value.

◆ varset_to_json()

static struct ast_json * varset_to_json ( struct stasis_message message,
const struct stasis_message_sanitizer sanitize 
)
static

Definition at line 1482 of file stasis_channels.c.

1485{
1486 return channel_blob_to_json(message, "ChannelVarset", sanitize);
1487}

References channel_blob_to_json().

Variable Documentation

◆ channel_cache

struct ao2_container* channel_cache
static

◆ channel_cache_by_name

struct ao2_container* channel_cache_by_name
static

◆ channel_topic_all

struct stasis_topic* channel_topic_all
static

◆ dial_masquerade_caller_info

const struct ast_datastore_info dial_masquerade_caller_info
static

◆ dial_masquerade_info

const struct ast_datastore_info dial_masquerade_info
static