Asterisk - The Open Source Telephony Project GIT-master-f08020d
Loading...
Searching...
No Matches
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.
 
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.
 
struct ao2_containerast_channel_cache_all (void)
 
struct ao2_containerast_channel_cache_by_name (void)
 Secondary channel cache, indexed by name.
 
void ast_channel_publish_blob (struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
 Publish a channel blob message.
 
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.
 
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.
 
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.
 
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.
 
void ast_channel_publish_snapshot (struct ast_channel *chan)
 Publish a ast_channel_snapshot for a channel.
 
void ast_channel_publish_varset (struct ast_channel *chan, const char *name, const char *value)
 Publish a ast_channel_publish_varset for a channel.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
void ast_channel_stage_snapshot (struct ast_channel *chan)
 Set flag to indicate channel snapshot is being staged.
 
void ast_channel_stage_snapshot_done (struct ast_channel *chan)
 Clear flag to indicate channel snapshot is being staged, and publish snapshot.
 
struct stasis_topicast_channel_topic_all (void)
 A topic which publishes the events for all channels.
 
void ast_multi_channel_blob_add_channel (struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
 Add a ast_channel_snapshot to a ast_multi_channel_blob object.
 
struct ast_multi_channel_blobast_multi_channel_blob_create (struct ast_json *blob)
 Create a ast_multi_channel_blob suitable for a stasis_message.
 
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.
 
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.
 
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.
 
int ast_stasis_channels_init (void)
 Initialize the stasis channel topic and message types.
 
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.
 
 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 1269 of file stasis_channels.c.

1270{
1271 struct ast_str *channel_string;
1272 struct ast_channel_blob *obj = stasis_message_data(msg);
1273 const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));
1274 struct ast_manager_event_blob *ev;
1275
1276 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1277 if (!channel_string) {
1278 return NULL;
1279 }
1280
1282 "%s"
1283 "Agent: %s\r\n",
1284 ast_str_buffer(channel_string), agent);
1285 ast_free(channel_string);
1286 return ev;
1287}
#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:10144
#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 *attribute_pure 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 1289 of file stasis_channels.c.

1290{
1291 struct ast_str *channel_string;
1292 struct ast_channel_blob *obj = stasis_message_data(msg);
1293 const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));
1294 long logintime = ast_json_integer_get(ast_json_object_get(obj->blob, "logintime"));
1295 struct ast_manager_event_blob *ev;
1296
1297 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1298 if (!channel_string) {
1299 return NULL;
1300 }
1301
1303 "%s"
1304 "Agent: %s\r\n"
1305 "Logintime: %ld\r\n",
1306 ast_str_buffer(channel_string), agent, logintime);
1307 ast_free(channel_string);
1308 return ev;
1309}
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 1757 of file stasis_channels.c.

1758{
1759 struct ast_ari_transfer_message *msg = obj;
1760
1761 ao2_cleanup(msg->source);
1764 ao2_cleanup(msg->dest);
1766 ao2_cleanup(msg->dest_peer);
1768 ast_free(msg->referred_by);
1769 ast_free(msg->protocol_id);
1770}
#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 1663 of file stasis_channels.c.

1665{
1666 struct ast_json *json_channel, *res;
1667 struct ast_json *refer_json, *referred_json, *dest_json;
1668 const struct timeval *tv = stasis_message_timestamp(msg);
1669 struct ast_ari_transfer_message *transfer_msg = stasis_message_data(msg);
1670
1671 dest_json = ast_json_pack("{s: s}", "destination", transfer_msg->destination);
1672 if (!dest_json) {
1673 return NULL;
1674 }
1675
1676 if (transfer_msg->protocol_id) {
1677 ast_json_object_set(dest_json, "protocol_id",
1678 ast_json_string_create(transfer_msg->protocol_id));
1679 }
1680
1681 if (AST_VECTOR_SIZE(transfer_msg->refer_params) > 0) {
1682 struct ast_json *params = ast_json_array_create();
1683 if (!params) {
1684 return NULL;
1685 }
1686 for (int i = 0; i < AST_VECTOR_SIZE(transfer_msg->refer_params); ++i) {
1687 struct ast_refer_param param = AST_VECTOR_GET(transfer_msg->refer_params, i);
1688 ast_json_array_append(params, ast_json_pack("{s: s, s: s}",
1689 "parameter_name", param.param_name,
1690 "parameter_value", param.param_value));
1691 }
1692 ast_json_object_set(dest_json, "additional_protocol_params", params);
1693 }
1694
1695 refer_json = ast_json_pack("{s: o}",
1696 "requested_destination", dest_json);
1697 if (!refer_json) {
1698 return NULL;
1699 }
1700 if (transfer_msg->dest) {
1701 struct ast_json *dest_chan_json;
1702
1703 dest_chan_json = ast_channel_snapshot_to_json(transfer_msg->dest, sanitize);
1704 ast_json_object_set(refer_json, "destination_channel", dest_chan_json);
1705 }
1706 if (transfer_msg->dest_peer) {
1707 struct ast_json *peer_chan_json;
1708
1709 peer_chan_json = ast_channel_snapshot_to_json(transfer_msg->dest_peer, sanitize);
1710 ast_json_object_set(refer_json, "connected_channel", peer_chan_json);
1711 }
1712 if (transfer_msg->dest_bridge) {
1713 struct ast_json *dest_bridge_json;
1714
1715 dest_bridge_json = ast_bridge_snapshot_to_json(transfer_msg->dest_bridge, sanitize);
1716 ast_json_object_set(refer_json, "bridge", dest_bridge_json);
1717 }
1718
1719 json_channel = ast_channel_snapshot_to_json(transfer_msg->source, sanitize);
1720 if (!json_channel) {
1721 return NULL;
1722 }
1723
1724 referred_json = ast_json_pack("{s: o}",
1725 "source_channel", json_channel);
1726 if (!referred_json) {
1727 return NULL;
1728 }
1729 if (transfer_msg->source_peer) {
1730 struct ast_json *peer_chan_json;
1731
1732 peer_chan_json = ast_channel_snapshot_to_json(transfer_msg->source_peer, sanitize);
1733 ast_json_object_set(referred_json, "connected_channel", peer_chan_json);
1734 }
1735 if (transfer_msg->source_bridge) {
1736 struct ast_json *source_bridge_json;
1737
1738 source_bridge_json = ast_bridge_snapshot_to_json(transfer_msg->source_bridge, sanitize);
1739 ast_json_object_set(referred_json, "bridge", source_bridge_json);
1740 }
1741
1742 res = ast_json_pack("{s: s, s: o, s: o, s: o}",
1743 "type", "ChannelTransfer",
1744 "timestamp", ast_json_timeval(*tv, NULL),
1745 "refer_to", refer_json,
1746 "referred_by", referred_json);
1747 if (!res) {
1748 return NULL;
1749 }
1750
1751 if (transfer_msg->state != AST_TRANSFER_INVALID) {
1752 ast_json_object_set(res, "state", ast_json_string_create(state2str(transfer_msg->state)));
1753 }
1754 return res;
1755}
@ 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:620
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:691

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 1772 of file stasis_channels.c.

1775{
1776 struct ast_ari_transfer_message *msg;
1777 msg = ao2_alloc(sizeof(*msg), ari_transfer_dtor);
1778 if (!msg) {
1779 return NULL;
1780 }
1781
1782 msg->refer_params = params;
1783 ao2_ref(msg->refer_params, +1);
1784
1785 msg->state = state;
1786
1787 ast_channel_lock(originating_chan);
1788 msg->source = ao2_bump(ast_channel_snapshot(originating_chan));
1789 ast_channel_unlock(originating_chan);
1790 if (!msg->source) {
1791 ao2_cleanup(msg);
1792 return NULL;
1793 }
1794
1795 if (dest) {
1799 if (!msg->dest) {
1800 ao2_cleanup(msg);
1801 return NULL;
1802 }
1803 }
1804
1805 if (referred_by) {
1807 if (!msg->referred_by) {
1808 ao2_cleanup(msg);
1809 return NULL;
1810 }
1811 }
1812
1813 ast_copy_string(msg->destination, exten, sizeof(msg->destination));
1814
1815 if (protocol_id) {
1817 if (!msg->protocol_id) {
1818 ao2_cleanup(msg);
1819 return NULL;
1820 }
1821 }
1822
1823 return msg;
1824}
#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
#define ast_channel_lock(chan)
Definition channel.h:2982
#define ast_channel_unlock(chan)
Definition channel.h:2983
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
Structure representing a snapshot of channel state.

References ao2_alloc, ao2_bump, ao2_cleanup, ao2_ref, ari_transfer_dtor(), ast_channel_lock, 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, and ast_ari_transfer_message::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 630 of file stasis_channels.c.

633{
634 struct ast_multi_channel_blob *payload;
635 struct stasis_message *msg;
636 struct ast_json *blob;
637 struct ast_channel_snapshot *peer_snapshot;
638
639 if (!ast_channel_dial_type()) {
640 return;
641 }
642
643 ast_assert(peer != NULL);
644
645 blob = ast_json_pack("{s: s, s: s, s: s}",
646 "dialstatus", S_OR(dialstatus, ""),
647 "forward", S_OR(forward, ""),
648 "dialstring", S_OR(dialstring, ""));
649 if (!blob) {
650 return;
651 }
652 payload = ast_multi_channel_blob_create(blob);
653 ast_json_unref(blob);
654 if (!payload) {
655 return;
656 }
657
658 if (caller) {
659 struct ast_channel_snapshot *caller_snapshot;
660
662 if (ast_strlen_zero(dialstatus)) {
664 } else {
665 caller_snapshot = ast_channel_snapshot_create(caller);
666 }
668 if (!caller_snapshot) {
669 ao2_ref(payload, -1);
670 return;
671 }
672 ast_multi_channel_blob_add_channel(payload, "caller", caller_snapshot);
673 ao2_ref(caller_snapshot, -1);
674 }
675
677 if (ast_strlen_zero(dialstatus)) {
679 } else {
680 peer_snapshot = ast_channel_snapshot_create(peer);
681 }
683 if (!peer_snapshot) {
684 ao2_ref(payload, -1);
685 return;
686 }
687 ast_multi_channel_blob_add_channel(payload, "peer", peer_snapshot);
688 ao2_ref(peer_snapshot, -1);
689
690 if (forwarded) {
691 struct ast_channel_snapshot *forwarded_snapshot;
692
693 ast_channel_lock(forwarded);
694 forwarded_snapshot = ast_channel_snapshot_create(forwarded);
695 ast_channel_unlock(forwarded);
696 if (!forwarded_snapshot) {
697 ao2_ref(payload, -1);
698 return;
699 }
700 ast_multi_channel_blob_add_channel(payload, "forwarded", forwarded_snapshot);
701 ao2_ref(forwarded_snapshot, -1);
702 }
703
705 ao2_ref(payload, -1);
706 if (msg) {
708 ao2_ref(msg, -1);
709 }
710}
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
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:779

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 1383 of file stasis_channels.c.

1386{
1387 ast_assert(old_snapshot != NULL);
1388 ast_assert(new_snapshot != NULL);
1389 return strcmp(old_snapshot->caller->number, new_snapshot->caller->number) == 0 &&
1390 strcmp(old_snapshot->caller->name, new_snapshot->caller->name) == 0;
1391}
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 1362 of file stasis_channels.c.

1365{
1366 ast_assert(old_snapshot != NULL);
1367 ast_assert(new_snapshot != NULL);
1368
1369 /* We actually get some snapshots with CEP set, but before the
1370 * application is set. Since empty application is invalid, we treat
1371 * setting the application from nothing as a CEP change.
1372 */
1373 if (ast_strlen_zero(old_snapshot->dialplan->appl) &&
1374 !ast_strlen_zero(new_snapshot->dialplan->appl)) {
1375 return 0;
1376 }
1377
1378 return old_snapshot->dialplan->priority == new_snapshot->dialplan->priority &&
1379 strcmp(old_snapshot->dialplan->context, new_snapshot->dialplan->context) == 0 &&
1380 strcmp(old_snapshot->dialplan->exten, new_snapshot->dialplan->exten) == 0;
1381}
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 1393 of file stasis_channels.c.

1396{
1397 ast_assert(old_snapshot != NULL);
1398 ast_assert(new_snapshot != NULL);
1399 return strcmp(old_snapshot->connected->number, new_snapshot->connected->number) == 0 &&
1400 strcmp(old_snapshot->connected->name, new_snapshot->connected->name) == 0;
1401}
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 1311 of file stasis_channels.c.

1314{
1315 struct ast_json *json_chan;
1316
1317 if (snapshot == NULL
1318 || (sanitize
1319 && sanitize->channel_snapshot
1320 && sanitize->channel_snapshot(snapshot))) {
1321 return NULL;
1322 }
1323
1324 json_chan = ast_json_pack(
1325 /* Broken up into groups for readability */
1326 "{ s: s, s: s, s: s, s: s,"
1327 " s: o, s: o, s: s,"
1328 " s: o, s: o, s: s }",
1329 /* First line */
1330 "id", snapshot->base->uniqueid,
1331 "name", snapshot->base->name,
1332 "state", ast_state2str(snapshot->state),
1333 "protocol_id", snapshot->base->protocol_id,
1334 /* Second line */
1335 "caller", ast_json_name_number(
1336 snapshot->caller->name, snapshot->caller->number),
1337 "connected", ast_json_name_number(
1338 snapshot->connected->name, snapshot->connected->number),
1339 "accountcode", snapshot->base->accountcode,
1340 /* Third line */
1341 "dialplan", ast_json_dialplan_cep_app(
1342 snapshot->dialplan->context, snapshot->dialplan->exten, snapshot->dialplan->priority,
1343 snapshot->dialplan->appl, snapshot->dialplan->data),
1344 "creationtime", ast_json_timeval(snapshot->base->creationtime, NULL),
1345 "language", snapshot->base->language);
1346
1347 if (!ast_strlen_zero(snapshot->caller->rdnis)) {
1348 ast_json_object_set(json_chan, "caller_rdnis", ast_json_string_create(snapshot->caller->rdnis));
1349 }
1350
1351 if (snapshot->ari_vars && !AST_LIST_EMPTY(snapshot->ari_vars)) {
1352 ast_json_object_set(json_chan, "channelvars", ast_json_channel_vars(snapshot->ari_vars));
1353 }
1354
1355 if (!ast_strlen_zero(snapshot->base->tenantid)) {
1356 ast_json_object_set(json_chan, "tenantid", ast_json_string_create(snapshot->base->tenantid));
1357 }
1358
1359 return json_chan;
1360}
const char * ast_state2str(enum ast_channel_state state)
Gives the string form of a given channel state.
Definition channel.c:636
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.
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(), 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 1922 of file stasis_channels.c.

1923{
1924 int res = 0;
1925
1927
1928 channel_topic_all = stasis_topic_create("channel:all");
1929 if (!channel_topic_all) {
1930 return -1;
1931 }
1932
1936 if (!channel_cache) {
1937 return -1;
1938 }
1939
1943 if (!channel_cache_by_name) {
1944 return -1;
1945 }
1946
1973
1974 return res;
1975}
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:684
#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 623 of file stasis_channels.c.

624{
625 struct ast_channel_blob *event = obj;
626 ao2_cleanup(event->snapshot);
627 ast_json_unref(event->blob);
628}

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 1403 of file stasis_channels.c.

1407{
1408 struct ast_json *to_json;
1409 struct ast_channel_blob *channel_blob = stasis_message_data(message);
1410 struct ast_json *blob = channel_blob->blob;
1411 struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
1412 const struct timeval *tv = stasis_message_timestamp(message);
1413 int res = 0;
1414
1415 if (blob == NULL || ast_json_is_null(blob)) {
1416 to_json = ast_json_object_create();
1417 } else {
1418 /* blobs are immutable, so shallow copies are fine */
1419 to_json = ast_json_copy(blob);
1420 }
1421 if (!to_json) {
1422 return NULL;
1423 }
1424
1425 res |= ast_json_object_set(to_json, "type", ast_json_string_create(type));
1426 res |= ast_json_object_set(to_json, "timestamp",
1427 ast_json_timeval(*tv, NULL));
1428
1429 /* For global channel messages, the snapshot is optional */
1430 if (snapshot) {
1431 struct ast_json *json_channel;
1432
1433 json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
1434 if (!json_channel) {
1435 ast_json_unref(to_json);
1436 return NULL;
1437 }
1438
1439 res |= ast_json_object_set(to_json, "channel", json_channel);
1440 }
1441
1442 if (res != 0) {
1443 ast_json_unref(to_json);
1444 return NULL;
1445 }
1446
1447 return to_json;
1448}
static const char type[]
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 848 of file stasis_channels.c.

849{
850 const struct channel_role_snapshot *object_left = obj;
851 const struct channel_role_snapshot *object_right = arg;
852 const char *right_key = arg;
853 int cmp;
854
855 switch (flags & OBJ_SEARCH_MASK) {
857 right_key = object_right->role;
858 case OBJ_SEARCH_KEY:
859 cmp = strcasecmp(object_left->role, right_key);
860 break;
862 cmp = strncasecmp(object_left->role, right_key, strlen(right_key));
863 break;
864 default:
865 cmp = 0;
866 break;
867 }
868 if (cmp) {
869 return 0;
870 }
871 return CMP_MATCH;
872}
@ 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 878 of file stasis_channels.c.

879{
880 const struct channel_role_snapshot *object = obj;
881 const char *key;
882
883 switch (flags & OBJ_SEARCH_MASK) {
884 case OBJ_SEARCH_KEY:
885 key = obj;
886 break;
888 key = object->role;
889 break;
890 default:
891 ast_assert(0);
892 return 0;
893 }
894 return ast_str_case_hash(key);
895}
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, OBJ_SEARCH_OBJECT, and channel_role_snapshot::role.

Referenced by ast_multi_channel_blob_create().

◆ channel_role_snapshot_dtor()

static void channel_role_snapshot_dtor ( void *  obj)
static

Definition at line 977 of file stasis_channels.c.

978{
979 struct channel_role_snapshot *role_snapshot = obj;
980
981 ao2_cleanup(role_snapshot->snapshot);
982}
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)
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.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_init_extended(x, field)
Initialize an extended string field.
Structure containing base information for a channel snapshot.
const ast_string_field userfield
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition channel.h:648

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_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

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:10578
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:64

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:1807
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.

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(), ast_channel_snapshot_dialplan::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);
473 snapshot->source = snapshot->buffer;
474 strcpy(snapshot->source, hangupsource); /* Safe */
475
476 return snapshot;
477}
int ast_channel_tech_hangupcause(const struct ast_channel *chan)
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_tech_hangupcause(), ast_channel_snapshot_hangup::cause, NULL, S_OR, ast_channel_snapshot_hangup::source, and ast_channel_snapshot_hangup::tech_cause.

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::base, ast_channel_snapshot::flags, ast_channel_snapshot_base::name, 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::base, ast_channel_snapshot::flags, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and ast_channel_snapshot_base::uniqueid.

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 594 of file stasis_channels.c.

595{
597
600 if (!update) {
601 return NULL;
602 }
603
604 update->old_snapshot = ao2_bump(ast_channel_snapshot(chan));
605 update->new_snapshot = ast_channel_snapshot_create(chan);
606 if (!update->new_snapshot) {
607 ao2_ref(update, -1);
608 return NULL;
609 }
610
611 return update;
612}
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_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 586 of file stasis_channels.c.

587{
589
590 ao2_cleanup(update->old_snapshot);
591 ao2_cleanup(update->new_snapshot);
592}

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 773 of file stasis_channels.c.

776{
777 struct stasis_message *msg;
778 struct ast_channel_blob *obj;
779
780 obj = ao2_alloc(sizeof(*obj), channel_blob_dtor);
781 if (!obj) {
782 return NULL;
783 }
784
785 if (snapshot) {
786 obj->snapshot = snapshot;
787 ao2_ref(obj->snapshot, +1);
788 }
789 if (!blob) {
791 }
792 obj->blob = ast_json_ref(blob);
793
794 msg = stasis_message_create(type, obj);
795 ao2_cleanup(obj);
796 return msg;
797}
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 2139 of file stasis_channels.c.

2140{
2141 struct dial_masquerade_datastore *masq_data = data;
2142 struct dial_target *cur;
2143
2144 ao2_lock(masq_data);
2145
2146 if (!masq_data->caller) {
2147 ao2_unlock(masq_data);
2148 return;
2149 }
2150
2151 if (masq_data->caller == new_chan) {
2152 /*
2153 * The caller channel is being masqueraded into.
2154 * The masquerade is likely because of a blonde transfer.
2155 */
2156 ast_debug(1, "Caller channel %s being masqueraded into by %s (is_empty:%d)\n",
2157 ast_channel_name(old_chan), ast_channel_name(new_chan),
2158 AST_LIST_EMPTY(&masq_data->dialed_peers));
2159 AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
2161 cur->dialstring, "NOANSWER", NULL);
2163 cur->dialstring, NULL, NULL);
2164 }
2165
2166 ao2_unlock(masq_data);
2167 return;
2168 }
2169
2170 /*
2171 * One of the peer channels is being masqueraded into.
2172 * The masquerade is likely because of a call pickup.
2173 */
2174 AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
2175 if (cur->peer == new_chan) {
2176 ast_debug(1, "Peer channel %s being masqueraded into by %s\n",
2177 ast_channel_name(old_chan), ast_channel_name(new_chan));
2178 ast_channel_publish_dial_internal(masq_data->caller, old_chan, NULL,
2179 cur->dialstring, "CANCEL", NULL);
2180 ast_channel_publish_dial_internal(masq_data->caller, new_chan, NULL,
2181 cur->dialstring, NULL, NULL);
2182 break;
2183 }
2184 }
2185
2186 ao2_unlock(masq_data);
2187}
#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.
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::@431 dialed_peers
struct ast_channel * peer
struct dial_target::@430 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 2072 of file stasis_channels.c.

2073{
2075 ao2_ref(data, -1);
2076}
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 2234 of file stasis_channels.c.

2236{
2237 struct ast_datastore *datastore;
2238
2240 if (!datastore) {
2241 return NULL;
2242 }
2243
2244 if (!masq_data) {
2245 masq_data = dial_masquerade_datastore_alloc();
2246 if (!masq_data) {
2247 ast_datastore_free(datastore);
2248 return NULL;
2249 }
2250 masq_data->caller = chan;
2251 }
2252
2253 datastore->data = masq_data;
2254 ast_channel_datastore_add(chan, datastore);
2255
2256 return masq_data;
2257}
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition channel.c:2375
#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 2046 of file stasis_channels.c.

2047{
2048 struct dial_masquerade_datastore *masq_data;
2049
2050 masq_data = ao2_alloc(sizeof(struct dial_masquerade_datastore),
2052 if (!masq_data) {
2053 return NULL;
2054 }
2056 return masq_data;
2057}
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
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 2012 of file stasis_channels.c.

2013{
2014 struct dial_target *cur;
2015
2016 while ((cur = AST_LIST_REMOVE_HEAD(&masq_data->dialed_peers, list))) {
2017 dial_target_free(cur);
2018 }
2019}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
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 2063 of file stasis_channels.c.

2064{
2065 ao2_ref(data, -1);
2066}

References ao2_ref.

◆ dial_masquerade_datastore_dtor()

static void dial_masquerade_datastore_dtor ( void *  vdoomed)
static

Definition at line 2041 of file stasis_channels.c.

2042{
2044}

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 2211 of file stasis_channels.c.

2212{
2213 struct ast_datastore *datastore;
2214
2216 if (!datastore) {
2218 }
2219
2220 return datastore;
2221}
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:2389

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 2021 of file stasis_channels.c.

2022{
2023 struct dial_target *cur;
2024
2025 ao2_lock(masq_data);
2026 if (masq_data->caller == chan) {
2028 } else {
2030 if (cur->peer == chan) {
2032 dial_target_free(cur);
2033 break;
2034 }
2035 }
2037 }
2038 ao2_unlock(masq_data);
2039}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.

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 2080 of file stasis_channels.c.

2081{
2082 struct dial_masquerade_datastore *masq_data = data;
2083 struct dial_target *cur;
2084 struct ast_datastore *datastore;
2085
2086 ao2_lock(masq_data);
2087 if (!masq_data->caller) {
2088 /* Nothing to do but remove the datastore */
2089 } else if (masq_data->caller == old_chan) {
2090 /* The caller channel is being masqueraded out. */
2091 ast_debug(1, "Caller channel %s being masqueraded out to %s (is_empty:%d)\n",
2092 ast_channel_name(new_chan), ast_channel_name(old_chan),
2093 AST_LIST_EMPTY(&masq_data->dialed_peers));
2094 AST_LIST_TRAVERSE(&masq_data->dialed_peers, cur, list) {
2096 cur->dialstring, "NOANSWER", NULL);
2098 cur->dialstring, NULL, NULL);
2099 }
2101 } else {
2102 /* One of the peer channels is being masqueraded out. */
2103 AST_LIST_TRAVERSE_SAFE_BEGIN(&masq_data->dialed_peers, cur, list) {
2104 if (cur->peer == old_chan) {
2105 ast_debug(1, "Peer channel %s being masqueraded out to %s\n",
2106 ast_channel_name(new_chan), ast_channel_name(old_chan));
2107 ast_channel_publish_dial_internal(masq_data->caller, new_chan, NULL,
2108 cur->dialstring, "CANCEL", NULL);
2109 ast_channel_publish_dial_internal(masq_data->caller, old_chan, NULL,
2110 cur->dialstring, NULL, NULL);
2111
2113 dial_target_free(cur);
2114 break;
2115 }
2116 }
2118 }
2119 ao2_unlock(masq_data);
2120
2121 /* Remove the datastore from the channel. */
2122 datastore = dial_masquerade_datastore_find(old_chan);
2123 if (!datastore) {
2124 return;
2125 }
2126 ast_channel_datastore_remove(old_chan, datastore);
2127 ast_datastore_free(datastore);
2128}
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition channel.c:2384
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 1990 of file stasis_channels.c.

1991{
1992 if (!doomed) {
1993 return;
1994 }
1995 ast_free(doomed->dialstring);
1996 ast_channel_cleanup(doomed->peer);
1997 ast_free(doomed);
1998}
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition channel.h:3029

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 1498 of file stasis_channels.c.

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

1453{
1454 struct ast_channel_blob *channel_blob = stasis_message_data(message);
1455 struct ast_json *blob = channel_blob->blob;
1456 struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
1457 const char *direction =
1458 ast_json_string_get(ast_json_object_get(blob, "direction"));
1459 const char *digit =
1461 long duration_ms =
1462 ast_json_integer_get(ast_json_object_get(blob, "duration_ms"));
1463 const struct timeval *tv = stasis_message_timestamp(message);
1464 struct ast_json *json_channel;
1465
1466 /* Only present received DTMF end events as JSON */
1467 if (strcasecmp("Received", direction) != 0) {
1468 return NULL;
1469 }
1470
1471 json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
1472 if (!json_channel) {
1473 return NULL;
1474 }
1475
1476 return ast_json_pack("{s: s, s: o, s: s, s: I, s: o}",
1477 "type", "ChannelDtmfReceived",
1478 "timestamp", ast_json_timeval(*tv, NULL),
1479 "digit", digit,
1480 "duration_ms", (ast_json_int_t)duration_ms,
1481 "channel", json_channel);
1482}
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 1491 of file stasis_channels.c.

1494{
1495 return channel_blob_to_json(message, "ChannelHangupRequest", sanitize);
1496}
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 1600 of file stasis_channels.c.

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

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 901 of file stasis_channels.c.

902{
903 struct ast_multi_channel_blob *multi_blob = obj;
904
905 ao2_cleanup(multi_blob->channel_snapshots);
906 ast_json_unref(multi_blob->blob);
907}
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 614 of file stasis_channels.c.

615{
616 if (chan) {
618 } else {
620 }
621}
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:1578

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 2338 of file stasis_channels.c.

2339{
2340 struct ast_datastore *datastore;
2341 struct dial_masquerade_datastore *masq_data;
2342
2343 datastore = dial_masquerade_datastore_find(peer);
2344 if (!datastore) {
2345 return;
2346 }
2347
2348 masq_data = datastore->data;
2349 if (masq_data) {
2351 }
2352
2353 ast_channel_datastore_remove(peer, datastore);
2354 ast_datastore_free(datastore);
2355}
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 2357 of file stasis_channels.c.

2358{
2359 struct ast_datastore *datastore;
2360 struct dial_masquerade_datastore *masq_data;
2361
2363 if (!datastore) {
2364 return;
2365 }
2366
2367 masq_data = datastore->data;
2368 if (!masq_data || !AST_LIST_EMPTY(&masq_data->dialed_peers)) {
2369 return;
2370 }
2371
2373
2375 ast_datastore_free(datastore);
2376}

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 2259 of file stasis_channels.c.

2260{
2261 struct ast_datastore *datastore;
2262 struct dial_masquerade_datastore *masq_data;
2263 struct dial_target *target;
2264
2265 /* Find or create caller datastore */
2266 datastore = dial_masquerade_datastore_find(caller);
2267 if (!datastore) {
2268 masq_data = dial_masquerade_datastore_add(caller, NULL);
2269 } else {
2270 masq_data = datastore->data;
2271 }
2272 if (!masq_data) {
2273 return -1;
2274 }
2275 ao2_ref(masq_data, +1);
2276
2277 /*
2278 * Someone likely forgot to do an ast_channel_publish_dial()
2279 * or ast_channel_publish_dial_forward() with a final dial
2280 * status on the channel.
2281 */
2282 ast_assert(masq_data->caller == caller);
2283
2284 /* Create peer target to put into datastore */
2285 target = ast_calloc(1, sizeof(*target));
2286 if (!target) {
2287 ao2_ref(masq_data, -1);
2288 return -1;
2289 }
2290 if (dialstring) {
2291 target->dialstring = ast_strdup(dialstring);
2292 if (!target->dialstring) {
2293 ast_free(target);
2294 ao2_ref(masq_data, -1);
2295 return -1;
2296 }
2297 }
2298 target->peer = ast_channel_ref(peer);
2299
2300 /* Put peer target into datastore */
2301 ao2_lock(masq_data);
2303 AST_LIST_INSERT_HEAD(&masq_data->dialed_peers, target, list);
2304 ao2_unlock(masq_data);
2305
2307 if (datastore) {
2308 if (datastore->data == masq_data) {
2309 /*
2310 * Peer already had the datastore for this dial masquerade.
2311 * This was a redundant peer dial masquerade setup.
2312 */
2313 ao2_ref(masq_data, -1);
2314 return 0;
2315 }
2316
2317 /* Something is wrong. Try to fix if the assert doesn't abort. */
2318 ast_assert(0);
2319
2320 /* Remove the stale dial masquerade datastore */
2323 ast_datastore_free(datastore);
2324 }
2325
2326 /* Create the peer dial masquerade datastore */
2327 if (dial_masquerade_datastore_add(peer, masq_data)) {
2328 /* Success */
2329 return 0;
2330 }
2331
2332 /* Failed to create the peer datastore */
2334 ao2_ref(masq_data, -1);
2335 return -1;
2336}
#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:3007
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
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 1885 of file stasis_channels.c.

1886{
1893
1920}
#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 1648 of file stasis_channels.c.

1648 {
1649 switch (state) {
1651 return "channel_declined";
1653 return "channel_answered";
1655 return "channel_progress";
1657 return "channel_declined";
1658 default:
1659 return "invalid";
1660 }
1661}
@ 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 1548 of file stasis_channels.c.

1549{
1550 struct ast_str *channel_string;
1551 struct ast_channel_blob *obj = stasis_message_data(msg);
1552 struct ast_manager_event_blob *blob;
1553
1554 channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1555 if (!channel_string) {
1556 return NULL;
1557 }
1558
1559 blob = ast_manager_event_blob_create(EVENT_FLAG_CALL, "ChannelTalkingStart",
1560 "%s", ast_str_buffer(channel_string));
1561 ast_free(channel_string);
1562
1563 return blob;
1564}
#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 1566 of file stasis_channels.c.

1568{
1569 return channel_blob_to_json(message, "ChannelTalkingStarted", sanitize);
1570}

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 1572 of file stasis_channels.c.

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

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 1594 of file stasis_channels.c.

1596{
1597 return channel_blob_to_json(message, "ChannelTalkingFinished", sanitize);
1598}

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 1623 of file stasis_channels.c.

1625{
1626 return channel_blob_to_json(message, "ChannelToneDetected", sanitize);
1627}

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 1629 of file stasis_channels.c.

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

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 1231 of file stasis_channels.c.

1232{
1233 struct ast_str *channel_event_string;
1234 struct ast_channel_blob *obj = stasis_message_data(msg);
1235 const char *variable =
1236 ast_json_string_get(ast_json_object_get(obj->blob, "variable"));
1237 char *value;
1238 struct ast_manager_event_blob *ev;
1239
1241 "value")));
1242 if (!value) {
1243 return NULL;
1244 }
1245
1246 if (obj->snapshot) {
1247 channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
1248 } else {
1249 channel_event_string = ast_str_create(35);
1250 ast_str_set(&channel_event_string, 0,
1251 "Channel: none\r\n"
1252 "Uniqueid: none\r\n");
1253 }
1254 if (!channel_event_string) {
1255 ast_free(value);
1256 return NULL;
1257 }
1258
1260 "%s"
1261 "Variable: %s\r\n"
1262 "Value: %s\r\n",
1263 ast_str_buffer(channel_event_string), variable, value);
1264 ast_free(channel_event_string);
1265 ast_free(value);
1266 return ev;
1267}
#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:2176
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 1484 of file stasis_channels.c.

1487{
1488 return channel_blob_to_json(message, "ChannelVarset", sanitize);
1489}

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

Definition at line 2196 of file stasis_channels.c.

2196 {
2197 .type = "stasis-chan-dial-masq",
2199 .chan_fixup = dial_masquerade_fixup,
2200 .chan_breakdown = dial_masquerade_breakdown,
2201};
static void dial_masquerade_caller_datastore_destroy(void *data)
static void dial_masquerade_breakdown(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
static void dial_masquerade_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)

Referenced by dial_masquerade_datastore_add(), and dial_masquerade_datastore_find().

◆ dial_masquerade_info

const struct ast_datastore_info dial_masquerade_info
static

Definition at line 2189 of file stasis_channels.c.

2189 {
2190 .type = "stasis-chan-dial-masq",
2192 .chan_fixup = dial_masquerade_fixup,
2193 .chan_breakdown = dial_masquerade_breakdown,
2194};
static void dial_masquerade_datastore_destroy(void *data)

Referenced by dial_masquerade_datastore_add(), and dial_masquerade_datastore_find().