Asterisk - The Open Source Telephony Project  21.4.1
Typedefs | Functions | Variables
manager_channels.c File Reference

The Asterisk Management Interface - AMI (channel event handling) More...

#include "asterisk.h"
#include "asterisk/callerid.h"
#include "asterisk/channel.h"
#include "asterisk/manager.h"
#include "asterisk/stasis_message_router.h"
#include "asterisk/pbx.h"
#include "asterisk/stasis_channels.h"

Go to the source code of this file.

Typedefs

typedef struct ast_manager_event_blob *(* channel_snapshot_monitor) (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 Typedef for callbacks that get called on channel snapshot updates.
 

Functions

struct ast_strast_manager_build_channel_state_string (const struct ast_channel_snapshot *snapshot)
 Generate the AMI message body from a channel snapshot. More...
 
struct ast_strast_manager_build_channel_state_string_prefix (const struct ast_channel_snapshot *snapshot, const char *prefix)
 Generate the AMI message body from a channel snapshot. More...
 
static void channel_chanspy_start_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_chanspy_stop_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_dial_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 Callback processing messages for channel dialing.
 
static void channel_dtmf_begin_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_dtmf_end_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_fax_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_flash_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_hangup_handler_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_hangup_request_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_hold_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_mixmonitor_mute_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_mixmonitor_start_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_mixmonitor_stop_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_moh_start_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_moh_stop_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static struct ast_manager_event_blobchannel_new_accountcode (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 
static struct ast_manager_event_blobchannel_new_callerid (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 
static struct ast_manager_event_blobchannel_new_connected_line (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 
static struct ast_manager_event_blobchannel_newexten (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 
static void channel_snapshot_update (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static struct ast_manager_event_blobchannel_state_change (struct ast_channel_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot)
 Handle channel state changes.
 
static void channel_unhold_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void channel_wink_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int dial_status_end (const char *dialstatus)
 
int manager_channels_init (void)
 Initialize support for AMI channel events. More...
 
static void manager_channels_shutdown (void)
 
static void publish_basic_channel_event (const char *event, int class, struct ast_channel_snapshot *snapshot)
 

Variables

channel_snapshot_monitor channel_monitors []
 
static struct stasis_forwardtopic_forwarder
 The Stasis Message Bus API subscription returned by the forwarding of the channel topic to the manager topic.
 

Detailed Description

The Asterisk Management Interface - AMI (channel event handling)

Author
David M. Lee, II dlee@.nosp@m.digi.nosp@m.um.co.nosp@m.m

AMI generated many per-channel and global-channel events by converting Stasis messages to AMI events. It makes sense to simply put them into a single file.

Definition in file manager_channels.c.

Function Documentation

struct ast_str* ast_manager_build_channel_state_string ( const struct ast_channel_snapshot snapshot)

Generate the AMI message body from a channel snapshot.

Since
12
Parameters
snapshotthe channel snapshot for which to generate an AMI message body
Return values
NULLon error
Returns
ast_str* on success (must be ast_freed by caller)

Definition at line 535 of file manager_channels.c.

References ast_manager_build_channel_state_string_prefix().

Referenced by channel_dial_cb(), and mwi_app_event_cb().

537 {
539 }
struct ast_str * ast_manager_build_channel_state_string_prefix(const struct ast_channel_snapshot *snapshot, const char *prefix)
Generate the AMI message body from a channel snapshot.
struct ast_str* ast_manager_build_channel_state_string_prefix ( const struct ast_channel_snapshot snapshot,
const char *  prefix 
)

Generate the AMI message body from a channel snapshot.

Since
12
Parameters
snapshotthe channel snapshot for which to generate an AMI message body
prefixWhat to prepend to the channel fields
Return values
NULLon error
Returns
ast_str* on success (must be ast_freed by caller)

Definition at line 461 of file manager_channels.c.

References ast_channel_snapshot_base::accountcode, AST_CHAN_TP_INTERNAL, ast_escape_c_alloc(), AST_LIST_TRAVERSE, ast_state2str(), ast_str_append(), ast_str_create, ast_str_set(), ast_channel_snapshot::base, ast_channel_snapshot::caller, ast_channel_snapshot::connected, ast_channel_snapshot_dialplan::context, ast_channel_snapshot::dialplan, ast_channel_snapshot_dialplan::exten, ast_channel_snapshot_base::language, ast_channel_snapshot_peer::linkedid, ast_channel_snapshot::manager_vars, ast_channel_snapshot_caller::name, ast_channel_snapshot_connected::name, ast_channel_snapshot_base::name, ast_channel_snapshot_caller::number, ast_channel_snapshot_connected::number, ast_channel_snapshot::peer, ast_channel_snapshot_dialplan::priority, S_OR, ast_channel_snapshot::state, ast_channel_snapshot_base::tech_properties, and ast_channel_snapshot_base::uniqueid.

Referenced by action_coreshowchannels(), ast_manager_build_channel_state_string(), channel_dial_cb(), and manager_build_parked_call_string().

464 {
465  struct ast_str *out;
466  char *caller_name;
467  char *connected_name;
468  int res;
469 
470  if (!snapshot || (snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL)) {
471  return NULL;
472  }
473 
474  out = ast_str_create(1024);
475  if (!out) {
476  return NULL;
477  }
478 
479  caller_name = ast_escape_c_alloc(snapshot->caller->name);
480  connected_name = ast_escape_c_alloc(snapshot->connected->name);
481 
482  res = ast_str_set(&out, 0,
483  "%sChannel: %s\r\n"
484  "%sChannelState: %u\r\n"
485  "%sChannelStateDesc: %s\r\n"
486  "%sCallerIDNum: %s\r\n"
487  "%sCallerIDName: %s\r\n"
488  "%sConnectedLineNum: %s\r\n"
489  "%sConnectedLineName: %s\r\n"
490  "%sLanguage: %s\r\n"
491  "%sAccountCode: %s\r\n"
492  "%sContext: %s\r\n"
493  "%sExten: %s\r\n"
494  "%sPriority: %d\r\n"
495  "%sUniqueid: %s\r\n"
496  "%sLinkedid: %s\r\n",
497  prefix, snapshot->base->name,
498  prefix, snapshot->state,
499  prefix, ast_state2str(snapshot->state),
500  prefix, S_OR(snapshot->caller->number, "<unknown>"),
501  prefix, S_OR(caller_name, "<unknown>"),
502  prefix, S_OR(snapshot->connected->number, "<unknown>"),
503  prefix, S_OR(connected_name, "<unknown>"),
504  prefix, snapshot->base->language,
505  prefix, snapshot->base->accountcode,
506  prefix, snapshot->dialplan->context,
507  prefix, snapshot->dialplan->exten,
508  prefix, snapshot->dialplan->priority,
509  prefix, snapshot->base->uniqueid,
510  prefix, snapshot->peer->linkedid);
511 
512  ast_free(caller_name);
513  ast_free(connected_name);
514 
515  if (!res) {
516  ast_free(out);
517  return NULL;
518  }
519 
520  if (snapshot->manager_vars) {
521  struct ast_var_t *var;
522  char *val;
523  AST_LIST_TRAVERSE(snapshot->manager_vars, var, entries) {
524  val = ast_escape_c_alloc(var->value);
525  ast_str_append(&out, 0, "%sChanVariable: %s=%s\r\n",
526  prefix,
527  var->name, S_OR(val, ""));
528  ast_free(val);
529  }
530  }
531 
532  return out;
533 }
struct ast_channel_snapshot_base * base
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:971
const ast_string_field name
const ast_string_field accountcode
const ast_string_field uniqueid
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
struct ast_channel_snapshot_dialplan * dialplan
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
const ast_string_field context
const ast_string_field exten
struct ast_channel_snapshot_caller * caller
struct varshead * manager_vars
Support for dynamic strings.
Definition: strings.h:623
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
char * ast_escape_c_alloc(const char *s)
Escape standard 'C' sequences in the given string.
Definition: utils.c:2140
enum ast_channel_state state
const ast_string_field language
const ast_string_field number
#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
struct ast_channel_snapshot_peer * peer
const char * ast_state2str(enum ast_channel_state state)
Gives the string form of a given channel state.
Definition: channel.c:636
struct ast_channel_snapshot_connected * connected
const ast_string_field name
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int manager_channels_init ( void  )

Initialize support for AMI channel events.

Return values
0on success.
non-zeroon error.
Since
12

Definition at line 1308 of file manager_channels.c.

References 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_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_topic_all(), ast_channel_unhold_type(), ast_channel_wink_type(), ast_manager_get_message_router(), ast_manager_get_topic(), ast_register_cleanup(), channel_dial_cb(), manager_topic, stasis_forward_all(), and stasis_message_router_add().

1309 {
1310  int ret = 0;
1311  struct stasis_topic *manager_topic;
1312  struct stasis_topic *channel_topic;
1313  struct stasis_message_router *message_router;
1314 
1315  manager_topic = ast_manager_get_topic();
1316  if (!manager_topic) {
1317  return -1;
1318  }
1319  message_router = ast_manager_get_message_router();
1320  if (!message_router) {
1321  return -1;
1322  }
1323  channel_topic = ast_channel_topic_all();
1324  if (!channel_topic) {
1325  return -1;
1326  }
1327 
1328  topic_forwarder = stasis_forward_all(channel_topic, manager_topic);
1329  if (!topic_forwarder) {
1330  return -1;
1331  }
1332 
1333  ast_register_cleanup(manager_channels_shutdown);
1334 
1335  /* The snapshot type has a special handler as it can result in multiple
1336  * manager events being queued due to aspects of the snapshot itself
1337  * changing.
1338  */
1339  ret |= stasis_message_router_add(message_router,
1340  ast_channel_snapshot_type(), channel_snapshot_update, NULL);
1341 
1342  ret |= stasis_message_router_add(message_router,
1343  ast_channel_dtmf_begin_type(), channel_dtmf_begin_cb, NULL);
1344 
1345  ret |= stasis_message_router_add(message_router,
1346  ast_channel_dtmf_end_type(), channel_dtmf_end_cb, NULL);
1347 
1348  ret |= stasis_message_router_add(message_router,
1349  ast_channel_flash_type(), channel_flash_cb, NULL);
1350 
1351  ret |= stasis_message_router_add(message_router,
1352  ast_channel_wink_type(), channel_wink_cb, NULL);
1353 
1354  ret |= stasis_message_router_add(message_router,
1355  ast_channel_hangup_request_type(), channel_hangup_request_cb,
1356  NULL);
1357 
1358  ret |= stasis_message_router_add(message_router,
1360 
1361  ret |= stasis_message_router_add(message_router,
1362  ast_channel_hold_type(), channel_hold_cb, NULL);
1363 
1364  ret |= stasis_message_router_add(message_router,
1365  ast_channel_unhold_type(), channel_unhold_cb, NULL);
1366 
1367  ret |= stasis_message_router_add(message_router,
1368  ast_channel_fax_type(), channel_fax_cb, NULL);
1369 
1370  ret |= stasis_message_router_add(message_router,
1371  ast_channel_chanspy_start_type(), channel_chanspy_start_cb,
1372  NULL);
1373 
1374  ret |= stasis_message_router_add(message_router,
1375  ast_channel_chanspy_stop_type(), channel_chanspy_stop_cb, NULL);
1376 
1377  ret |= stasis_message_router_add(message_router,
1378  ast_channel_hangup_handler_type(), channel_hangup_handler_cb,
1379  NULL);
1380 
1381  ret |= stasis_message_router_add(message_router,
1382  ast_channel_moh_start_type(), channel_moh_start_cb, NULL);
1383 
1384  ret |= stasis_message_router_add(message_router,
1385  ast_channel_moh_stop_type(), channel_moh_stop_cb, NULL);
1386 
1387  ret |= stasis_message_router_add(message_router,
1388  ast_channel_mixmonitor_start_type(), channel_mixmonitor_start_cb, NULL);
1389 
1390  ret |= stasis_message_router_add(message_router,
1391  ast_channel_mixmonitor_stop_type(), channel_mixmonitor_stop_cb, NULL);
1392 
1393  ret |= stasis_message_router_add(message_router,
1394  ast_channel_mixmonitor_mute_type(), channel_mixmonitor_mute_cb, NULL);
1395 
1396  /* If somehow we failed to add any routes, just shut down the whole
1397  * thing and fail it.
1398  */
1399  if (ret) {
1400  manager_channels_shutdown();
1401  return -1;
1402  }
1403 
1404  return 0;
1405 }
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_dtmf_end_type(void)
Message type for when DTMF ends on a channel.
struct stasis_message_type * ast_channel_unhold_type(void)
Message type for when a channel is removed from hold.
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
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_wink_type(void)
Message type for when a wink occurs 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_chanspy_start_type(void)
Message type for when a channel starts spying on another channel.
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1644
static void channel_dial_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Callback processing messages for channel dialing.
struct stasis_topic * ast_channel_topic_all(void)
A topic which publishes the events for all channels.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
struct stasis_message_type * ast_channel_mixmonitor_start_type(void)
Message type for starting mixmonitor on a channel.
struct stasis_message_type * ast_channel_mixmonitor_stop_type(void)
Message type for stopping mixmonitor on a channel.
struct stasis_message_router * ast_manager_get_message_router(void)
Get the stasis_message_router for AMI.
Definition: manager.c:1885
struct stasis_message_type * ast_channel_hangup_handler_type(void)
Message type for hangup handler related actions.
struct stasis_message_type * ast_channel_snapshot_type(void)
Message type for ast_channel_snapshot_update.
struct stasis_message_type * ast_channel_dtmf_begin_type(void)
Message type for when DTMF begins on a channel.
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:1880
static struct stasis_forward * topic_forwarder
The Stasis Message Bus API subscription returned by the forwarding of the channel topic to the manage...
struct stasis_message_type * ast_channel_dial_type(void)
Message type for when a channel dials another channel.
struct stasis_message_type * ast_channel_moh_stop_type(void)
Message type for stopping music on hold on a channel.
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1578
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_fax_type(void)
Message type for a fax operation.
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_mixmonitor_mute_type(void)
Message type for muting or unmuting mixmonitor on a channel.