Asterisk - The Open Source Telephony Project GIT-master-6144b6b
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 1273 of file stasis_channels.c.

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

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

1762{
1763 struct ast_ari_transfer_message *msg = obj;
1764
1765 ao2_cleanup(msg->source);
1768 ao2_cleanup(msg->dest);
1770 ao2_cleanup(msg->dest_peer);
1772 ast_free(msg->referred_by);
1773 ast_free(msg->protocol_id);
1774}
#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 1667 of file stasis_channels.c.

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

1779{
1780 struct ast_ari_transfer_message *msg;
1781 msg = ao2_alloc(sizeof(*msg), ari_transfer_dtor);
1782 if (!msg) {
1783 return NULL;
1784 }
1785
1786 msg->refer_params = params;
1787 ao2_ref(msg->refer_params, +1);
1788
1789 msg->state = state;
1790
1791 ast_channel_lock(originating_chan);
1792 msg->source = ao2_bump(ast_channel_snapshot(originating_chan));
1793 ast_channel_unlock(originating_chan);
1794 if (!msg->source) {
1795 ao2_cleanup(msg);
1796 return NULL;
1797 }
1798
1799 if (dest) {
1803 if (!msg->dest) {
1804 ao2_cleanup(msg);
1805 return NULL;
1806 }
1807 }
1808
1809 if (referred_by) {
1811 if (!msg->referred_by) {
1812 ao2_cleanup(msg);
1813 return NULL;
1814 }
1815 }
1816
1817 ast_copy_string(msg->destination, exten, sizeof(msg->destination));
1818
1819 if (protocol_id) {
1821 if (!msg->protocol_id) {
1822 ao2_cleanup(msg);
1823 return NULL;
1824 }
1825 }
1826
1827 return msg;
1828}
#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:2983
#define ast_channel_unlock(chan)
Definition channel.h:2984
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 1387 of file stasis_channels.c.

1390{
1391 ast_assert(old_snapshot != NULL);
1392 ast_assert(new_snapshot != NULL);
1393 return strcmp(old_snapshot->caller->number, new_snapshot->caller->number) == 0 &&
1394 strcmp(old_snapshot->caller->name, new_snapshot->caller->name) == 0;
1395}
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 1366 of file stasis_channels.c.

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

1400{
1401 ast_assert(old_snapshot != NULL);
1402 ast_assert(new_snapshot != NULL);
1403 return strcmp(old_snapshot->connected->number, new_snapshot->connected->number) == 0 &&
1404 strcmp(old_snapshot->connected->name, new_snapshot->connected->name) == 0;
1405}
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 1315 of file stasis_channels.c.

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

1927{
1928 int res = 0;
1929
1931
1932 channel_topic_all = stasis_topic_create("channel:all");
1933 if (!channel_topic_all) {
1934 return -1;
1935 }
1936
1940 if (!channel_cache) {
1941 return -1;
1942 }
1943
1947 if (!channel_cache_by_name) {
1948 return -1;
1949 }
1950
1977
1978 return res;
1979}
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:1524
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 1407 of file stasis_channels.c.

1411{
1412 struct ast_json *to_json;
1413 struct ast_channel_blob *channel_blob = stasis_message_data(message);
1414 struct ast_json *blob = channel_blob->blob;
1415 struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
1416 const struct timeval *tv = stasis_message_timestamp(message);
1417 int res = 0;
1418
1419 if (blob == NULL || ast_json_is_null(blob)) {
1420 to_json = ast_json_object_create();
1421 } else {
1422 /* blobs are immutable, so shallow copies are fine */
1423 to_json = ast_json_copy(blob);
1424 }
1425 if (!to_json) {
1426 return NULL;
1427 }
1428
1429 res |= ast_json_object_set(to_json, "type", ast_json_string_create(type));
1430 res |= ast_json_object_set(to_json, "timestamp",
1431 ast_json_timeval(*tv, NULL));
1432
1433 /* For global channel messages, the snapshot is optional */
1434 if (snapshot) {
1435 struct ast_json *json_channel;
1436
1437 json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);
1438 if (!json_channel) {
1439 ast_json_unref(to_json);
1440 return NULL;
1441 }
1442
1443 res |= ast_json_object_set(to_json, "channel", json_channel);
1444 }
1445
1446 if (res != 0) {
1447 ast_json_unref(to_json);
1448 return NULL;
1449 }
1450
1451 return to_json;
1452}
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:361
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition chan_iax2.c:510
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:10714
Structure that contains information about a bridge.
Definition bridge.h:355
const ast_string_field uniqueid
Definition bridge.h:407
struct ast_flags feature_flags
Definition bridge.h:375
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:1808
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 2143 of file stasis_channels.c.

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

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

2077{
2079 ao2_ref(data, -1);
2080}
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 2238 of file stasis_channels.c.

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

2051{
2052 struct dial_masquerade_datastore *masq_data;
2053
2054 masq_data = ao2_alloc(sizeof(struct dial_masquerade_datastore),
2056 if (!masq_data) {
2057 return NULL;
2058 }
2060 return masq_data;
2061}
#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 2016 of file stasis_channels.c.

2017{
2018 struct dial_target *cur;
2019
2020 while ((cur = AST_LIST_REMOVE_HEAD(&masq_data->dialed_peers, list))) {
2021 dial_target_free(cur);
2022 }
2023}
#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 2067 of file stasis_channels.c.

2068{
2069 ao2_ref(data, -1);
2070}

References ao2_ref.

◆ dial_masquerade_datastore_dtor()

static void dial_masquerade_datastore_dtor ( void *  vdoomed)
static

Definition at line 2045 of file stasis_channels.c.

2046{
2048}

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

2216{
2217 struct ast_datastore *datastore;
2218
2220 if (!datastore) {
2222 }
2223
2224 return datastore;
2225}
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:2390

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

2026{
2027 struct dial_target *cur;
2028
2029 ao2_lock(masq_data);
2030 if (masq_data->caller == chan) {
2032 } else {
2034 if (cur->peer == chan) {
2036 dial_target_free(cur);
2037 break;
2038 }
2039 }
2041 }
2042 ao2_unlock(masq_data);
2043}
#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 2084 of file stasis_channels.c.

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

1995{
1996 if (!doomed) {
1997 return;
1998 }
1999 ast_free(doomed->dialstring);
2000 ast_channel_cleanup(doomed->peer);
2001 ast_free(doomed);
2002}
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition channel.h:3030

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

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

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

1498{
1499 return channel_blob_to_json(message, "ChannelHangupRequest", sanitize);
1500}
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 1604 of file stasis_channels.c.

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

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:1589

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

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

2362{
2363 struct ast_datastore *datastore;
2364 struct dial_masquerade_datastore *masq_data;
2365
2367 if (!datastore) {
2368 return;
2369 }
2370
2371 masq_data = datastore->data;
2372 if (!masq_data || !AST_LIST_EMPTY(&masq_data->dialed_peers)) {
2373 return;
2374 }
2375
2377
2379 ast_datastore_free(datastore);
2380}

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

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

1890{
1897
1924}
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition stasis.h:1546

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

1652 {
1653 switch (state) {
1655 return "channel_declined";
1657 return "channel_answered";
1659 return "channel_progress";
1661 return "channel_declined";
1662 default:
1663 return "invalid";
1664 }
1665}
@ 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 1552 of file stasis_channels.c.

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

1572{
1573 return channel_blob_to_json(message, "ChannelTalkingStarted", sanitize);
1574}

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

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

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

1600{
1601 return channel_blob_to_json(message, "ChannelTalkingFinished", sanitize);
1602}

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

1629{
1630 return channel_blob_to_json(message, "ChannelToneDetected", sanitize);
1631}

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

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

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

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

1491{
1492 return channel_blob_to_json(message, "ChannelVarset", sanitize);
1493}

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

2200 {
2201 .type = "stasis-chan-dial-masq",
2203 .chan_fixup = dial_masquerade_fixup,
2204 .chan_breakdown = dial_masquerade_breakdown,
2205};
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 2193 of file stasis_channels.c.

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

Referenced by dial_masquerade_datastore_add(), and dial_masquerade_datastore_find().