Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Data Structures | Macros | Enumerations | Functions | Variables
AMI functions

Data Structures

struct  actions
 list of actions registered More...
 
struct  all_events
 
struct  ast_manager_user
 user descriptor, as read from the config file. More...
 
struct  eventqent
 
struct  fast_originate_helper
 helper function for originate More...
 
struct  manager_hooks
 list of hooks registered More...
 
struct  mansession
 In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data. More...
 
struct  mansession_session
 
struct  permalias
 
struct  users
 list of users found in the config file More...
 

Macros

#define any_manager_listeners(sessions)    ((sessions && ao2_container_count(sessions)) || !AST_RWLIST_EMPTY(&manager_hooks))
 
#define ASTMAN_APPEND_BUF_INITSIZE   256
 initial allocated size for the astman_append_buf and astman_send_*_va More...
 
#define DEFAULT_REALM   "asterisk"
 
#define EVENT_FLAG_SHUTDOWN   -1
 Fake event class used to end sessions at shutdown. More...
 
#define GET_HEADER_FIRST_MATCH   0
 
#define GET_HEADER_LAST_MATCH   1
 
#define GET_HEADER_SKIP_EMPTY   2
 
#define MANAGER_EVENT_BUF_INITSIZE   256
 
#define manager_event_sessions(sessions, category, event, contents, ...)    __manager_event_sessions(sessions, category, event, 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__)
 
#define MAX_AUTH_PERM_STRING   150
 
#define MAX_BLACKLIST_CMD_LEN   2
 Descriptor for a manager session, either on the AMI socket or over HTTP. More...
 
#define MAX_VARS   128
 
#define MGR_SHOW_TERMINAL_WIDTH   80
 
#define MSG_MOREDATA   ((char *)astman_send_response)
 

Enumerations

enum  add_filter_result { FILTER_SUCCESS , FILTER_ALLOC_FAILED , FILTER_COMPILE_FAIL }
 
enum  error_type {
  UNKNOWN_ACTION = 1 , UNKNOWN_CATEGORY , UNSPECIFIED_CATEGORY , UNSPECIFIED_ARGUMENT ,
  FAILURE_ALLOCATION , FAILURE_NEWCAT , FAILURE_DELCAT , FAILURE_EMPTYCAT ,
  FAILURE_UPDATE , FAILURE_DELETE , FAILURE_APPEND , FAILURE_TEMPLATE
}
 
enum  mansession_message_parsing { MESSAGE_OKAY , MESSAGE_LINE_TOO_LONG }
 

Functions

int __ast_manager_event_multichan (int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
 
static const char * __astman_get_header (const struct message *m, char *var, int mode)
 Return a matching header value. More...
 
static void __init_astman_append_buf (void)
 thread local buffer for astman_append More...
 
static void __init_manager_event_buf (void)
 
static void __init_userevent_buf (void)
 
static int __manager_event_sessions (struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
 
static int __manager_event_sessions_va (struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt, va_list ap)
 
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void acl_change_stasis_subscribe (void)
 
static void acl_change_stasis_unsubscribe (void)
 
static int action_aocmessage (struct mansession *s, const struct message *m)
 
static int action_atxfer (struct mansession *s, const struct message *m)
 
static int action_blind_transfer (struct mansession *s, const struct message *m)
 
static int action_cancel_atxfer (struct mansession *s, const struct message *m)
 
static int action_challenge (struct mansession *s, const struct message *m)
 
static int action_command (struct mansession *s, const struct message *m)
 Manager command "command" - execute CLI command. More...
 
static int action_coresettings (struct mansession *s, const struct message *m)
 Show PBX core settings information. More...
 
static int action_coreshowchannels (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannels" - List currently defined channels and some information about them. More...
 
static int action_corestatus (struct mansession *s, const struct message *m)
 Show PBX core status information. More...
 
static int action_createconfig (struct mansession *s, const struct message *m)
 
static void action_destroy (void *obj)
 
static int action_events (struct mansession *s, const struct message *m)
 
static int action_extensionstate (struct mansession *s, const struct message *m)
 
static int action_filter (struct mansession *s, const struct message *m)
 Manager command to add an event filter to a manager session. More...
 
static struct manager_actionaction_find (const char *name)
 
static int action_getconfig (struct mansession *s, const struct message *m)
 
static int action_getconfigjson (struct mansession *s, const struct message *m)
 
static int action_getvar (struct mansession *s, const struct message *m)
 
static int action_hangup (struct mansession *s, const struct message *m)
 
static int action_listcategories (struct mansession *s, const struct message *m)
 
static int action_listcommands (struct mansession *s, const struct message *m)
 
static int action_loggerrotate (struct mansession *s, const struct message *m)
 Manager command "LoggerRotate" - reloads and rotates the logger in the same manner as the CLI command 'logger rotate'. More...
 
static int action_login (struct mansession *s, const struct message *m)
 
static int action_logoff (struct mansession *s, const struct message *m)
 
static int action_mailboxcount (struct mansession *s, const struct message *m)
 
static int action_mailboxstatus (struct mansession *s, const struct message *m)
 
static int action_originate (struct mansession *s, const struct message *m)
 
static int action_ping (struct mansession *s, const struct message *m)
 
static int action_presencestate (struct mansession *s, const struct message *m)
 
static int action_redirect (struct mansession *s, const struct message *m)
 action_redirect: The redirect manager command More...
 
static int action_reload (struct mansession *s, const struct message *m)
 Send a reload event. More...
 
static int action_sendtext (struct mansession *s, const struct message *m)
 
static int action_setvar (struct mansession *s, const struct message *m)
 
static int action_status (struct mansession *s, const struct message *m)
 Manager "status" command to show channels. More...
 
static int action_timeout (struct mansession *s, const struct message *m)
 
static int action_updateconfig (struct mansession *s, const struct message *m)
 
static int action_userevent (struct mansession *s, const struct message *m)
 
static int action_waitevent (struct mansession *s, const struct message *m)
 
static struct eventqentadvance_event (struct eventqent *e)
 
static AO2_GLOBAL_OBJ_STATIC (event_docs)
 A container of event documentation nodes. More...
 
static AO2_GLOBAL_OBJ_STATIC (mgr_sessions)
 
static int aocmessage_get_unit_entry (const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
 
static void append_channel_vars (struct ast_str **pbuf, struct ast_channel *chan)
 
static int append_event (const char *str, int category)
 events are appended to a queue from where they can be dispatched to clients. More...
 
int ast_hook_send_action (struct manager_custom_hook *hook, const char *msg)
 access for hooks to send action messages to ami More...
 
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
 
int ast_manager_check_enabled (void)
 Check if AMI is enabled. More...
 
struct stasis_message_routerast_manager_get_message_router (void)
 Get the stasis_message_router for AMI. More...
 
struct stasis_topicast_manager_get_topic (void)
 Get the Stasis Message Bus API topic for AMI. More...
 
void ast_manager_publish_event (const char *type, int class_type, struct ast_json *obj)
 Publish an event to AMI. More...
 
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), struct ast_module *module, const char *synopsis, const char *description)
 register a new command with manager, including online help. This is the preferred way to register a manager command More...
 
void ast_manager_register_hook (struct manager_custom_hook *hook)
 Add a custom hook to be called when an event is fired. More...
 
static int ast_manager_register_struct (struct manager_action *act)
 
struct ast_strast_manager_str_from_json_object (struct ast_json *blob, key_exclusion_cb exclusion_cb)
 Convert a JSON object into an AMI compatible string. More...
 
int ast_manager_unregister (const char *action)
 support functions to register/unregister AMI action handlers, More...
 
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired. More...
 
int ast_webmanager_check_enabled (void)
 Check if AMI/HTTP is enabled. More...
 
void astman_append (struct mansession *s, const char *fmt,...)
 
static void astman_append_headers (struct message *m, const struct ast_variable *params)
 Append additional headers into the message structure from params. More...
 
static void astman_append_json (struct mansession *s, const char *str)
 
static void astman_flush (struct mansession *s, struct ast_str *buf)
 
static void astman_free_headers (struct message *m)
 Free headers inside message structure, but not the message structure itself. More...
 
const char * astman_get_header (const struct message *m, char *var)
 Return the first matching variable from an array. More...
 
struct ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers. More...
 
struct ast_variableastman_get_variables_order (const struct message *m, enum variable_orders order)
 Get a linked list of the Variable: headers with order specified. More...
 
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction. More...
 
void astman_send_error (struct mansession *s, const struct message *m, char *error)
 Send error in manager transaction. More...
 
void astman_send_error_va (struct mansession *s, const struct message *m, const char *fmt,...)
 Send error in manager transaction (with va_args support) More...
 
static void astman_send_list_complete (struct mansession *s, const struct message *m, const char *event_name, int count)
 
void astman_send_list_complete_end (struct mansession *s)
 End the list complete event. More...
 
void astman_send_list_complete_start (struct mansession *s, const struct message *m, const char *event_name, int count)
 Start the list complete event. More...
 
static struct ast_strastman_send_list_complete_start_common (struct mansession *s, const struct message *m, const char *event_name, int count)
 
void astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager transaction to begin a list. More...
 
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction. More...
 
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. More...
 
static void astman_start_ack (struct mansession *s, const struct message *m)
 
static int authenticate (struct mansession *s, const struct message *m)
 
static const char * authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned. More...
 
static int blackfilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
static struct mansession_sessionbuild_mansession (const struct ast_sockaddr *addr)
 Allocate manager session structure and add it to the list of sessions. More...
 
static int check_blacklist (const char *cmd)
 
static int check_manager_session_inuse (const char *name)
 
static void destroy_fast_originate_helper (struct fast_originate_helper *doomed)
 
static int do_message (struct mansession *s)
 
static void event_filter_destructor (void *obj)
 
static void * fast_originate (void *data)
 
static int function_capable_string_allowed_with_auths (const char *evaluating, int writepermlist)
 Checks to see if a string which can be used to evaluate functions should be rejected. More...
 
static void generate_status (struct mansession *s, struct ast_channel *chan, char **vars, int varc, int all_variables, char *id_text, int *count)
 
static int get_input (struct mansession *s, char *output)
 
static struct ast_manager_userget_manager_by_name_locked (const char *name)
 
static int get_perm (const char *instr)
 
static struct eventqentgrab_last (void)
 
static char * handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager reload. More...
 
static char * handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void handle_parse_error (struct mansession *s, struct message *m, char *error)
 
static char * handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list commands. More...
 
static char * handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list connected. More...
 
static char * handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list eventq. More...
 
static enum error_type handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
 helper function for action_updateconfig More...
 
static void json_escape (char *out, const char *in)
 
static void log_action (const struct message *m, const char *action)
 
static struct ast_variableman_do_variable_value (struct ast_variable *head, const char *hdr_val)
 
static enum add_filter_result manager_add_filter (const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
 Add an event filter to a manager session. More...
 
static void manager_default_msg_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int manager_displayconnects (struct mansession_session *session)
 Get displayconnects config option. More...
 
static void manager_generic_msg_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void manager_json_array_with_key (struct ast_json *obj, const char *key, size_t index, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_obj_with_key (struct ast_json *obj, const char *key, const char *parent_key, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_to_ast_str (struct ast_json *obj, const char *key, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_value_str_append (struct ast_json *value, const char *key, struct ast_str **res)
 
static int manager_modulecheck (struct mansession *s, const struct message *m)
 Manager function to check if module is loaded. More...
 
static int manager_moduleload (struct mansession *s, const struct message *m)
 
static int manager_state_cb (const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
 
static int mansession_cmp_fn (void *obj, void *arg, int flags)
 
static enum ast_transport mansession_get_transport (const struct mansession *s)
 
static void mansession_lock (struct mansession *s)
 Lock the 'mansession' structure. More...
 
static void mansession_unlock (struct mansession *s)
 Unlock the 'mansession' structure. More...
 
static int match_filter (struct mansession *s, char *eventdata)
 
static void print_event_instance (struct ast_cli_args *a, struct ast_xml_doc_item *instance)
 
static int process_events (struct mansession *s)
 
static int process_message (struct mansession *s, const struct message *m)
 Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the session to be destroyed. More...
 
static void purge_events (void)
 
static void purge_sessions (int n_max)
 remove at most n_max stale session from the list. More...
 
static int queue_read_action_payload (struct ast_channel *chan, const unsigned char *payload, size_t payload_size, enum ast_frame_read_action action)
 Queue a given read action containing a payload onto a channel. More...
 
static int queue_sendtext (struct ast_channel *chan, const char *body)
 Queue a read action to send a text message. More...
 
static int queue_sendtext_data (struct ast_channel *chan, const char *body, const char *content_type)
 Queue a read action to send a text data message. More...
 
static int reload_module (void)
 
static void report_auth_success (const struct mansession *s)
 
static void report_failed_acl (const struct mansession *s, const char *username)
 
static void report_failed_challenge_response (const struct mansession *s, const char *response, const char *expected_response)
 
static void report_inval_password (const struct mansession *s, const char *username)
 
static void report_invalid_user (const struct mansession *s, const char *username)
 
static void report_req_bad_format (const struct mansession *s, const char *action)
 
static void report_req_not_allowed (const struct mansession *s, const char *action)
 
static void report_session_limit (const struct mansession *s)
 
static int send_string (struct mansession *s, char *string)
 
static void session_destroy (struct mansession_session *s)
 
static void session_destructor (void *obj)
 
static void * session_do (void *data)
 The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ) More...
 
static int set_eventmask (struct mansession *s, const char *eventmask)
 Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. More...
 
static int strings_to_mask (const char *string)
 
static struct mansession_sessionunref_mansession (struct mansession_session *s)
 Unreference manager session object. If no more references, then go ahead and delete it. More...
 
static const char * user_authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options for a user. This will only display those authority codes that have an explicit match on authority. More...
 
static int whitefilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 

Variables

static struct stasis_subscriptionacl_change_sub
 
static struct actions actions = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct all_events all_events = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static int allowmultiplelogin = 1
 
static struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , }
 
static int authlimit
 
static int authtimeout
 
static int broken_events_action = 0
 
struct {
   const char *   words [AST_MAX_CMD_LEN]
 
command_blacklist []
 
static int displayconnects = 1
 
static char global_realm [MAXHOSTNAMELEN]
 
static int httptimeout = 60
 
static char * manager_channelvars
 
static int manager_debug = 0
 
static char * manager_disabledevents
 
static int manager_enabled = 0
 
static struct ast_threadstorage manager_event_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_buf , .custom_init = NULL , }
 
static struct manager_hooks manager_hooks = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct stasis_topicmanager_topic
 A stasis_topic that all topics AMI cares about will be forwarded to. More...
 
static const struct permalias perms []
 
static struct stasis_forwardrtp_topic_forwarder
 The stasis_subscription for forwarding the RTP topic to the AMI topic. More...
 
static struct stasis_forwardsecurity_topic_forwarder
 The stasis_subscription for forwarding the Security topic to the AMI topic. More...
 
static struct stasis_message_routerstasis_router
 The stasis_message_router for all Stasis Message Bus API messages. More...
 
static int subscribed = 0
 
static int timestampevents
 
static int unauth_sessions = 0
 
static struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , }
 
static struct users users = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static int webmanager_enabled = 0
 
 STASIS_MESSAGE_TYPE_DEFN (ast_manager_get_generic_type)
 Define AMI message types. More...
 

Detailed Description

Macro Definition Documentation

◆ any_manager_listeners

#define any_manager_listeners (   sessions)     ((sessions && ao2_container_count(sessions)) || !AST_RWLIST_EMPTY(&manager_hooks))

Definition at line 1842 of file manager.c.

◆ ASTMAN_APPEND_BUF_INITSIZE

#define ASTMAN_APPEND_BUF_INITSIZE   256

initial allocated size for the astman_append_buf and astman_send_*_va

Definition at line 3073 of file manager.c.

◆ DEFAULT_REALM

#define DEFAULT_REALM   "asterisk"

Definition at line 1490 of file manager.c.

◆ EVENT_FLAG_SHUTDOWN

#define EVENT_FLAG_SHUTDOWN   -1

Fake event class used to end sessions at shutdown.

Definition at line 1518 of file manager.c.

◆ GET_HEADER_FIRST_MATCH

#define GET_HEADER_FIRST_MATCH   0

Definition at line 2773 of file manager.c.

◆ GET_HEADER_LAST_MATCH

#define GET_HEADER_LAST_MATCH   1

Definition at line 2774 of file manager.c.

◆ GET_HEADER_SKIP_EMPTY

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 2775 of file manager.c.

◆ MANAGER_EVENT_BUF_INITSIZE

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 7111 of file manager.c.

◆ manager_event_sessions

#define manager_event_sessions (   sessions,
  category,
  event,
  contents,
  ... 
)     __manager_event_sessions(sessions, category, event, 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__)

Definition at line 1839 of file manager.c.

◆ MAX_AUTH_PERM_STRING

#define MAX_AUTH_PERM_STRING   150

Maximum string length of the AMI authority permission string buildable from perms[].

Definition at line 2050 of file manager.c.

◆ MAX_BLACKLIST_CMD_LEN

#define MAX_BLACKLIST_CMD_LEN   2

Descriptor for a manager session, either on the AMI socket or over HTTP.

Note
AMI session have managerid == 0; the entry is created upon a connect, and destroyed with the socket. HTTP sessions have managerid != 0, the value is used as a search key to lookup sessions (using the mansession_id cookie, or nonce key from Digest Authentication http header).

Definition at line 1530 of file manager.c.

◆ MAX_VARS

#define MAX_VARS   128

Definition at line 1515 of file manager.c.

◆ MGR_SHOW_TERMINAL_WIDTH

#define MGR_SHOW_TERMINAL_WIDTH   80

Definition at line 1513 of file manager.c.

◆ MSG_MOREDATA

#define MSG_MOREDATA   ((char *)astman_send_response)
Note
NOTE: XXX this comment is unclear and possibly wrong. Callers of astman_send_error(), astman_send_response() or astman_send_ack() must EITHER hold the session lock or be running in an action callback (in which case s->session->busy will be non-zero). In either of these cases, there is no need to lock-protect the session's fd, since no other output will be sent (events will be queued), and no input will be read until either the current action finishes or get_input() obtains the session lock.
Todo:
XXX MSG_MOREDATA should go to a header file.

Definition at line 3121 of file manager.c.

Enumeration Type Documentation

◆ add_filter_result

Enumerator
FILTER_SUCCESS 
FILTER_ALLOC_FAILED 
FILTER_COMPILE_FAIL 

Definition at line 1440 of file manager.c.

1440  {
1444 };
@ FILTER_SUCCESS
Definition: manager.c:1441
@ FILTER_COMPILE_FAIL
Definition: manager.c:1443
@ FILTER_ALLOC_FAILED
Definition: manager.c:1442

◆ error_type

enum error_type

Doxygen group

Enumerator
UNKNOWN_ACTION 
UNKNOWN_CATEGORY 
UNSPECIFIED_CATEGORY 
UNSPECIFIED_ARGUMENT 
FAILURE_ALLOCATION 
FAILURE_NEWCAT 
FAILURE_DELCAT 
FAILURE_EMPTYCAT 
FAILURE_UPDATE 
FAILURE_DELETE 
FAILURE_APPEND 
FAILURE_TEMPLATE 

Definition at line 1425 of file manager.c.

1425  {
1426  UNKNOWN_ACTION = 1,
1438 };
@ FAILURE_EMPTYCAT
Definition: manager.c:1433
@ FAILURE_UPDATE
Definition: manager.c:1434
@ FAILURE_NEWCAT
Definition: manager.c:1431
@ FAILURE_DELETE
Definition: manager.c:1435
@ FAILURE_APPEND
Definition: manager.c:1436
@ UNKNOWN_CATEGORY
Definition: manager.c:1427
@ FAILURE_DELCAT
Definition: manager.c:1432
@ FAILURE_ALLOCATION
Definition: manager.c:1430
@ FAILURE_TEMPLATE
Definition: manager.c:1437
@ UNSPECIFIED_CATEGORY
Definition: manager.c:1428
@ UNSPECIFIED_ARGUMENT
Definition: manager.c:1429
@ UNKNOWN_ACTION
Definition: manager.c:1426

◆ mansession_message_parsing

Enumerator
MESSAGE_OKAY 
MESSAGE_LINE_TOO_LONG 

Definition at line 1622 of file manager.c.

1622  {
1623  MESSAGE_OKAY,
1625 };
@ MESSAGE_OKAY
Definition: manager.c:1623
@ MESSAGE_LINE_TOO_LONG
Definition: manager.c:1624

Function Documentation

◆ __ast_manager_event_multichan()

int __ast_manager_event_multichan ( int  category,
const char *  event,
int  chancount,
struct ast_channel **  chans,
const char *  file,
int  line,
const char *  func,
const char *  contents,
  ... 
)

External routines may send asterisk manager events this way

Parameters
categoryEvent category, matches manager authorization
eventEvent name
chancountNumber of channels in chans parameter
chansA pointer to an array of channels involved in the event
file,line,func
contentsFormat string describing event
...
Since
1.8

Definition at line 7234 of file manager.c.

7237 {
7238  struct ao2_container *sessions = ao2_global_obj_ref(mgr_sessions);
7239  va_list ap;
7240  int res;
7241 
7244  ast_debug(3, "AMI Event '%s' is globally disabled, skipping\n", event);
7245  /* Event is globally disabled */
7247  return 0;
7248  }
7249  }
7250 
7252  /* Nobody is listening */
7254  return 0;
7255  }
7256 
7257  va_start(ap, fmt);
7259  file, line, func, fmt, ap);
7260  va_end(ap);
7262  return res;
7263 }
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static int chancount
Definition: channel.c:93
#define any_manager_listeners(sessions)
Definition: manager.c:1842
static char * manager_disabledevents
Definition: manager.c:1488
static int __manager_event_sessions_va(struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt, va_list ap)
Definition: manager.c:7113
#define ast_debug(level,...)
Log a DEBUG message.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
int ast_in_delimited_string(const char *needle, const char *haystack, char delim)
Check if there is an exact match for 'needle' between delimiters in 'haystack'.
Definition: strings.c:434
Generic container type.
Definition: astman.c:88
Definition: astman.c:222

References __manager_event_sessions_va(), any_manager_listeners, ao2_cleanup, ao2_global_obj_ref, ast_debug, ast_in_delimited_string(), ast_strlen_zero(), chancount, make_ari_stubs::file, and manager_disabledevents.

◆ __astman_get_header()

static const char* __astman_get_header ( const struct message m,
char *  var,
int  mode 
)
static

Return a matching header value.

Generic function to return either the first or the last matching header from a list of variables, possibly skipping empty strings.

Note
At the moment there is only one use of this function in this file, so we make it static.
Never returns NULL.

Definition at line 2790 of file manager.c.

2791 {
2792  int x, l = strlen(var);
2793  const char *result = "";
2794 
2795  if (!m) {
2796  return result;
2797  }
2798 
2799  for (x = 0; x < m->hdrcount; x++) {
2800  const char *h = m->headers[x];
2801  if (!strncasecmp(var, h, l) && h[l] == ':') {
2802  const char *value = h + l + 1;
2803  value = ast_skip_blanks(value); /* ignore leading spaces in the value */
2804  /* found a potential candidate */
2805  if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
2806  continue; /* not interesting */
2807  }
2808  if (mode & GET_HEADER_LAST_MATCH) {
2809  result = value; /* record the last match so far */
2810  } else {
2811  return value;
2812  }
2813  }
2814  }
2815 
2816  return result;
2817 }
#define var
Definition: ast_expr2f.c:614
static PGresult * result
Definition: cel_pgsql.c:84
#define GET_HEADER_LAST_MATCH
Definition: manager.c:2774
#define GET_HEADER_SKIP_EMPTY
Definition: manager.c:2775
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
unsigned int hdrcount
Definition: manager.h:150
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:151
int value
Definition: syslog.c:37

References ast_skip_blanks(), ast_strlen_zero(), GET_HEADER_LAST_MATCH, GET_HEADER_SKIP_EMPTY, message::hdrcount, message::headers, result, value, and var.

Referenced by astman_get_header(), and process_message().

◆ __init_astman_append_buf()

static void __init_astman_append_buf ( void  )
static

thread local buffer for astman_append

Note
This can not be defined within the astman_append() function because it declares a couple of functions that get used to initialize the thread local storage key.

Definition at line 3068 of file manager.c.

3076 {

◆ __init_manager_event_buf()

static void __init_manager_event_buf ( void  )
static

Definition at line 7110 of file manager.c.

7124 {

◆ __init_userevent_buf()

static void __init_userevent_buf ( void  )
static

Definition at line 3070 of file manager.c.

3076 {

◆ __manager_event_sessions()

static int __manager_event_sessions ( struct ao2_container sessions,
int  category,
const char *  event,
int  chancount,
struct ast_channel **  chans,
const char *  file,
int  line,
const char *  func,
const char *  fmt,
  ... 
)
static

Definition at line 7212 of file manager.c.

7223 {
7224  va_list ap;
7225  int res;
7226 
7227  va_start(ap, fmt);
7229  file, line, func, fmt, ap);
7230  va_end(ap);
7231  return res;
7232 }

References __manager_event_sessions_va(), chancount, and make_ari_stubs::file.

◆ __manager_event_sessions_va()

static int __manager_event_sessions_va ( struct ao2_container sessions,
int  category,
const char *  event,
int  chancount,
struct ast_channel **  chans,
const char *  file,
int  line,
const char *  func,
const char *  fmt,
va_list  ap 
)
static

Definition at line 7113 of file manager.c.

7124 {
7126  const char *cat_str;
7127  struct timeval now;
7128  struct ast_str *buf;
7129  int i;
7130 
7132  if (!buf) {
7133  return -1;
7134  }
7135 
7136  cat_str = authority_to_str(category, &auth);
7137  ast_str_set(&buf, 0,
7138  "Event: %s\r\n"
7139  "Privilege: %s\r\n",
7140  event, cat_str);
7141 
7142  if (timestampevents) {
7143  now = ast_tvnow();
7144  ast_str_append(&buf, 0,
7145  "Timestamp: %ld.%06lu\r\n",
7146  (long)now.tv_sec, (unsigned long) now.tv_usec);
7147  }
7148  if (manager_debug) {
7149  static int seq;
7150 
7151  ast_str_append(&buf, 0,
7152  "SequenceNumber: %d\r\n",
7154  ast_str_append(&buf, 0,
7155  "File: %s\r\n"
7156  "Line: %d\r\n"
7157  "Func: %s\r\n",
7158  file, line, func);
7159  }
7161  ast_str_append(&buf, 0,
7162  "SystemName: %s\r\n",
7164  }
7165 
7166  ast_str_append_va(&buf, 0, fmt, ap);
7167  for (i = 0; i < chancount; i++) {
7169  }
7170 
7171  ast_str_append(&buf, 0, "\r\n");
7172 
7173  append_event(ast_str_buffer(buf), category);
7174 
7175  /* Wake up any sleeping sessions */
7176  if (sessions) {
7177  struct ao2_iterator iter;
7178  struct mansession_session *session;
7179 
7180  iter = ao2_iterator_init(sessions, 0);
7181  while ((session = ao2_iterator_next(&iter))) {
7182  ast_mutex_lock(&session->notify_lock);
7183  if (session->waiting_thread != AST_PTHREADT_NULL) {
7184  pthread_kill(session->waiting_thread, SIGURG);
7185  } else {
7186  /* We have an event to process, but the mansession is
7187  * not waiting for it. We still need to indicate that there
7188  * is an event waiting so that get_input processes the pending
7189  * event instead of polling.
7190  */
7191  session->pending_event = 1;
7192  }
7193  ast_mutex_unlock(&session->notify_lock);
7195  }
7196  ao2_iterator_destroy(&iter);
7197  }
7198 
7199  if (category != EVENT_FLAG_SHUTDOWN && !AST_RWLIST_EMPTY(&manager_hooks)) {
7200  struct manager_custom_hook *hook;
7201 
7203  AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
7204  hook->helper(category, event, ast_str_buffer(buf));
7205  }
7207  }
7208 
7209  return 0;
7210 }
static volatile unsigned int seq
Definition: app_sms.c:120
static struct ast_mansession session
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct ast_threadstorage manager_event_buf
Definition: manager.c:7110
static int manager_debug
Definition: manager.c:1484
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
Definition: manager.c:7093
static const char * authority_to_str(int authority, struct ast_str **res)
Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be re...
Definition: manager.c:2091
static struct mansession_session * unref_mansession(struct mansession_session *s)
Unreference manager session object. If no more references, then go ahead and delete it.
Definition: manager.c:2190
#define MAX_AUTH_PERM_STRING
Definition: manager.c:2050
static int timestampevents
Definition: manager.c:1478
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:1518
static int append_event(const char *str, int category)
events are appended to a queue from where they can be dispatched to clients.
Definition: manager.c:7069
#define MANAGER_EVENT_BUF_INITSIZE
Definition: manager.c:7111
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:452
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_unlock(a)
Definition: lock.h:188
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
#define ast_mutex_lock(a)
Definition: lock.h:187
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
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:1117
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:739
#define ast_str_alloca(init_len)
Definition: strings.h:826
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:1091
int ast_str_append_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Append to a dynamic string using a va_list.
Definition: strings.h:1026
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:887
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Support for dynamic strings.
Definition: strings.h:604
manager_hook_t helper
Definition: manager.h:117
list of hooks registered
Definition: manager.c:1675
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:157

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, append_channel_vars(), append_event(), ast_atomic_fetchadd_int(), ast_config_AST_SYSTEM_NAME, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), ast_tvnow(), authority_to_str(), buf, chancount, EVENT_FLAG_SHUTDOWN, make_ari_stubs::file, manager_custom_hook::helper, manager_debug, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, MAX_AUTH_PERM_STRING, seq, session, timestampevents, and unref_mansession().

Referenced by __ast_manager_event_multichan(), and __manager_event_sessions().

◆ acl_change_stasis_cb()

static void acl_change_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 9670 of file manager.c.

9672 {
9674  return;
9675  }
9676 
9677  /* For now, this is going to be performed simply and just execute a forced reload. */
9678  ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
9679  __init_manager(1, 1);
9680 }
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs
#define ast_log
Definition: astobj2.c:42
#define LOG_NOTICE
static int __init_manager(int reload, int by_external_config)
Definition: manager.c:9175
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.

References __init_manager(), ast_log, ast_named_acl_change_type(), LOG_NOTICE, and stasis_message_type().

Referenced by acl_change_stasis_subscribe().

◆ acl_change_stasis_subscribe()

static void acl_change_stasis_subscribe ( void  )
static

Definition at line 1541 of file manager.c.

1542 {
1543  if (!acl_change_sub) {
1548  }
1549 }
static struct stasis_subscription * acl_change_sub
Definition: manager.c:1494
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:9670
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
#define NULL
Definition: resample.c:96
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
Definition: stasis.h:297
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1025
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1079
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:649

References acl_change_stasis_cb(), acl_change_sub, ast_named_acl_change_type(), ast_security_topic(), NULL, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, and stasis_subscription_set_filter().

Referenced by __init_manager().

◆ acl_change_stasis_unsubscribe()

static void acl_change_stasis_unsubscribe ( void  )
static

Definition at line 1551 of file manager.c.

1552 {
1554 }
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1136

References acl_change_sub, and stasis_unsubscribe_and_join().

Referenced by __init_manager(), and manager_shutdown().

◆ action_aocmessage()

static int action_aocmessage ( struct mansession s,
const struct message m 
)
static

Definition at line 5524 of file manager.c.

5525 {
5526  const char *channel = astman_get_header(m, "Channel");
5527  const char *pchannel = astman_get_header(m, "ChannelPrefix");
5528  const char *msgtype = astman_get_header(m, "MsgType");
5529  const char *chargetype = astman_get_header(m, "ChargeType");
5530  const char *currencyname = astman_get_header(m, "CurrencyName");
5531  const char *currencyamount = astman_get_header(m, "CurrencyAmount");
5532  const char *mult = astman_get_header(m, "CurrencyMultiplier");
5533  const char *totaltype = astman_get_header(m, "TotalType");
5534  const char *aocbillingid = astman_get_header(m, "AOCBillingId");
5535  const char *association_id= astman_get_header(m, "ChargingAssociationId");
5536  const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
5537  const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
5538 
5539  enum ast_aoc_type _msgtype;
5540  enum ast_aoc_charge_type _chargetype;
5542  enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
5543  enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
5544  unsigned int _currencyamount = 0;
5545  int _association_id = 0;
5546  unsigned int _association_plan = 0;
5547  struct ast_channel *chan = NULL;
5548 
5549  struct ast_aoc_decoded *decoded = NULL;
5550  struct ast_aoc_encoded *encoded = NULL;
5551  size_t encoded_size = 0;
5552 
5553  if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
5554  astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
5555  goto aocmessage_cleanup;
5556  }
5557 
5558  if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
5559  chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
5560  }
5561 
5562  if (!chan) {
5563  astman_send_error(s, m, "No such channel");
5564  goto aocmessage_cleanup;
5565  }
5566 
5567  if (ast_strlen_zero(msgtype) || (strcasecmp(msgtype, "d") && strcasecmp(msgtype, "e"))) {
5568  astman_send_error(s, m, "Invalid MsgType");
5569  goto aocmessage_cleanup;
5570  }
5571 
5572  if (ast_strlen_zero(chargetype)) {
5573  astman_send_error(s, m, "ChargeType not specified");
5574  goto aocmessage_cleanup;
5575  }
5576 
5577  _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
5578 
5579  if (!strcasecmp(chargetype, "NA")) {
5580  _chargetype = AST_AOC_CHARGE_NA;
5581  } else if (!strcasecmp(chargetype, "Free")) {
5582  _chargetype = AST_AOC_CHARGE_FREE;
5583  } else if (!strcasecmp(chargetype, "Currency")) {
5584  _chargetype = AST_AOC_CHARGE_CURRENCY;
5585  } else if (!strcasecmp(chargetype, "Unit")) {
5586  _chargetype = AST_AOC_CHARGE_UNIT;
5587  } else {
5588  astman_send_error(s, m, "Invalid ChargeType");
5589  goto aocmessage_cleanup;
5590  }
5591 
5592  if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
5593 
5594  if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
5595  astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
5596  goto aocmessage_cleanup;
5597  }
5598 
5599  if (ast_strlen_zero(mult)) {
5600  astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
5601  goto aocmessage_cleanup;
5602  } else if (!strcasecmp(mult, "onethousandth")) {
5604  } else if (!strcasecmp(mult, "onehundredth")) {
5605  _mult = AST_AOC_MULT_ONEHUNDREDTH;
5606  } else if (!strcasecmp(mult, "onetenth")) {
5607  _mult = AST_AOC_MULT_ONETENTH;
5608  } else if (!strcasecmp(mult, "one")) {
5609  _mult = AST_AOC_MULT_ONE;
5610  } else if (!strcasecmp(mult, "ten")) {
5611  _mult = AST_AOC_MULT_TEN;
5612  } else if (!strcasecmp(mult, "hundred")) {
5613  _mult = AST_AOC_MULT_HUNDRED;
5614  } else if (!strcasecmp(mult, "thousand")) {
5615  _mult = AST_AOC_MULT_THOUSAND;
5616  } else {
5617  astman_send_error(s, m, "Invalid ChargeMultiplier");
5618  goto aocmessage_cleanup;
5619  }
5620  }
5621 
5622  /* create decoded object and start setting values */
5623  if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
5624  astman_send_error(s, m, "Message Creation Failed");
5625  goto aocmessage_cleanup;
5626  }
5627 
5628  if (_msgtype == AST_AOC_D) {
5629  if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
5630  _totaltype = AST_AOC_SUBTOTAL;
5631  }
5632 
5633  if (ast_strlen_zero(aocbillingid)) {
5634  /* ignore this is optional */
5635  } else if (!strcasecmp(aocbillingid, "Normal")) {
5636  _billingid = AST_AOC_BILLING_NORMAL;
5637  } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
5638  _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
5639  } else if (!strcasecmp(aocbillingid, "CreditCard")) {
5640  _billingid = AST_AOC_BILLING_CREDIT_CARD;
5641  } else {
5642  astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
5643  goto aocmessage_cleanup;
5644  }
5645  } else {
5646  if (ast_strlen_zero(aocbillingid)) {
5647  /* ignore this is optional */
5648  } else if (!strcasecmp(aocbillingid, "Normal")) {
5649  _billingid = AST_AOC_BILLING_NORMAL;
5650  } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
5651  _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
5652  } else if (!strcasecmp(aocbillingid, "CreditCard")) {
5653  _billingid = AST_AOC_BILLING_CREDIT_CARD;
5654  } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
5656  } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
5657  _billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
5658  } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
5659  _billingid = AST_AOC_BILLING_CALL_FWD_NO_REPLY;
5660  } else if (!strcasecmp(aocbillingid, "CallDeflection")) {
5661  _billingid = AST_AOC_BILLING_CALL_DEFLECTION;
5662  } else if (!strcasecmp(aocbillingid, "CallTransfer")) {
5663  _billingid = AST_AOC_BILLING_CALL_TRANSFER;
5664  } else {
5665  astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
5666  goto aocmessage_cleanup;
5667  }
5668 
5669  if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
5670  astman_send_error(s, m, "Invalid ChargingAssociationId");
5671  goto aocmessage_cleanup;
5672  }
5673  if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
5674  astman_send_error(s, m, "Invalid ChargingAssociationPlan");
5675  goto aocmessage_cleanup;
5676  }
5677 
5678  if (_association_id) {
5679  ast_aoc_set_association_id(decoded, _association_id);
5680  } else if (!ast_strlen_zero(association_num)) {
5681  ast_aoc_set_association_number(decoded, association_num, _association_plan);
5682  }
5683  }
5684 
5685  if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
5686  ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
5687  } else if (_chargetype == AST_AOC_CHARGE_UNIT) {
5688  struct ast_aoc_unit_entry entry;
5689  int i;
5690 
5691  /* multiple unit entries are possible, lets get them all */
5692  for (i = 0; i < 32; i++) {
5693  if (aocmessage_get_unit_entry(m, &entry, i)) {
5694  break; /* that's the end then */
5695  }
5696 
5697  ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
5698  }
5699 
5700  /* at least one unit entry is required */
5701  if (!i) {
5702  astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
5703  goto aocmessage_cleanup;
5704  }
5705 
5706  }
5707 
5708  ast_aoc_set_billing_id(decoded, _billingid);
5709  ast_aoc_set_total_type(decoded, _totaltype);
5710 
5711 
5712  if ((encoded = ast_aoc_encode(decoded, &encoded_size, NULL)) && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
5713  astman_send_ack(s, m, "AOC Message successfully queued on channel");
5714  } else {
5715  astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
5716  }
5717 
5718 aocmessage_cleanup:
5719 
5720  ast_aoc_destroy_decoded(decoded);
5721  ast_aoc_destroy_encoded(encoded);
5722 
5723  if (chan) {
5724  chan = ast_channel_unref(chan);
5725  }
5726  return 0;
5727 }
ast_aoc_charge_type
Definition: aoc.h:69
@ AST_AOC_CHARGE_CURRENCY
Definition: aoc.h:72
@ AST_AOC_CHARGE_FREE
Definition: aoc.h:71
@ AST_AOC_CHARGE_UNIT
Definition: aoc.h:73
@ AST_AOC_CHARGE_NA
Definition: aoc.h:70
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
Definition: aoc.h:34
@ AST_AOC_MULT_TEN
Definition: aoc.h:39
@ AST_AOC_MULT_ONEHUNDREDTH
Definition: aoc.h:36
@ AST_AOC_MULT_HUNDRED
Definition: aoc.h:40
@ AST_AOC_MULT_ONETENTH
Definition: aoc.h:37
@ AST_AOC_MULT_ONETHOUSANDTH
Definition: aoc.h:35
@ AST_AOC_MULT_THOUSAND
Definition: aoc.h:41
@ AST_AOC_MULT_ONE
Definition: aoc.h:38
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan)
set the charging association number for an AOC-E message
Definition: aoc.c:1056
int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded, const unsigned int amount_is_present, const unsigned int amount, const unsigned int type_is_present, const unsigned int type)
Adds a unit entry into the list of units.
Definition: aoc.c:977
ast_aoc_billing_id
Defines the billing id options for an aoc message.
Definition: aoc.h:49
@ AST_AOC_BILLING_CALL_FWD_BUSY
Definition: aoc.h:55
@ AST_AOC_BILLING_CALL_FWD_NO_REPLY
Definition: aoc.h:56
@ AST_AOC_BILLING_NORMAL
Definition: aoc.h:51
@ AST_AOC_BILLING_CALL_DEFLECTION
Definition: aoc.h:57
@ AST_AOC_BILLING_CREDIT_CARD
Definition: aoc.h:53
@ AST_AOC_BILLING_CALL_TRANSFER
Definition: aoc.h:58
@ AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL
Definition: aoc.h:54
@ AST_AOC_BILLING_REVERSE_CHARGE
Definition: aoc.h:52
@ AST_AOC_BILLING_NA
Definition: aoc.h:50
int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id)
set the billing id for a AOC-D or AST_AOC_E message
Definition: aoc.c:1024
int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded, const unsigned int amount, const enum ast_aoc_currency_multiplier multiplier, const char *name)
Sets the currency values for a AOC-D or AOC-E message.
Definition: aoc.c:919
int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id)
set the charging association id for an AST_AOC_E message
Definition: aoc.c:1040
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:313
int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type)
Sets the type of total for a AOC-D message.
Definition: aoc.c:907
ast_aoc_type
Definition: aoc.h:62
@ AST_AOC_D
Definition: aoc.h:65
@ AST_AOC_E
Definition: aoc.h:66
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:650
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
Definition: aoc.c:276
ast_aoc_total_type
Definition: aoc.h:82
@ AST_AOC_TOTAL
Definition: aoc.h:83
@ AST_AOC_SUBTOTAL
Definition: aoc.h:84
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1428
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
Definition: channel.c:4688
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1448
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3166
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3198
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:2827
static int aocmessage_get_unit_entry(const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
Definition: manager.c:5499
@ AST_CONTROL_AOC
Definition: aoc.h:178
Main Channel structure associated with a channel.
Definition: search.h:40

References aocmessage_get_unit_entry(), ast_aoc_add_unit_entry(), AST_AOC_BILLING_CALL_DEFLECTION, AST_AOC_BILLING_CALL_FWD_BUSY, AST_AOC_BILLING_CALL_FWD_NO_REPLY, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL, AST_AOC_BILLING_CALL_TRANSFER, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_create(), AST_AOC_D, ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), AST_AOC_E, ast_aoc_encode(), AST_AOC_MULT_HUNDRED, AST_AOC_MULT_ONE, AST_AOC_MULT_ONEHUNDREDTH, AST_AOC_MULT_ONETENTH, AST_AOC_MULT_ONETHOUSANDTH, AST_AOC_MULT_TEN, AST_AOC_MULT_THOUSAND, ast_aoc_set_association_id(), ast_aoc_set_association_number(), ast_aoc_set_billing_id(), ast_aoc_set_currency_info(), ast_aoc_set_total_type(), AST_AOC_SUBTOTAL, AST_AOC_TOTAL, ast_channel_get_by_name(), ast_channel_get_by_name_prefix(), ast_channel_unref, AST_CONTROL_AOC, ast_indicate_data(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and NULL.

Referenced by __init_manager().

◆ action_atxfer()

static int action_atxfer ( struct mansession s,
const struct message m 
)
static

Definition at line 5172 of file manager.c.

5173 {
5174  const char *name = astman_get_header(m, "Channel");
5175  const char *exten = astman_get_header(m, "Exten");
5176  const char *context = astman_get_header(m, "Context");
5177  struct ast_channel *chan = NULL;
5178  char feature_code[AST_FEATURE_MAX_LEN];
5179  const char *digit;
5180 
5181  if (ast_strlen_zero(name)) {
5182  astman_send_error(s, m, "No channel specified");
5183  return 0;
5184  }
5185  if (ast_strlen_zero(exten)) {
5186  astman_send_error(s, m, "No extension specified");
5187  return 0;
5188  }
5189 
5190  if (!(chan = ast_channel_get_by_name(name))) {
5191  astman_send_error(s, m, "Channel specified does not exist");
5192  return 0;
5193  }
5194 
5195  ast_channel_lock(chan);
5196  if (ast_get_builtin_feature(chan, "atxfer", feature_code, sizeof(feature_code)) ||
5197  ast_strlen_zero(feature_code)) {
5198  ast_channel_unlock(chan);
5199  astman_send_error(s, m, "No attended transfer feature code found");
5200  ast_channel_unref(chan);
5201  return 0;
5202  }
5203  ast_channel_unlock(chan);
5204 
5205  if (!ast_strlen_zero(context)) {
5206  pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
5207  }
5208 
5209  for (digit = feature_code; *digit; ++digit) {
5210  struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
5211  ast_queue_frame(chan, &f);
5212  }
5213 
5214  for (digit = exten; *digit; ++digit) {
5215  struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
5216  ast_queue_frame(chan, &f);
5217  }
5218 
5219  chan = ast_channel_unref(chan);
5220 
5221  astman_send_ack(s, m, "Atxfer successfully queued");
5222 
5223  return 0;
5224 }
char digit
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:122
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1133
#define ast_channel_unlock(chan)
Definition: channel.h:2923
static const char name[]
Definition: format_mp3.c:68
#define AST_FEATURE_MAX_LEN
int ast_get_builtin_feature(struct ast_channel *chan, const char *feature, char *buf, size_t len)
Get the DTMF code for a builtin feature.
#define AST_FRAME_DTMF
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
Data structure associated with a single frame of data.

References ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_FEATURE_MAX_LEN, AST_FRAME_DTMF, ast_get_builtin_feature(), ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, digit, exten, name, NULL, and pbx_builtin_setvar_helper().

Referenced by __init_manager().

◆ action_blind_transfer()

static int action_blind_transfer ( struct mansession s,
const struct message m 
)
static

Definition at line 5126 of file manager.c.

5127 {
5128  const char *name = astman_get_header(m, "Channel");
5129  const char *exten = astman_get_header(m, "Exten");
5130  const char *context = astman_get_header(m, "Context");
5131  struct ast_channel *chan;
5132 
5133  if (ast_strlen_zero(name)) {
5134  astman_send_error(s, m, "No channel specified");
5135  return 0;
5136  }
5137 
5138  if (ast_strlen_zero(exten)) {
5139  astman_send_error(s, m, "No extension specified");
5140  return 0;
5141  }
5142 
5143  chan = ast_channel_get_by_name(name);
5144  if (!chan) {
5145  astman_send_error(s, m, "Channel specified does not exist");
5146  return 0;
5147  }
5148 
5149  if (ast_strlen_zero(context)) {
5150  context = ast_channel_context(chan);
5151  }
5152 
5153  switch (ast_bridge_transfer_blind(1, chan, exten, context, NULL, NULL)) {
5155  astman_send_error(s, m, "Transfer not permitted");
5156  break;
5158  astman_send_error(s, m, "Transfer invalid");
5159  break;
5161  astman_send_error(s, m, "Transfer failed");
5162  break;
5164  astman_send_ack(s, m, "Transfer succeeded");
5165  break;
5166  }
5167 
5168  ast_channel_unref(chan);
5169  return 0;
5170 }
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
Definition: bridge.c:4410
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition: bridge.h:1102
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1100
@ AST_BRIDGE_TRANSFER_INVALID
Definition: bridge.h:1104
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1106
const char * ast_channel_context(const struct ast_channel *chan)

References ast_bridge_transfer_blind(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_context(), ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, name, and NULL.

Referenced by __init_manager().

◆ action_cancel_atxfer()

static int action_cancel_atxfer ( struct mansession s,
const struct message m 
)
static

Definition at line 5226 of file manager.c.

5227 {
5228  const char *name = astman_get_header(m, "Channel");
5229  struct ast_channel *chan = NULL;
5230  char *feature_code;
5231  const char *digit;
5232 
5233  if (ast_strlen_zero(name)) {
5234  astman_send_error(s, m, "No channel specified");
5235  return 0;
5236  }
5237 
5238  if (!(chan = ast_channel_get_by_name(name))) {
5239  astman_send_error(s, m, "Channel specified does not exist");
5240  return 0;
5241  }
5242 
5243  ast_channel_lock(chan);
5244  feature_code = ast_get_chan_features_atxferabort(chan);
5245  ast_channel_unlock(chan);
5246 
5247  if (!feature_code) {
5248  astman_send_error(s, m, "No disconnect feature code found");
5249  ast_channel_unref(chan);
5250  return 0;
5251  }
5252 
5253  for (digit = feature_code; *digit; ++digit) {
5254  struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
5255  ast_queue_frame(chan, &f);
5256  }
5257  ast_free(feature_code);
5258 
5259  chan = ast_channel_unref(chan);
5260 
5261  astman_send_ack(s, m, "CancelAtxfer successfully queued");
5262 
5263  return 0;
5264 }
#define ast_free(a)
Definition: astmm.h:180
char * ast_get_chan_features_atxferabort(struct ast_channel *chan)
Get the transfer configuration option atxferabort.

References ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_FRAME_DTMF, ast_free, ast_get_chan_features_atxferabort(), ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), digit, name, and NULL.

Referenced by __init_manager().

◆ action_challenge()

static int action_challenge ( struct mansession s,
const struct message m 
)
static

Definition at line 4447 of file manager.c.

4448 {
4449  const char *authtype = astman_get_header(m, "AuthType");
4450 
4451  if (!strcasecmp(authtype, "MD5")) {
4452  if (ast_strlen_zero(s->session->challenge)) {
4453  snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
4454  }
4455  mansession_lock(s);
4456  astman_start_ack(s, m);
4457  astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
4458  mansession_unlock(s);
4459  } else {
4460  astman_send_error(s, m, "Must specify AuthType");
4461  }
4462  return 0;
4463 }
static void mansession_unlock(struct mansession *s)
Unlock the 'mansession' structure.
Definition: manager.c:3264
static void mansession_lock(struct mansession *s)
Lock the 'mansession' structure.
Definition: manager.c:3258
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:3203
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3087
char challenge[10]
Definition: manager.c:1600
struct mansession_session * session
Definition: manager.c:1633
long int ast_random(void)
Definition: main/utils.c:2210

References ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mansession_session::challenge, mansession_lock(), mansession_unlock(), and mansession::session.

Referenced by __init_manager().

◆ action_command()

static int action_command ( struct mansession s,
const struct message m 
)
static

Manager command "command" - execute CLI command.

Definition at line 5303 of file manager.c.

5304 {
5305  const char *cmd = astman_get_header(m, "Command");
5306  char *buf = NULL, *final_buf = NULL, *delim, *output;
5307  char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
5308  int fd, ret;
5309  off_t len;
5310 
5311  if (ast_strlen_zero(cmd)) {
5312  astman_send_error(s, m, "No command provided");
5313  return 0;
5314  }
5315 
5316  if (check_blacklist(cmd)) {
5317  astman_send_error(s, m, "Command blacklisted");
5318  return 0;
5319  }
5320 
5321  if ((fd = mkstemp(template)) < 0) {
5322  astman_send_error_va(s, m, "Failed to create temporary file: %s", strerror(errno));
5323  return 0;
5324  }
5325 
5326  ret = ast_cli_command(fd, cmd);
5327  astman_send_response_full(s, m, ret == RESULT_SUCCESS ? "Success" : "Error", MSG_MOREDATA, NULL);
5328 
5329  /* Determine number of characters available */
5330  if ((len = lseek(fd, 0, SEEK_END)) < 0) {
5331  astman_append(s, "Message: Failed to determine number of characters: %s\r\n", strerror(errno));
5332  goto action_command_cleanup;
5333  }
5334 
5335  /* This has a potential to overflow the stack. Hence, use the heap. */
5336  buf = ast_malloc(len + 1);
5337  final_buf = ast_malloc(len + 1);
5338 
5339  if (!buf || !final_buf) {
5340  astman_append(s, "Message: Memory allocation failure\r\n");
5341  goto action_command_cleanup;
5342  }
5343 
5344  if (lseek(fd, 0, SEEK_SET) < 0) {
5345  astman_append(s, "Message: Failed to set position on temporary file: %s\r\n", strerror(errno));
5346  goto action_command_cleanup;
5347  }
5348 
5349  if (read(fd, buf, len) < 0) {
5350  astman_append(s, "Message: Failed to read from temporary file: %s\r\n", strerror(errno));
5351  goto action_command_cleanup;
5352  }
5353 
5354  buf[len] = '\0';
5355  term_strip(final_buf, buf, len);
5356  final_buf[len] = '\0';
5357 
5358  /* Trim trailing newline */
5359  if (len && final_buf[len - 1] == '\n') {
5360  final_buf[len - 1] = '\0';
5361  }
5362 
5363  astman_append(s, "Message: Command output follows\r\n");
5364 
5365  delim = final_buf;
5366  while ((output = strsep(&delim, "\n"))) {
5367  astman_append(s, "Output: %s\r\n", output);
5368  }
5369 
5370 action_command_cleanup:
5371  astman_append(s, "\r\n");
5372 
5373  close(fd);
5374  unlink(template);
5375 
5376  ast_free(buf);
5377  ast_free(final_buf);
5378 
5379  return 0;
5380 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define RESULT_SUCCESS
Definition: cli.h:40
ast_cli_command
calling arguments for new-style handlers.
Definition: cli.h:151
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_send_error_va(struct mansession *s, const struct message *m, const char *fmt,...)
Send error in manager transaction (with va_args support)
Definition: manager.c:3171
static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
send a response with an optional message, and terminate it with an empty line. m is used only to grab...
Definition: manager.c:3130
static int check_blacklist(const char *cmd)
Definition: manager.c:5267
#define MSG_MOREDATA
Definition: manager.c:3121
char * strsep(char **str, const char *delims)
int errno
char * term_strip(char *outbuf, const char *inbuf, int maxout)
Remove colorings from a specified string.
Definition: term.c:362

References ast_free, ast_malloc, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_error_va(), astman_send_response_full(), buf, check_blacklist(), errno, len(), MSG_MOREDATA, NULL, RESULT_SUCCESS, strsep(), and term_strip().

Referenced by __init_manager().

◆ action_coresettings()

static int action_coresettings ( struct mansession s,
const struct message m 
)
static

Show PBX core settings information.

Definition at line 6283 of file manager.c.

6284 {
6285  const char *actionid = astman_get_header(m, "ActionID");
6286  char idText[150];
6287 
6288  if (!ast_strlen_zero(actionid)) {
6289  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6290  } else {
6291  idText[0] = '\0';
6292  }
6293 
6294  astman_append(s, "Response: Success\r\n"
6295  "%s"
6296  "AMIversion: %s\r\n"
6297  "AsteriskVersion: %s\r\n"
6298  "SystemName: %s\r\n"
6299  "CoreMaxCalls: %d\r\n"
6300  "CoreMaxLoadAvg: %f\r\n"
6301  "CoreRunUser: %s\r\n"
6302  "CoreRunGroup: %s\r\n"
6303  "CoreMaxFilehandles: %d\r\n"
6304  "CoreRealTimeEnabled: %s\r\n"
6305  "CoreCDRenabled: %s\r\n"
6306  "CoreHTTPenabled: %s\r\n"
6307  "\r\n",
6308  idText,
6309  AMI_VERSION,
6310  ast_get_version(),
6320  );
6321  return 0;
6322 }
const char * ast_get_version(void)
Retrieve the Asterisk version string.
int ast_cdr_is_enabled(void)
Return TRUE if CDR subsystem is enabled.
Definition: cdr.c:2883
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
int ast_webmanager_check_enabled(void)
Check if AMI/HTTP is enabled.
Definition: manager.c:1961
int ast_option_maxfiles
Definition: options.c:81
int ast_option_maxcalls
Definition: options.c:79
double ast_option_maxload
Definition: options.c:77
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
Definition: main/config.c:3443
#define AMI_VERSION
Definition: manager.h:57
const char * ast_config_AST_RUN_GROUP
Definition: options.c:169
const char * ast_config_AST_RUN_USER
Definition: options.c:168

References AMI_VERSION, ast_cdr_is_enabled(), AST_CLI_YESNO, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SYSTEM_NAME, ast_get_version(), ast_option_maxcalls, ast_option_maxfiles, ast_option_maxload, ast_realtime_enabled(), ast_strlen_zero(), ast_webmanager_check_enabled(), astman_append(), and astman_get_header().

Referenced by __init_manager().

◆ action_coreshowchannels()

static int action_coreshowchannels ( struct mansession s,
const struct message m 
)
static

Manager command "CoreShowChannels" - List currently defined channels and some information about them.

Definition at line 6397 of file manager.c.

6398 {
6399  const char *actionid = astman_get_header(m, "ActionID");
6400  char idText[256];
6401  int numchans = 0;
6402  struct ao2_container *channels;
6403  struct ao2_iterator it_chans;
6404  struct ast_channel_snapshot *cs;
6405 
6406  if (!ast_strlen_zero(actionid)) {
6407  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6408  } else {
6409  idText[0] = '\0';
6410  }
6411 
6413 
6414  astman_send_listack(s, m, "Channels will follow", "start");
6415 
6416  it_chans = ao2_iterator_init(channels, 0);
6417  for (; (cs = ao2_iterator_next(&it_chans)); ao2_ref(cs, -1)) {
6419  char durbuf[16] = "";
6420 
6421  if (!built) {
6422  continue;
6423  }
6424 
6425  if (!ast_tvzero(cs->base->creationtime)) {
6426  int duration, durh, durm, durs;
6427 
6428  duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
6429  durh = duration / 3600;
6430  durm = (duration % 3600) / 60;
6431  durs = duration % 60;
6432  snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
6433  }
6434 
6435  astman_append(s,
6436  "Event: CoreShowChannel\r\n"
6437  "%s"
6438  "%s"
6439  "Application: %s\r\n"
6440  "ApplicationData: %s\r\n"
6441  "Duration: %s\r\n"
6442  "BridgeId: %s\r\n"
6443  "\r\n",
6444  idText,
6445  ast_str_buffer(built),
6446  cs->dialplan->appl,
6447  cs->dialplan->data,
6448  durbuf,
6449  cs->bridge->id);
6450 
6451  numchans++;
6452 
6453  ast_free(built);
6454  }
6455  ao2_iterator_destroy(&it_chans);
6456 
6457  astman_send_list_complete(s, m, "CoreShowChannelsComplete", numchans);
6458 
6459  ao2_ref(channels, -1);
6460  return 0;
6461 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static struct channel_usage channels
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3208
static void astman_send_list_complete(struct mansession *s, const struct message *m, const char *event_name, int count)
Definition: manager.c:3235
struct ao2_container * ast_channel_cache_by_name(void)
Secondary channel cache, indexed by name.
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.
const ast_string_field data
const ast_string_field appl
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_dialplan * dialplan
struct ast_channel_snapshot_bridge * bridge
struct ast_channel_snapshot_base * base
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:115
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:105

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_snapshot_dialplan::appl, ast_channel_cache_by_name(), ast_free, ast_manager_build_channel_state_string_prefix(), ast_str_buffer(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), astman_append(), astman_get_header(), astman_send_list_complete(), astman_send_listack(), ast_channel_snapshot::base, ast_channel_snapshot::bridge, channels, ast_channel_snapshot_base::creationtime, ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, and ast_channel_snapshot_bridge::id.

Referenced by __init_manager().

◆ action_corestatus()

static int action_corestatus ( struct mansession s,
const struct message m 
)
static

Show PBX core status information.

Definition at line 6325 of file manager.c.

6326 {
6327  const char *actionid = astman_get_header(m, "ActionID");
6328  char idText[150];
6329  char startuptime[150], startupdate[150];
6330  char reloadtime[150], reloaddate[150];
6331  struct ast_tm tm;
6332 
6333  if (!ast_strlen_zero(actionid)) {
6334  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6335  } else {
6336  idText[0] = '\0';
6337  }
6338 
6340  ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
6341  ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
6343  ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
6344  ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
6345 
6346  astman_append(s, "Response: Success\r\n"
6347  "%s"
6348  "CoreStartupDate: %s\r\n"
6349  "CoreStartupTime: %s\r\n"
6350  "CoreReloadDate: %s\r\n"
6351  "CoreReloadTime: %s\r\n"
6352  "CoreCurrentCalls: %d\r\n"
6353  "\r\n",
6354  idText,
6355  startupdate,
6356  startuptime,
6357  reloaddate,
6358  reloadtime,
6360  );
6361  return 0;
6362 }
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
struct timeval ast_startuptime
Definition: asterisk.c:336

References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strftime(), ast_strlen_zero(), astman_append(), astman_get_header(), and NULL.

Referenced by __init_manager().

◆ action_createconfig()

static int action_createconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 4193 of file manager.c.

4194 {
4195  int fd;
4196  const char *fn = astman_get_header(m, "Filename");
4197  struct ast_str *filepath = ast_str_alloca(PATH_MAX);
4198  ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
4199  ast_str_append(&filepath, 0, "%s", fn);
4200 
4201  if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
4202  close(fd);
4203  astman_send_ack(s, m, "New configuration file created successfully");
4204  } else {
4205  astman_send_error(s, m, strerror(errno));
4206  }
4207 
4208  return 0;
4209 }
#define AST_FILE_MODE
Definition: asterisk.h:32
#define PATH_MAX
Definition: asterisk.h:40
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151

References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), errno, and PATH_MAX.

Referenced by __init_manager().

◆ action_destroy()

static void action_destroy ( void *  obj)
static

Definition at line 7380 of file manager.c.

7381 {
7382  struct manager_action *doomed = obj;
7383 
7384  if (doomed->synopsis) {
7385  /* The string fields were initialized. */
7387  }
7388  ao2_cleanup(doomed->final_response);
7389  ao2_cleanup(doomed->list_responses);
7390 }
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
struct ast_xml_doc_item * final_response
Definition: manager.h:167
const ast_string_field synopsis
Definition: manager.h:163
struct ast_xml_doc_item * list_responses
Definition: manager.h:165

References ao2_cleanup, ast_string_field_free_memory, manager_action::final_response, manager_action::list_responses, and manager_action::synopsis.

Referenced by ast_manager_register2().

◆ action_events()

static int action_events ( struct mansession s,
const struct message m 
)
static

Definition at line 4348 of file manager.c.

4349 {
4350  const char *mask = astman_get_header(m, "EventMask");
4351  int res, x;
4352  const char *id = astman_get_header(m, "ActionID");
4353  char id_text[256];
4354 
4355  if (!ast_strlen_zero(id)) {
4356  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
4357  } else {
4358  id_text[0] = '\0';
4359  }
4360 
4361  res = set_eventmask(s, mask);
4362  if (broken_events_action) {
4363  /* if this option is set we should not return a response on
4364  * error, or when all events are set */
4365 
4366  if (res > 0) {
4367  for (x = 0; x < ARRAY_LEN(perms); x++) {
4368  if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
4369  return 0;
4370  }
4371  }
4372  astman_append(s, "Response: Success\r\n%s"
4373  "Events: On\r\n\r\n", id_text);
4374  } else if (res == 0)
4375  astman_append(s, "Response: Success\r\n%s"
4376  "Events: Off\r\n\r\n", id_text);
4377  return 0;
4378  }
4379 
4380  if (res > 0)
4381  astman_append(s, "Response: Success\r\n%s"
4382  "Events: On\r\n\r\n", id_text);
4383  else if (res == 0)
4384  astman_append(s, "Response: Success\r\n%s"
4385  "Events: Off\r\n\r\n", id_text);
4386  else
4387  astman_send_error(s, m, "Invalid event mask");
4388 
4389  return 0;
4390 }
static int broken_events_action
Definition: manager.c:1480
static int set_eventmask(struct mansession *s, const char *eventmask)
Rather than braindead on,off this now can also accept a specific int mask value or a ',...
Definition: manager.c:3273
static const struct permalias perms[]
int num
Definition: manager.c:2023
#define ARRAY_LEN(a)
Definition: utils.h:661

References ARRAY_LEN, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), broken_events_action, permalias::num, perms, and set_eventmask().

Referenced by __init_manager().

◆ action_extensionstate()

static int action_extensionstate ( struct mansession s,
const struct message m 
)
static

Definition at line 5980 of file manager.c.

5981 {
5982  const char *exten = astman_get_header(m, "Exten");
5983  const char *context = astman_get_header(m, "Context");
5984  char hint[256];
5985  int status;
5986 
5987  if (ast_strlen_zero(exten)) {
5988  astman_send_error(s, m, "Extension not specified");
5989  return 0;
5990  }
5991  if (ast_strlen_zero(context)) {
5992  context = "default";
5993  }
5995  hint[0] = '\0';
5996  ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
5997  astman_start_ack(s, m);
5998  astman_append(s, "Message: Extension Status\r\n"
5999  "Exten: %s\r\n"
6000  "Context: %s\r\n"
6001  "Hint: %s\r\n"
6002  "Status: %d\r\n"
6003  "StatusText: %s\r\n"
6004  "\r\n",
6005  exten, context, hint, status,
6007  return 0;
6008 }
jack_status_t status
Definition: app_jack.c:146
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:3133
int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
If an extension hint exists, return non-zero.
Definition: pbx.c:4144
int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
Uses hint and devicestate callback to get the state of an extension.
Definition: pbx.c:3177

References ast_extension_state(), ast_extension_state2str(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), context, exten, NULL, and status.

Referenced by __init_manager().

◆ action_filter()

static int action_filter ( struct mansession s,
const struct message m 
)
static

Manager command to add an event filter to a manager session.

See also
For more details look at manager_add_filter

Definition at line 6117 of file manager.c.

6118 {
6119  const char *filter = astman_get_header(m, "Filter");
6120  const char *operation = astman_get_header(m, "Operation");
6121  int res;
6122 
6123  if (!strcasecmp(operation, "Add")) {
6125 
6126  if (res != FILTER_SUCCESS) {
6127  if (res == FILTER_ALLOC_FAILED) {
6128  astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
6129  return 0;
6130  } else if (res == FILTER_COMPILE_FAIL) {
6131  astman_send_error(s, m, "Filter did not compile. Check the syntax of the filter given.");
6132  return 0;
6133  } else {
6134  astman_send_error(s, m, "Internal Error. Failed adding filter.");
6135  return 0;
6136  }
6137  }
6138 
6139  astman_send_ack(s, m, "Success");
6140  return 0;
6141  }
6142 
6143  astman_send_error(s, m, "Unknown operation");
6144  return 0;
6145 }
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:734
static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
Add an event filter to a manager session.
Definition: manager.c:6169
struct ao2_container * whitefilters
Definition: manager.c:1606
struct ao2_container * blackfilters
Definition: manager.c:1607

References astman_get_header(), astman_send_ack(), astman_send_error(), mansession_session::blackfilters, filter(), FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL, FILTER_SUCCESS, manager_add_filter(), mansession::session, and mansession_session::whitefilters.

Referenced by __init_manager().

◆ action_find()

static struct manager_action* action_find ( const char *  name)
static

Definition at line 1711 of file manager.c.

1712 {
1713  struct manager_action *act;
1714 
1716  AST_RWLIST_TRAVERSE(&actions, act, list) {
1717  if (!strcasecmp(name, act->action)) {
1718  ao2_t_ref(act, +1, "found action object");
1719  break;
1720  }
1721  }
1723 
1724  return act;
1725 }
#define ao2_t_ref(o, delta, tag)
Definition: astobj2.h:460
list of actions registered
Definition: manager.c:1672
const char * action
Definition: manager.h:156

References manager_action::action, ao2_t_ref, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and name.

Referenced by ast_hook_send_action(), and process_message().

◆ action_getconfig()

static int action_getconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 3627 of file manager.c.

3628 {
3629  struct ast_config *cfg;
3630  const char *fn = astman_get_header(m, "Filename");
3631  const char *category = astman_get_header(m, "Category");
3632  const char *filter = astman_get_header(m, "Filter");
3633  const char *category_name;
3634  int catcount = 0;
3635  int lineno = 0;
3636  struct ast_category *cur_category = NULL;
3637  struct ast_variable *v;
3638  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
3639 
3640  if (ast_strlen_zero(fn)) {
3641  astman_send_error(s, m, "Filename not specified");
3642  return 0;
3643  }
3644 
3645  cfg = ast_config_load2(fn, "manager", config_flags);
3646  if (cfg == CONFIG_STATUS_FILEMISSING) {
3647  astman_send_error(s, m, "Config file not found");
3648  return 0;
3649  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3650  astman_send_error(s, m, "Config file has invalid format");
3651  return 0;
3652  }
3653 
3654  astman_start_ack(s, m);
3655  while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
3656  struct ast_str *templates;
3657 
3658  category_name = ast_category_get_name(cur_category);
3659  lineno = 0;
3660  astman_append(s, "Category-%06d: %s\r\n", catcount, category_name);
3661 
3662  if (ast_category_is_template(cur_category)) {
3663  astman_append(s, "IsTemplate-%06d: %d\r\n", catcount, 1);
3664  }
3665 
3666  if ((templates = ast_category_get_templates(cur_category))
3667  && ast_str_strlen(templates) > 0) {
3668  astman_append(s, "Templates-%06d: %s\r\n", catcount, ast_str_buffer(templates));
3670  }
3671 
3672  for (v = ast_category_first(cur_category); v; v = v->next) {
3673  astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
3674  }
3675 
3676  catcount++;
3677  }
3678 
3679  if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
3680  astman_append(s, "No categories found\r\n");
3681  }
3682 
3683  ast_config_destroy(cfg);
3684  astman_append(s, "\r\n");
3685 
3686  return 0;
3687 }
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1102
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
Definition: main/config.c:1409
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1231
#define CONFIG_STATUS_FILEMISSING
struct ast_str * ast_category_get_templates(const struct ast_category *category)
Return the template names this category inherits from.
Definition: main/config.c:1112
@ CONFIG_FLAG_NOCACHE
@ CONFIG_FLAG_WITHCOMMENTS
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
int ast_category_is_template(const struct ast_category *category)
Check if category is a template.
Definition: main/config.c:1107
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3220
static struct templates templates
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:711
Structure used to handle boolean flags.
Definition: utils.h:199
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

References ast_category_browse_filtered(), ast_category_first(), ast_category_get_name(), ast_category_get_templates(), ast_category_is_template(), ast_config_destroy(), ast_config_load2(), ast_free, ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, filter(), ast_variable::name, ast_variable::next, NULL, templates, and ast_variable::value.

Referenced by __init_manager().

◆ action_getconfigjson()

static int action_getconfigjson ( struct mansession s,
const struct message m 
)
static

Definition at line 3755 of file manager.c.

3756 {
3757  struct ast_config *cfg;
3758  const char *fn = astman_get_header(m, "Filename");
3759  const char *filter = astman_get_header(m, "Filter");
3760  const char *category = astman_get_header(m, "Category");
3761  struct ast_category *cur_category = NULL;
3762  const char *category_name;
3763  struct ast_variable *v;
3764  int comma1 = 0;
3765  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
3766 
3767  if (ast_strlen_zero(fn)) {
3768  astman_send_error(s, m, "Filename not specified");
3769  return 0;
3770  }
3771 
3772  if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
3773  astman_send_error(s, m, "Config file not found");
3774  return 0;
3775  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3776  astman_send_error(s, m, "Config file has invalid format");
3777  return 0;
3778  }
3779 
3780  astman_start_ack(s, m);
3781  astman_append(s, "JSON: {");
3782  while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
3783  int comma2 = 0;
3784  struct ast_str *templates;
3785 
3786  category_name = ast_category_get_name(cur_category);
3787  astman_append(s, "%s\"", comma1 ? "," : "");
3788  astman_append_json(s, category_name);
3789  astman_append(s, "\":{");
3790  comma1 = 1;
3791 
3792  if (ast_category_is_template(cur_category)) {
3793  astman_append(s, "\"istemplate\":1");
3794  comma2 = 1;
3795  }
3796 
3797  if ((templates = ast_category_get_templates(cur_category))
3798  && ast_str_strlen(templates) > 0) {
3799  astman_append(s, "%s", comma2 ? "," : "");
3800  astman_append(s, "\"templates\":\"%s\"", ast_str_buffer(templates));
3802  comma2 = 1;
3803  }
3804 
3805  for (v = ast_category_first(cur_category); v; v = v->next) {
3806  astman_append(s, "%s\"", comma2 ? "," : "");
3807  astman_append_json(s, v->name);
3808  astman_append(s, "\":\"");
3809  astman_append_json(s, v->value);
3810  astman_append(s, "\"");
3811  comma2 = 1;
3812  }
3813 
3814  astman_append(s, "}");
3815  }
3816  astman_append(s, "}\r\n\r\n");
3817 
3818  ast_config_destroy(cfg);
3819 
3820  return 0;
3821 }
static void astman_append_json(struct mansession *s, const char *str)
Definition: manager.c:3746

References ast_category_browse_filtered(), ast_category_first(), ast_category_get_name(), ast_category_get_templates(), ast_category_is_template(), ast_config_destroy(), ast_config_load2(), ast_free, ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), astman_append(), astman_append_json(), astman_get_header(), astman_send_error(), astman_start_ack(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, filter(), ast_variable::name, ast_variable::next, NULL, templates, and ast_variable::value.

Referenced by __init_manager().

◆ action_getvar()

static int action_getvar ( struct mansession s,
const struct message m 
)
static

Definition at line 4615 of file manager.c.

4616 {
4617  struct ast_channel *c = NULL;
4618  const char *name = astman_get_header(m, "Channel");
4619  const char *varname = astman_get_header(m, "Variable");
4620  char *varval;
4621  char workspace[1024];
4622 
4623  if (ast_strlen_zero(varname)) {
4624  astman_send_error(s, m, "No variable specified");
4625  return 0;
4626  }
4627 
4628  /* We don't want users with insufficient permissions using certain functions. */
4630  astman_send_error(s, m, "GetVar Access Forbidden: Variable");
4631  return 0;
4632  }
4633 
4634  if (!ast_strlen_zero(name)) {
4635  if (!(c = ast_channel_get_by_name(name))) {
4636  astman_send_error(s, m, "No such channel");
4637  return 0;
4638  }
4639  }
4640 
4641  workspace[0] = '\0';
4642  if (varname[strlen(varname) - 1] == ')') {
4643  if (!c) {
4645  if (c) {
4646  ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
4647  } else
4648  ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
4649  } else {
4650  ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
4651  }
4652  varval = workspace;
4653  } else {
4654  pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
4655  }
4656 
4657  if (c) {
4658  c = ast_channel_unref(c);
4659  }
4660 
4661  astman_start_ack(s, m);
4662  astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
4663 
4664  return 0;
4665 }
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1282
static int function_capable_string_allowed_with_auths(const char *evaluating, int writepermlist)
Checks to see if a string which can be used to evaluate functions should be rejected.
Definition: manager.c:2053
#define LOG_ERROR
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
Retrieve the value of a builtin variable or variable from the channel variable stack.
#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 struct test_val c

References ast_channel_get_by_name(), ast_channel_unref, ast_dummy_channel_alloc, ast_func_read(), ast_log, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), c, function_capable_string_allowed_with_auths(), LOG_ERROR, name, NULL, pbx_retrieve_variable(), S_OR, mansession::session, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_hangup()

static int action_hangup ( struct mansession s,
const struct message m 
)
static

Definition at line 4465 of file manager.c.

4466 {
4467  struct ast_channel *c = NULL;
4468  int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
4469  const char *id = astman_get_header(m, "ActionID");
4470  const char *name_or_regex = astman_get_header(m, "Channel");
4471  const char *cause = astman_get_header(m, "Cause");
4472  char idText[256];
4473  regex_t regexbuf;
4474  struct ast_channel_iterator *iter = NULL;
4475  struct ast_str *regex_string;
4476  int channels_matched = 0;
4477 
4478  if (ast_strlen_zero(name_or_regex)) {
4479  astman_send_error(s, m, "No channel specified");
4480  return 0;
4481  }
4482 
4483  if (!ast_strlen_zero(id)) {
4484  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
4485  } else {
4486  idText[0] = '\0';
4487  }
4488 
4489  if (!ast_strlen_zero(cause)) {
4490  char *endptr;
4491  causecode = strtol(cause, &endptr, 10);
4492  if (causecode < 0 || causecode > 127 || *endptr != '\0') {
4493  ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
4494  /* keep going, better to hangup without cause than to not hang up at all */
4495  causecode = 0; /* do not set channel's hangupcause */
4496  }
4497  }
4498 
4499  /************************************************/
4500  /* Regular explicit match channel byname hangup */
4501 
4502  if (name_or_regex[0] != '/') {
4503  if (!(c = ast_channel_get_by_name(name_or_regex))) {
4504  ast_log(LOG_NOTICE, "Request to hangup non-existent channel: %s\n",
4505  name_or_regex);
4506  astman_send_error(s, m, "No such channel");
4507  return 0;
4508  }
4509 
4510  ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
4511  (s->session->managerid ? "HTTP " : ""),
4512  s->session->username,
4514  ast_channel_name(c));
4515 
4517  c = ast_channel_unref(c);
4518 
4519  astman_send_ack(s, m, "Channel Hungup");
4520 
4521  return 0;
4522  }
4523 
4524  /***********************************************/
4525  /* find and hangup any channels matching regex */
4526 
4527  regex_string = ast_str_create(strlen(name_or_regex));
4528  if (!regex_string) {
4529  astman_send_error(s, m, "Memory Allocation Failure");
4530  return 0;
4531  }
4532 
4533  /* Make "/regex/" into "regex" */
4534  if (ast_regex_string_to_regex_pattern(name_or_regex, &regex_string) != 0) {
4535  astman_send_error(s, m, "Regex format invalid, Channel param should be /regex/");
4536  ast_free(regex_string);
4537  return 0;
4538  }
4539 
4540  /* if regex compilation fails, hangup fails */
4541  if (regcomp(&regexbuf, ast_str_buffer(regex_string), REG_EXTENDED | REG_NOSUB)) {
4542  astman_send_error_va(s, m, "Regex compile failed on: %s", name_or_regex);
4543  ast_free(regex_string);
4544  return 0;
4545  }
4546 
4547  astman_send_listack(s, m, "Channels hung up will follow", "start");
4548 
4550  if (iter) {
4551  for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
4552  if (regexec(&regexbuf, ast_channel_name(c), 0, NULL, 0)) {
4553  continue;
4554  }
4555 
4556  ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
4557  (s->session->managerid ? "HTTP " : ""),
4558  s->session->username,
4560  ast_channel_name(c));
4561 
4563  channels_matched++;
4564 
4565  astman_append(s,
4566  "Event: ChannelHungup\r\n"
4567  "Channel: %s\r\n"
4568  "%s"
4569  "\r\n", ast_channel_name(c), idText);
4570  }
4572  }
4573 
4574  regfree(&regexbuf);
4575  ast_free(regex_string);
4576 
4577  astman_send_list_complete(s, m, "ChannelsHungupListComplete", channels_matched);
4578 
4579  return 0;
4580 }
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1354
void ast_channel_softhangup_withcause_locked(struct ast_channel *chan, int causecode)
Lock the given channel, then request softhangup on the channel with the given causecode.
Definition: channel.c:468
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1402
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1416
#define ast_verb(level,...)
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:640
int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
Given a string regex_string in the form of "/regex/", convert it into the form of "regex".
Definition: main/utils.c:2077
struct ast_sockaddr addr
Definition: manager.c:1590
uint32_t managerid
Definition: manager.c:1595
char username[80]
Definition: manager.c:1599

References mansession_session::addr, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_name(), ast_channel_softhangup_withcause_locked(), ast_channel_unref, ast_free, ast_log, ast_regex_string_to_regex_pattern(), ast_sockaddr_stringify_addr(), ast_str_buffer(), ast_str_create, ast_strlen_zero(), ast_verb, astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), astman_send_error_va(), astman_send_list_complete(), astman_send_listack(), c, LOG_NOTICE, mansession_session::managerid, NULL, mansession::session, and mansession_session::username.

Referenced by __init_manager().

◆ action_listcategories()

static int action_listcategories ( struct mansession s,
const struct message m 
)
static

Definition at line 3689 of file manager.c.

3690 {
3691  struct ast_config *cfg;
3692  const char *fn = astman_get_header(m, "Filename");
3693  const char *match = astman_get_header(m, "Match");
3694  struct ast_category *category = NULL;
3695  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
3696  int catcount = 0;
3697 
3698  if (ast_strlen_zero(fn)) {
3699  astman_send_error(s, m, "Filename not specified");
3700  return 0;
3701  }
3702 
3703  if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
3704  astman_send_error(s, m, "Config file not found");
3705  return 0;
3706  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3707  astman_send_error(s, m, "Config file has invalid format");
3708  return 0;
3709  }
3710 
3711  astman_start_ack(s, m);
3712  while ((category = ast_category_browse_filtered(cfg, NULL, category, match))) {
3713  astman_append(s, "Category-%06d: %s\r\n", catcount, ast_category_get_name(category));
3714  catcount++;
3715  }
3716 
3717  if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
3718  astman_append(s, "Error: no categories found\r\n");
3719  }
3720 
3721  ast_config_destroy(cfg);
3722  astman_append(s, "\r\n");
3723 
3724  return 0;
3725 }
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2312

References ast_category_browse_filtered(), ast_category_get_name(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, match(), and NULL.

Referenced by __init_manager().

◆ action_listcommands()

static int action_listcommands ( struct mansession s,
const struct message m 
)
static

Definition at line 4329 of file manager.c.

4330 {
4331  struct manager_action *cur;
4333 
4334  astman_start_ack(s, m);
4336  AST_RWLIST_TRAVERSE(&actions, cur, list) {
4337  if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
4338  astman_append(s, "%s: %s (Priv: %s)\r\n",
4339  cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
4340  }
4341  }
4343  astman_append(s, "\r\n");
4344 
4345  return 0;
4346 }

References manager_action::action, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, astman_append(), astman_start_ack(), manager_action::authority, authority_to_str(), MAX_AUTH_PERM_STRING, mansession::session, manager_action::synopsis, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_loggerrotate()

static int action_loggerrotate ( struct mansession s,
const struct message m 
)
static

Manager command "LoggerRotate" - reloads and rotates the logger in the same manner as the CLI command 'logger rotate'.

Definition at line 6465 of file manager.c.

6466 {
6467  if (ast_logger_rotate()) {
6468  astman_send_error(s, m, "Failed to reload the logger and rotate log files");
6469  return 0;
6470  }
6471 
6472  astman_send_ack(s, m, "Reloaded the logger and rotated log files");
6473  return 0;
6474 }
int ast_logger_rotate(void)
Reload logger while rotating log files.
Definition: logger.c:1314

References ast_logger_rotate(), astman_send_ack(), and astman_send_error().

Referenced by __init_manager().

◆ action_login()

static int action_login ( struct mansession s,
const struct message m 
)
static

Definition at line 4398 of file manager.c.

4399 {
4400 
4401  /* still authenticated - don't process again */
4402  if (s->session->authenticated) {
4403  astman_send_ack(s, m, "Already authenticated");
4404  return 0;
4405  }
4406 
4407  if (authenticate(s, m)) {
4408  sleep(1);
4409  astman_send_error(s, m, "Authentication failed");
4410  return -1;
4411  }
4412  s->session->authenticated = 1;
4414  if (manager_displayconnects(s->session)) {
4415  ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
4416  }
4417  astman_send_ack(s, m, "Authentication accepted");
4422  const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
4423  long uptime = 0;
4424  long lastreloaded = 0;
4425  struct timeval tmp;
4426  struct timeval curtime = ast_tvnow();
4427 
4428  if (ast_startuptime.tv_sec) {
4429  tmp = ast_tvsub(curtime, ast_startuptime);
4430  uptime = tmp.tv_sec;
4431  }
4432 
4433  if (ast_lastreloadtime.tv_sec) {
4434  tmp = ast_tvsub(curtime, ast_lastreloadtime);
4435  lastreloaded = tmp.tv_sec;
4436  }
4437 
4438  astman_append(s, "Event: FullyBooted\r\n"
4439  "Privilege: %s\r\n"
4440  "Uptime: %ld\r\n"
4441  "LastReload: %ld\r\n"
4442  "Status: Fully Booted\r\n\r\n", cat_str, uptime, lastreloaded);
4443  }
4444  return 0;
4445 }
static int tmp()
Definition: bt_open.c:389
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:2329
static int unauth_sessions
Definition: manager.c:1493
static int authenticate(struct mansession *s, const struct message *m)
Definition: manager.c:3512
struct ast_flags ast_options
Definition: options.c:61
@ AST_OPT_FLAG_FULLY_BOOTED
Definition: options.h:58
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2297
#define ast_test_flag(p, flag)
Definition: utils.h:63

References mansession_session::addr, ast_atomic_fetchadd_int(), ast_lastreloadtime, AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_sockaddr_stringify_addr(), ast_startuptime, ast_str_alloca, ast_test_flag, ast_tvnow(), ast_tvsub(), ast_verb, astman_append(), astman_send_ack(), astman_send_error(), authenticate(), mansession_session::authenticated, authority_to_str(), EVENT_FLAG_SYSTEM, manager_displayconnects(), mansession_session::managerid, MAX_AUTH_PERM_STRING, mansession_session::readperm, mansession_session::send_events, mansession::session, tmp(), unauth_sessions, and mansession_session::username.

Referenced by __init_manager().

◆ action_logoff()

static int action_logoff ( struct mansession s,
const struct message m 
)
static

Definition at line 4392 of file manager.c.

4393 {
4394  astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
4395  return -1;
4396 }
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition: manager.c:3161

References astman_send_response().

Referenced by __init_manager().

◆ action_mailboxcount()

static int action_mailboxcount ( struct mansession s,
const struct message m 
)
static

Definition at line 5959 of file manager.c.

5960 {
5961  const char *mailbox = astman_get_header(m, "Mailbox");
5962  int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
5963 
5964  if (ast_strlen_zero(mailbox)) {
5965  astman_send_error(s, m, "Mailbox not specified");
5966  return 0;
5967  }
5968  ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
5969  astman_start_ack(s, m);
5970  astman_append(s, "Message: Mailbox Message Count\r\n"
5971  "Mailbox: %s\r\n"
5972  "UrgMessages: %d\r\n"
5973  "NewMessages: %d\r\n"
5974  "OldMessages: %d\r\n"
5975  "\r\n",
5976  mailbox, urgentmsgs, newmsgs, oldmsgs);
5977  return 0;
5978 }
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:207
int ast_app_inboxcount2(const char *mailboxes, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Determine number of urgent/new/old messages in a mailbox.
Definition: main/app.c:689

References ast_app_inboxcount2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and mailbox.

Referenced by __init_manager().

◆ action_mailboxstatus()

static int action_mailboxstatus ( struct mansession s,
const struct message m 
)
static

Definition at line 5942 of file manager.c.

5943 {
5944  const char *mailbox = astman_get_header(m, "Mailbox");
5945  int ret;
5946 
5947  if (ast_strlen_zero(mailbox)) {
5948  astman_send_error(s, m, "Mailbox not specified");
5949  return 0;
5950  }
5952  astman_start_ack(s, m);
5953  astman_append(s, "Message: Mailbox Status\r\n"
5954  "Mailbox: %s\r\n"
5955  "Waiting: %d\r\n\r\n", mailbox, ret);
5956  return 0;
5957 }
int ast_app_has_voicemail(const char *mailboxes, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX"....
Definition: main/app.c:652

References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mailbox, and NULL.

Referenced by __init_manager().

◆ action_originate()

static int action_originate ( struct mansession s,
const struct message m 
)
static

Definition at line 5729 of file manager.c.

5730 {
5731  const char *name = astman_get_header(m, "Channel");
5732  const char *exten = astman_get_header(m, "Exten");
5733  const char *context = astman_get_header(m, "Context");
5734  const char *priority = astman_get_header(m, "Priority");
5735  const char *timeout = astman_get_header(m, "Timeout");
5736  const char *callerid = astman_get_header(m, "CallerID");
5737  const char *account = astman_get_header(m, "Account");
5738  const char *app = astman_get_header(m, "Application");
5739  const char *appdata = astman_get_header(m, "Data");
5740  const char *async = astman_get_header(m, "Async");
5741  const char *id = astman_get_header(m, "ActionID");
5742  const char *codecs = astman_get_header(m, "Codecs");
5743  const char *early_media = astman_get_header(m, "Earlymedia");
5744  struct ast_assigned_ids assignedids = {
5745  .uniqueid = astman_get_header(m, "ChannelId"),
5746  .uniqueid2 = astman_get_header(m, "OtherChannelId"),
5747  };
5748  struct ast_variable *vars = NULL;
5749  char *tech, *data;
5750  char *l = NULL, *n = NULL;
5751  int pi = 0;
5752  int res;
5753  int to = 30000;
5754  int reason = 0;
5755  char tmp[256];
5756  char tmp2[256];
5758  pthread_t th;
5759  int bridge_early = 0;
5760 
5761  if (!cap) {
5762  astman_send_error(s, m, "Internal Error. Memory allocation failure.");
5763  return 0;
5764  }
5766 
5767  if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
5768  || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
5769  astman_send_error_va(s, m, "Uniqueid length exceeds maximum of %d\n",
5771  res = 0;
5772  goto fast_orig_cleanup;
5773  }
5774 
5775  if (ast_strlen_zero(name)) {
5776  astman_send_error(s, m, "Channel not specified");
5777  res = 0;
5778  goto fast_orig_cleanup;
5779  }
5780  if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
5781  if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
5782  astman_send_error(s, m, "Invalid priority");
5783  res = 0;
5784  goto fast_orig_cleanup;
5785  }
5786  }
5787  if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
5788  astman_send_error(s, m, "Invalid timeout");
5789  res = 0;
5790  goto fast_orig_cleanup;
5791  }
5792  ast_copy_string(tmp, name, sizeof(tmp));
5793  tech = tmp;
5794  data = strchr(tmp, '/');
5795  if (!data) {
5796  astman_send_error(s, m, "Invalid channel");
5797  res = 0;
5798  goto fast_orig_cleanup;
5799  }
5800  *data++ = '\0';
5801  ast_copy_string(tmp2, callerid, sizeof(tmp2));
5802  ast_callerid_parse(tmp2, &n, &l);
5803  if (n) {
5804  if (ast_strlen_zero(n)) {
5805  n = NULL;
5806  }
5807  }
5808  if (l) {
5810  if (ast_strlen_zero(l)) {
5811  l = NULL;
5812  }
5813  }
5814  if (!ast_strlen_zero(codecs)) {
5817  }
5818 
5819  if (!ast_strlen_zero(app) && s->session) {
5820  int bad_appdata = 0;
5821  /* To run the System application (or anything else that goes to
5822  * shell), you must have the additional System privilege */
5823  if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
5824  && (
5825  strcasestr(app, "system") || /* System(rm -rf /)
5826  TrySystem(rm -rf /) */
5827  strcasestr(app, "exec") || /* Exec(System(rm -rf /))
5828  TryExec(System(rm -rf /)) */
5829  strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /)
5830  EAGI(/bin/rm,-rf /) */
5831  strcasestr(app, "mixmonitor") || /* MixMonitor(blah,,rm -rf) */
5832  strcasestr(app, "externalivr") || /* ExternalIVR(rm -rf) */
5833  strcasestr(app, "originate") || /* Originate(Local/1234,app,System,rm -rf) */
5834  (strstr(appdata, "SHELL") && (bad_appdata = 1)) || /* NoOp(${SHELL(rm -rf /)}) */
5835  (strstr(appdata, "EVAL") && (bad_appdata = 1)) /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
5836  )) {
5837  char error_buf[64];
5838  snprintf(error_buf, sizeof(error_buf), "Originate Access Forbidden: %s", bad_appdata ? "Data" : "Application");
5839  astman_send_error(s, m, error_buf);
5840  res = 0;
5841  goto fast_orig_cleanup;
5842  }
5843  }
5844 
5845  /* Check early if the extension exists. If not, we need to bail out here. */
5846  if (exten && context && pi) {
5847  if (! ast_exists_extension(NULL, context, exten, pi, l)) {
5848  /* The extension does not exist. */
5849  astman_send_error(s, m, "Extension does not exist.");
5850  res = 0;
5851  goto fast_orig_cleanup;
5852  }
5853  }
5854 
5855  /* Allocate requested channel variables */
5856  vars = astman_get_variables(m);
5857  if (s->session && s->session->chanvars) {
5858  struct ast_variable *v, *old;
5859  old = vars;
5860  vars = NULL;
5861 
5862  /* The variables in the AMI originate action are appended at the end of the list, to override any user variables that apply*/
5863 
5864  vars = ast_variables_dup(s->session->chanvars);
5865  if (old) {
5866  for (v = vars; v->next; v = v->next );
5867  if (v->next) {
5868  v->next = old; /* Append originate variables at end of list */
5869  }
5870  }
5871  }
5872 
5873  /* For originate async - we can bridge in early media stage */
5874  bridge_early = ast_true(early_media);
5875 
5876  if (ast_true(async)) {
5877  struct fast_originate_helper *fast;
5878 
5879  fast = ast_calloc(1, sizeof(*fast));
5880  if (!fast || ast_string_field_init(fast, 252)) {
5881  ast_free(fast);
5883  res = -1;
5884  } else {
5885  if (!ast_strlen_zero(id)) {
5886  ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
5887  }
5888  ast_string_field_set(fast, tech, tech);
5889  ast_string_field_set(fast, data, data);
5890  ast_string_field_set(fast, app, app);
5892  ast_string_field_set(fast, cid_num, l);
5893  ast_string_field_set(fast, cid_name, n);
5897  ast_string_field_set(fast, channelid, assignedids.uniqueid);
5898  ast_string_field_set(fast, otherchannelid, assignedids.uniqueid2);
5899  fast->vars = vars;
5900  fast->cap = cap;
5901  cap = NULL; /* transfered originate helper the capabilities structure. It is now responsible for freeing it. */
5902  fast->timeout = to;
5903  fast->early_media = bridge_early;
5904  fast->priority = pi;
5905  if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
5907  res = -1;
5908  } else {
5909  res = 0;
5910  }
5911  }
5912  } else if (!ast_strlen_zero(app)) {
5913  res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason,
5915  assignedids.uniqueid ? &assignedids : NULL);
5917  } else {
5918  if (exten && context && pi) {
5919  res = ast_pbx_outgoing_exten(tech, cap, data, to,
5920  context, exten, pi, &reason, AST_OUTGOING_WAIT,
5921  l, n, vars, account, NULL, bridge_early,
5922  assignedids.uniqueid ? &assignedids : NULL);
5924  } else {
5925  astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
5927  res = 0;
5928  goto fast_orig_cleanup;
5929  }
5930  }
5931  if (!res) {
5932  astman_send_ack(s, m, "Originate successfully queued");
5933  } else {
5934  astman_send_error(s, m, "Originate failed");
5935  }
5936 
5937 fast_orig_cleanup:
5938  ao2_cleanup(cap);
5939  return 0;
5940 }
static const char app[]
Definition: app_adsiprog.c:56
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1008
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
Definition: callerid.c:947
static int priority
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:167
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:168
#define AST_MAX_PUBLIC_UNIQUEID
Definition: channel.h:147
static struct ao2_container * codecs
Registered codecs.
Definition: codec.c:48
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:523
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
struct ast_variable * astman_get_variables(const struct message *m)
Get a linked list of the Variable: headers.
Definition: manager.c:2913
static void destroy_fast_originate_helper(struct fast_originate_helper *doomed)
Definition: manager.c:5411
static void * fast_originate(void *data)
Definition: manager.c:5419
char * strcasestr(const char *, const char *)
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:543
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
Find the priority of an extension that has the specified label.
Definition: pbx.c:4187
@ AST_OUTGOING_WAIT
Definition: pbx.h:1148
int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, const struct ast_assigned_ids *assignedids)
Synchronously or asynchronously make an outbound call and execute an application on the channel.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4182
int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids)
Synchronously or asynchronously make an outbound call and send it to a particular extension.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: main/utils.c:2097
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:406
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
const char * uniqueid2
Definition: channel.h:606
const char * uniqueid
Definition: channel.h:605
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
helper function for originate
Definition: manager.c:5383
const ast_string_field appdata
Definition: manager.c:5401
struct ast_variable * vars
Definition: manager.c:5403
const ast_string_field account
Definition: manager.c:5401
const ast_string_field tech
Definition: manager.c:5401
const ast_string_field data
Definition: manager.c:5401
const ast_string_field channelid
Definition: manager.c:5401
const ast_string_field otherchannelid
Definition: manager.c:5401
struct ast_format_cap * cap
Definition: manager.c:5385
const ast_string_field idtext
Definition: manager.c:5401
struct ast_variable * chanvars
Definition: manager.c:1608
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:583

References ao2_cleanup, app, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_exists_extension(), ast_findlabel_extension(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_remove_by_type(), ast_format_cap_update_by_allow_disallow(), ast_format_slin, ast_free, AST_MAX_PUBLIC_UNIQUEID, AST_MEDIA_TYPE_UNKNOWN, AST_OUTGOING_WAIT, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create_detached, ast_shrink_phone_number(), ast_string_field_build, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_true(), ast_variables_destroy(), ast_variables_dup(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), astman_send_error_va(), fast_originate_helper::cap, mansession_session::chanvars, cid_name, cid_num, codecs, context, destroy_fast_originate_helper(), fast_originate_helper::early_media, EVENT_FLAG_SYSTEM, exten, fast_originate(), name, ast_variable::next, NULL, priority, fast_originate_helper::priority, mansession::session, strcasestr(), fast_originate_helper::timeout, tmp(), ast_assigned_ids::uniqueid, ast_assigned_ids::uniqueid2, fast_originate_helper::vars, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_ping()

static int action_ping ( struct mansession s,
const struct message m 
)
static

Definition at line 3609 of file manager.c.

3610 {
3611  const char *actionid = astman_get_header(m, "ActionID");
3612  struct timeval now = ast_tvnow();
3613 
3614  astman_append(s, "Response: Success\r\n");
3615  if (!ast_strlen_zero(actionid)){
3616  astman_append(s, "ActionID: %s\r\n", actionid);
3617  }
3618  astman_append(
3619  s,
3620  "Ping: Pong\r\n"
3621  "Timestamp: %ld.%06lu\r\n"
3622  "\r\n",
3623  (long) now.tv_sec, (unsigned long) now.tv_usec);
3624  return 0;
3625 }

References ast_strlen_zero(), ast_tvnow(), astman_append(), and astman_get_header().

Referenced by __init_manager().

◆ action_presencestate()

static int action_presencestate ( struct mansession s,
const struct message m 
)
static

Definition at line 6010 of file manager.c.

6011 {
6012  const char *provider = astman_get_header(m, "Provider");
6014  char *subtype;
6015  char *message;
6016 
6017  if (ast_strlen_zero(provider)) {
6018  astman_send_error(s, m, "No provider specified");
6019  return 0;
6020  }
6021 
6022  state = ast_presence_state(provider, &subtype, &message);
6023  if (state == AST_PRESENCE_INVALID) {
6024  astman_send_error_va(s, m, "Invalid provider %s or provider in invalid state", provider);
6025  return 0;
6026  }
6027 
6028  astman_start_ack(s, m);
6029  astman_append(s, "Message: Presence State\r\n"
6030  "State: %s\r\n", ast_presence_state2str(state));
6031 
6032  if (!ast_strlen_zero(subtype)) {
6033  astman_append(s, "Subtype: %s\r\n", subtype);
6034  }
6035 
6036  if (!ast_strlen_zero(message)) {
6037  /* XXX The Message header here is deprecated as it
6038  * duplicates the action response header 'Message'.
6039  * Remove it in the next major revision of AMI.
6040  */
6041  astman_append(s, "Message: %s\r\n"
6042  "PresenceMessage: %s\r\n",
6043  message, message);
6044  }
6045  astman_append(s, "\r\n");
6046 
6047  return 0;
6048 }
static struct prometheus_metrics_provider provider
Definition: bridges.c:178
enum sip_cc_notify_state state
Definition: chan_sip.c:966
ast_presence_state
Definition: presencestate.h:26
@ AST_PRESENCE_INVALID
Definition: presencestate.h:39
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.

References AST_PRESENCE_INVALID, ast_presence_state2str(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_error_va(), astman_start_ack(), provider, and state.

Referenced by __init_manager().

◆ action_redirect()

static int action_redirect ( struct mansession s,
const struct message m 
)
static

action_redirect: The redirect manager command

Definition at line 4981 of file manager.c.

4982 {
4983  char buf[256];
4984  const char *name = astman_get_header(m, "Channel");
4985  const char *name2 = astman_get_header(m, "ExtraChannel");
4986  const char *exten = astman_get_header(m, "Exten");
4987  const char *exten2 = astman_get_header(m, "ExtraExten");
4988  const char *context = astman_get_header(m, "Context");
4989  const char *context2 = astman_get_header(m, "ExtraContext");
4990  const char *priority = astman_get_header(m, "Priority");
4991  const char *priority2 = astman_get_header(m, "ExtraPriority");
4992  struct ast_channel *chan;
4993  struct ast_channel *chan2;
4994  int pi = 0;
4995  int pi2 = 0;
4996  int res;
4997  int chan1_wait = 0;
4998  int chan2_wait = 0;
4999 
5000  if (ast_strlen_zero(name)) {
5001  astman_send_error(s, m, "Channel not specified");
5002  return 0;
5003  }
5004 
5005  if (ast_strlen_zero(context)) {
5006  astman_send_error(s, m, "Context not specified");
5007  return 0;
5008  }
5009  if (ast_strlen_zero(exten)) {
5010  astman_send_error(s, m, "Exten not specified");
5011  return 0;
5012  }
5013  if (ast_strlen_zero(priority)) {
5014  astman_send_error(s, m, "Priority not specified");
5015  return 0;
5016  }
5017  if (sscanf(priority, "%30d", &pi) != 1) {
5019  }
5020  if (pi < 1) {
5021  astman_send_error(s, m, "Priority is invalid");
5022  return 0;
5023  }
5024 
5025  if (!ast_strlen_zero(name2) && !ast_strlen_zero(context2)) {
5026  /* We have an ExtraChannel and an ExtraContext */
5027  if (ast_strlen_zero(exten2)) {
5028  astman_send_error(s, m, "ExtraExten not specified");
5029  return 0;
5030  }
5031  if (ast_strlen_zero(priority2)) {
5032  astman_send_error(s, m, "ExtraPriority not specified");
5033  return 0;
5034  }
5035  if (sscanf(priority2, "%30d", &pi2) != 1) {
5036  pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL);
5037  }
5038  if (pi2 < 1) {
5039  astman_send_error(s, m, "ExtraPriority is invalid");
5040  return 0;
5041  }
5042  }
5043 
5044  chan = ast_channel_get_by_name(name);
5045  if (!chan) {
5046  snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
5047  astman_send_error(s, m, buf);
5048  return 0;
5049  }
5050  if (ast_check_hangup_locked(chan)) {
5051  astman_send_error(s, m, "Redirect failed, channel not up.");
5052  chan = ast_channel_unref(chan);
5053  return 0;
5054  }
5055 
5056  if (ast_strlen_zero(name2)) {
5057  /* Single channel redirect in progress. */
5058  res = ast_async_goto(chan, context, exten, pi);
5059  if (!res) {
5060  astman_send_ack(s, m, "Redirect successful");
5061  } else {
5062  astman_send_error(s, m, "Redirect failed");
5063  }
5064  chan = ast_channel_unref(chan);
5065  return 0;
5066  }
5067 
5068  chan2 = ast_channel_get_by_name(name2);
5069  if (!chan2) {
5070  snprintf(buf, sizeof(buf), "ExtraChannel does not exist: %s", name2);
5071  astman_send_error(s, m, buf);
5072  chan = ast_channel_unref(chan);
5073  return 0;
5074  }
5075  if (ast_check_hangup_locked(chan2)) {
5076  astman_send_error(s, m, "Redirect failed, extra channel not up.");
5077  chan2 = ast_channel_unref(chan2);
5078  chan = ast_channel_unref(chan);
5079  return 0;
5080  }
5081 
5082  /* Dual channel redirect in progress. */
5083  ast_channel_lock(chan);
5084  if (ast_channel_is_bridged(chan)) {
5086  chan1_wait = 1;
5087  }
5088  ast_channel_unlock(chan);
5089 
5090  ast_channel_lock(chan2);
5091  if (ast_channel_is_bridged(chan2)) {
5093  chan2_wait = 1;
5094  }
5095  ast_channel_unlock(chan2);
5096 
5097  res = ast_async_goto(chan, context, exten, pi);
5098  if (!res) {
5099  if (!ast_strlen_zero(context2)) {
5100  res = ast_async_goto(chan2, context2, exten2, pi2);
5101  } else {
5102  res = ast_async_goto(chan2, context, exten, pi);
5103  }
5104  if (!res) {
5105  astman_send_ack(s, m, "Dual Redirect successful");
5106  } else {
5107  astman_send_error(s, m, "Secondary redirect failed");
5108  }
5109  } else {
5110  astman_send_error(s, m, "Redirect failed");
5111  }
5112 
5113  /* Release the bridge wait. */
5114  if (chan1_wait) {
5116  }
5117  if (chan2_wait) {
5119  }
5120 
5121  chan2 = ast_channel_unref(chan2);
5122  chan = ast_channel_unref(chan);
5123  return 0;
5124 }
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11220
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
@ AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT
Definition: channel.h:1035
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10731
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ast_async_goto(), ast_channel_clear_flag(), ast_channel_flags(), ast_channel_get_by_name(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_check_hangup_locked(), ast_findlabel_extension(), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT, ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), buf, context, exten, name, NULL, and priority.

Referenced by __init_manager().

◆ action_reload()

static int action_reload ( struct mansession s,
const struct message m 
)
static

Send a reload event.

Definition at line 6365 of file manager.c.

6366 {
6367  const char *module = astman_get_header(m, "Module");
6368  enum ast_module_reload_result res = ast_module_reload(S_OR(module, NULL));
6369 
6370  switch (res) {
6372  astman_send_error(s, m, "No such module");
6373  break;
6375  astman_send_error(s, m, "Module does not support reload");
6376  break;
6378  astman_send_error(s, m, "An unknown error occurred");
6379  break;
6381  astman_send_error(s, m, "A reload is in progress");
6382  break;
6384  astman_send_error(s, m, "Module not initialized");
6385  break;
6388  /* Treat a queued request as success */
6389  astman_send_ack(s, m, "Module Reloaded");
6390  break;
6391  }
6392  return 0;
6393 }
ast_module_reload_result
Possible return types for ast_module_reload.
Definition: module.h:109
@ AST_MODULE_RELOAD_IN_PROGRESS
Definition: module.h:114
@ AST_MODULE_RELOAD_QUEUED
Definition: module.h:111
@ AST_MODULE_RELOAD_SUCCESS
Definition: module.h:110
@ AST_MODULE_RELOAD_ERROR
Definition: module.h:113
@ AST_MODULE_RELOAD_NOT_IMPLEMENTED
Definition: module.h:116
@ AST_MODULE_RELOAD_NOT_FOUND
Definition: module.h:112
@ AST_MODULE_RELOAD_UNINITIALIZED
Definition: module.h:115
enum ast_module_reload_result ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:1562

References ast_module_reload(), AST_MODULE_RELOAD_ERROR, AST_MODULE_RELOAD_IN_PROGRESS, AST_MODULE_RELOAD_NOT_FOUND, AST_MODULE_RELOAD_NOT_IMPLEMENTED, AST_MODULE_RELOAD_QUEUED, AST_MODULE_RELOAD_SUCCESS, AST_MODULE_RELOAD_UNINITIALIZED, astman_get_header(), astman_send_ack(), astman_send_error(), NULL, and S_OR.

Referenced by __init_manager().

◆ action_sendtext()

static int action_sendtext ( struct mansession s,
const struct message m 
)
static

Definition at line 4938 of file manager.c.

4939 {
4940  struct ast_channel *c;
4941  const char *name = astman_get_header(m, "Channel");
4942  const char *textmsg = astman_get_header(m, "Message");
4943  const char *content_type = astman_get_header(m, "Content-Type");
4944  int res;
4945 
4946  if (ast_strlen_zero(name)) {
4947  astman_send_error(s, m, "No channel specified");
4948  return 0;
4949  }
4950 
4951  if (ast_strlen_zero(textmsg)) {
4952  astman_send_error(s, m, "No Message specified");
4953  return 0;
4954  }
4955 
4957  if (!c) {
4958  astman_send_error(s, m, "No such channel");
4959  return 0;
4960  }
4961 
4962  /*
4963  * If the "extra" data is not available, then send using "string" only.
4964  * Doing such maintains backward compatibilities.
4965  */
4966  res = ast_strlen_zero(content_type) ? queue_sendtext(c, textmsg) :
4967  queue_sendtext_data(c, textmsg, content_type);
4968 
4970 
4971  if (res >= 0) {
4972  astman_send_ack(s, m, "Success");
4973  } else {
4974  astman_send_error(s, m, "Failure");
4975  }
4976 
4977  return 0;
4978 }
static int queue_sendtext_data(struct ast_channel *chan, const char *body, const char *content_type)
Queue a read action to send a text data message.
Definition: manager.c:4919
static int queue_sendtext(struct ast_channel *chan, const char *body)
Queue a read action to send a text message.
Definition: manager.c:4903

References ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), c, name, queue_sendtext(), and queue_sendtext_data().

Referenced by __init_manager().

◆ action_setvar()

static int action_setvar ( struct mansession s,
const struct message m 
)
static

Definition at line 4582 of file manager.c.

4583 {
4584  struct ast_channel *c = NULL;
4585  const char *name = astman_get_header(m, "Channel");
4586  const char *varname = astman_get_header(m, "Variable");
4587  const char *varval = astman_get_header(m, "Value");
4588  int res = 0;
4589 
4590  if (ast_strlen_zero(varname)) {
4591  astman_send_error(s, m, "No variable specified");
4592  return 0;
4593  }
4594 
4595  if (!ast_strlen_zero(name)) {
4596  if (!(c = ast_channel_get_by_name(name))) {
4597  astman_send_error(s, m, "No such channel");
4598  return 0;
4599  }
4600  }
4601 
4602  res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
4603 
4604  if (c) {
4605  c = ast_channel_unref(c);
4606  }
4607  if (res == 0) {
4608  astman_send_ack(s, m, "Variable Set");
4609  } else {
4610  astman_send_error(s, m, "Variable not set");
4611  }
4612  return 0;
4613 }

References ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), c, name, NULL, pbx_builtin_setvar_helper(), and S_OR.

Referenced by __init_manager().

◆ action_status()

static int action_status ( struct mansession s,
const struct message m 
)
static

Manager "status" command to show channels.

Definition at line 4782 of file manager.c.

4783 {
4784  const char *name = astman_get_header(m, "Channel");
4785  const char *chan_variables = astman_get_header(m, "Variables");
4786  const char *all_chan_variables = astman_get_header(m, "AllVariables");
4787  int all_variables = 0;
4788  const char *id = astman_get_header(m, "ActionID");
4789  char *variables = ast_strdupa(S_OR(chan_variables, ""));
4790  struct ast_channel *chan;
4791  int channels = 0;
4792  int all = ast_strlen_zero(name); /* set if we want all channels */
4793  char id_text[256];
4794  struct ast_channel_iterator *it_chans = NULL;
4795  AST_DECLARE_APP_ARGS(vars,
4796  AST_APP_ARG(name)[100];
4797  );
4798 
4799  if (!ast_strlen_zero(all_chan_variables)) {
4800  all_variables = ast_true(all_chan_variables);
4801  }
4802 
4804  astman_send_error(s, m, "Status Access Forbidden: Variables");
4805  return 0;
4806  }
4807 
4808  if (all) {
4809  if (!(it_chans = ast_channel_iterator_all_new())) {
4810  astman_send_error(s, m, "Memory Allocation Failure");
4811  return 1;
4812  }
4813  chan = ast_channel_iterator_next(it_chans);
4814  } else {
4815  chan = ast_channel_get_by_name(name);
4816  if (!chan) {
4817  astman_send_error(s, m, "No such channel");
4818  return 0;
4819  }
4820  }
4821 
4822  astman_send_listack(s, m, "Channel status will follow", "start");
4823 
4824  if (!ast_strlen_zero(id)) {
4825  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
4826  } else {
4827  id_text[0] = '\0';
4828  }
4829 
4830  if (!ast_strlen_zero(chan_variables)) {
4831  AST_STANDARD_APP_ARGS(vars, variables);
4832  }
4833 
4834  /* if we look by name, we break after the first iteration */
4835  for (; chan; all ? chan = ast_channel_iterator_next(it_chans) : 0) {
4836  ast_channel_lock(chan);
4837 
4838  generate_status(s, chan, vars.name, vars.argc, all_variables, id_text, &channels);
4839 
4840  ast_channel_unlock(chan);
4841  chan = ast_channel_unref(chan);
4842  }
4843 
4844  if (it_chans) {
4845  ast_channel_iterator_destroy(it_chans);
4846  }
4847 
4848  astman_send_list_complete_start(s, m, "StatusComplete", channels);
4849  astman_append(s, "Items: %d\r\n", channels);
4851 
4852  return 0;
4853 }
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static void generate_status(struct mansession *s, struct ast_channel *chan, char **vars, int varc, int all_variables, char *id_text, int *count)
Definition: manager.c:4667
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3244
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3252
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.

References AST_APP_ARG, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_true(), astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), channels, function_capable_string_allowed_with_auths(), generate_status(), name, ast_channel::name, NULL, S_OR, mansession::session, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_timeout()

static int action_timeout ( struct mansession s,
const struct message m 
)
static

Definition at line 6050 of file manager.c.

6051 {
6052  struct ast_channel *c;
6053  const char *name = astman_get_header(m, "Channel");
6054  double timeout = atof(astman_get_header(m, "Timeout"));
6055  struct timeval when = { timeout, 0 };
6056 
6057  if (ast_strlen_zero(name)) {
6058  astman_send_error(s, m, "No channel specified");
6059  return 0;
6060  }
6061 
6062  if (!timeout || timeout < 0) {
6063  astman_send_error(s, m, "No timeout specified");
6064  return 0;
6065  }
6066 
6067  if (!(c = ast_channel_get_by_name(name))) {
6068  astman_send_error(s, m, "No such channel");
6069  return 0;
6070  }
6071 
6072  when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
6073 
6077  c = ast_channel_unref(c);
6078 
6079  astman_send_ack(s, m, "Timeout Set");
6080 
6081  return 0;
6082 }
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
Definition: channel.c:510

References ast_channel_get_by_name(), ast_channel_lock, ast_channel_setwhentohangup_tv(), ast_channel_unlock, ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), c, and name.

Referenced by __init_manager().

◆ action_updateconfig()

static int action_updateconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 4107 of file manager.c.

4108 {
4109  struct ast_config *cfg;
4110  const char *sfn = astman_get_header(m, "SrcFilename");
4111  const char *dfn = astman_get_header(m, "DstFilename");
4112  int res;
4113  const char *rld = astman_get_header(m, "Reload");
4114  int preserve_effective_context = CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT;
4115  const char *preserve_effective_context_string = astman_get_header(m, "PreserveEffectiveContext");
4116  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
4117  enum error_type result;
4118 
4119  if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
4120  astman_send_error(s, m, "Filename not specified");
4121  return 0;
4122  }
4123  if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
4124  astman_send_error(s, m, "Config file not found");
4125  return 0;
4126  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
4127  astman_send_error(s, m, "Config file has invalid format");
4128  return 0;
4129  }
4130  result = handle_updates(s, m, cfg, dfn);
4131  if (!result) {
4132  ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
4133  if (!ast_strlen_zero(preserve_effective_context_string) && !ast_true(preserve_effective_context_string)) {
4134  preserve_effective_context = CONFIG_SAVE_FLAG_NONE;
4135  }
4136  res = ast_config_text_file_save2(dfn, cfg, "Manager", preserve_effective_context);
4137  ast_config_destroy(cfg);
4138  if (res) {
4139  astman_send_error(s, m, "Save of config failed");
4140  return 0;
4141  }
4142  astman_send_ack(s, m, NULL);
4143  if (!ast_strlen_zero(rld)) {
4144  if (ast_true(rld)) {
4145  rld = NULL;
4146  }
4147  ast_module_reload(rld);
4148  }
4149  } else {
4150  ast_config_destroy(cfg);
4151  switch(result) {
4152  case UNKNOWN_ACTION:
4153  astman_send_error(s, m, "Unknown action command");
4154  break;
4155  case UNKNOWN_CATEGORY:
4156  astman_send_error(s, m, "Given category does not exist");
4157  break;
4158  case UNSPECIFIED_CATEGORY:
4159  astman_send_error(s, m, "Category not specified");
4160  break;
4161  case UNSPECIFIED_ARGUMENT:
4162  astman_send_error(s, m, "Problem with category, value, or line (if required)");
4163  break;
4164  case FAILURE_ALLOCATION:
4165  astman_send_error(s, m, "Memory allocation failure, this should not happen");
4166  break;
4167  case FAILURE_NEWCAT:
4168  astman_send_error(s, m, "Create category did not complete successfully");
4169  break;
4170  case FAILURE_DELCAT:
4171  astman_send_error(s, m, "Delete category did not complete successfully");
4172  break;
4173  case FAILURE_EMPTYCAT:
4174  astman_send_error(s, m, "Empty category did not complete successfully");
4175  break;
4176  case FAILURE_UPDATE:
4177  astman_send_error(s, m, "Update did not complete successfully");
4178  break;
4179  case FAILURE_DELETE:
4180  astman_send_error(s, m, "Delete did not complete successfully");
4181  break;
4182  case FAILURE_APPEND:
4183  astman_send_error(s, m, "Append did not complete successfully");
4184  break;
4185  case FAILURE_TEMPLATE:
4186  astman_send_error(s, m, "Template category not found");
4187  break;
4188  }
4189  }
4190  return 0;
4191 }
static enum error_type handle_updates(struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
helper function for action_updateconfig
Definition: manager.c:3824
error_type
Definition: manager.c:1425
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
Definition: main/config.c:383
int ast_config_text_file_save2(const char *filename, const struct ast_config *cfg, const char *generator, uint32_t flags)
Save a config text file.
Definition: main/config.c:2621
@ CONFIG_SAVE_FLAG_NONE
@ CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT

References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save2(), ast_include_rename(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_SAVE_FLAG_NONE, CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_APPEND, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_TEMPLATE, FAILURE_UPDATE, handle_updates(), NULL, result, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.

Referenced by __init_manager().

◆ action_userevent()

static int action_userevent ( struct mansession s,
const struct message m 
)
static

Definition at line 6262 of file manager.c.

6263 {
6264  const char *event = astman_get_header(m, "UserEvent");
6265  struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
6266  int x;
6267 
6268  ast_str_reset(body);
6269 
6270  for (x = 0; x < m->hdrcount; x++) {
6271  if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:")) &&
6272  strncasecmp("Action:", m->headers[x], strlen("Action:"))) {
6273  ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
6274  }
6275  }
6276 
6277  astman_send_ack(s, m, "Event Sent");
6278  manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
6279  return 0;
6280 }
static struct ast_threadstorage userevent_buf
Definition: manager.c:3070
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
#define EVENT_FLAG_USER
Definition: manager.h:81
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:674

References ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), astman_send_ack(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, and userevent_buf.

Referenced by __init_manager().

◆ action_waitevent()

static int action_waitevent ( struct mansession s,
const struct message m 
)
static

Definition at line 4211 of file manager.c.

4212 {
4213  const char *timeouts = astman_get_header(m, "Timeout");
4214  int timeout = -1;
4215  int x;
4216  int needexit = 0;
4217  const char *id = astman_get_header(m, "ActionID");
4218  char idText[256];
4219 
4220  if (!ast_strlen_zero(id)) {
4221  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
4222  } else {
4223  idText[0] = '\0';
4224  }
4225 
4226  if (!ast_strlen_zero(timeouts)) {
4227  sscanf(timeouts, "%30i", &timeout);
4228  if (timeout < -1) {
4229  timeout = -1;
4230  }
4231  /* XXX maybe put an upper bound, or prevent the use of 0 ? */
4232  }
4233 
4236  pthread_kill(s->session->waiting_thread, SIGURG);
4237  }
4239 
4240  ao2_lock(s->session);
4241 
4242  if (s->session->managerid) { /* AMI-over-HTTP session */
4243  /*
4244  * Make sure the timeout is within the expire time of the session,
4245  * as the client will likely abort the request if it does not see
4246  * data coming after some amount of time.
4247  */
4248  time_t now = time(NULL);
4249  int max = s->session->sessiontimeout - now - 10;
4250 
4251  if (max < 0) { /* We are already late. Strange but possible. */
4252  max = 0;
4253  }
4254  if (timeout < 0 || timeout > max) {
4255  timeout = max;
4256  }
4257  if (!s->session->send_events) { /* make sure we record events */
4258  s->session->send_events = -1;
4259  }
4260  }
4261  ao2_unlock(s->session);
4262 
4264  s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
4266  ast_debug(1, "Starting waiting for an event!\n");
4267 
4268  for (x = 0; x < timeout || timeout < 0; x++) {
4269  ao2_lock(s->session);
4270  if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
4271  needexit = 1;
4272  }
4273  if (s->session->needdestroy) {
4274  needexit = 1;
4275  }
4276  ao2_unlock(s->session);
4277  /* We can have multiple HTTP session point to the same mansession entry.
4278  * The way we deal with it is not very nice: newcomers kick out the previous
4279  * HTTP session. XXX this needs to be improved.
4280  */
4282  if (s->session->waiting_thread != pthread_self()) {
4283  needexit = 1;
4284  }
4286  if (needexit) {
4287  break;
4288  }
4289  if (s->session->managerid == 0) { /* AMI session */
4291  break;
4292  }
4293  } else { /* HTTP session */
4294  sleep(1);
4295  }
4296  }
4297  ast_debug(1, "Finished waiting for an event!\n");
4298 
4300  if (s->session->waiting_thread == pthread_self()) {
4301  struct eventqent *eqe = s->session->last_ev;
4302 
4305 
4306  ao2_lock(s->session);
4307  astman_send_response(s, m, "Success", "Waiting for Event completed.");
4308  while ((eqe = advance_event(eqe))) {
4309  if (((s->session->readperm & eqe->category) == eqe->category)
4310  && ((s->session->send_events & eqe->category) == eqe->category)
4311  && match_filter(s, eqe->eventdata)) {
4312  astman_append(s, "%s", eqe->eventdata);
4313  }
4314  s->session->last_ev = eqe;
4315  }
4316  astman_append(s,
4317  "Event: WaitEventComplete\r\n"
4318  "%s"
4319  "\r\n", idText);
4320  ao2_unlock(s->session);
4321  } else {
4323  ast_debug(1, "Abandoning event request!\n");
4324  }
4325 
4326  return 0;
4327 }
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define max(a, b)
Definition: f2c.h:198
static struct eventqent * advance_event(struct eventqent *e)
Definition: manager.c:2760
static int match_filter(struct mansession *s, char *eventdata)
Definition: manager.c:6200
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition: iostream.c:84
#define AST_RWLIST_NEXT
Definition: linkedlists.h:441
int category
Definition: manager.c:1467
ast_mutex_t notify_lock
Definition: manager.c:1617
pthread_t waiting_thread
Definition: manager.c:1594
struct ast_iostream * stream
Definition: manager.c:1591
struct eventqent * last_ev
Definition: manager.c:1610
time_t sessiontimeout
Definition: manager.c:1598
int ast_wait_for_input(int fd, int ms)
Definition: main/utils.c:1665

References advance_event(), ao2_lock, ao2_unlock, ast_debug, ast_iostream_get_fd(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_RWLIST_NEXT, ast_strlen_zero(), ast_wait_for_input(), astman_append(), astman_get_header(), astman_send_response(), eventqent::category, mansession_session::last_ev, mansession_session::managerid, match_filter(), max, mansession_session::needdestroy, mansession_session::notify_lock, NULL, mansession_session::readperm, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, mansession_session::stream, and mansession_session::waiting_thread.

Referenced by __init_manager().

◆ advance_event()

static struct eventqent* advance_event ( struct eventqent e)
static

Definition at line 2760 of file manager.c.

2761 {
2762  struct eventqent *next;
2763 
2765  if ((next = AST_RWLIST_NEXT(e, eq_next))) {
2766  ast_atomic_fetchadd_int(&next->usecount, 1);
2768  }
2770  return next;
2771 }
int usecount
Definition: manager.c:1466

References ast_atomic_fetchadd_int(), AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and eventqent::usecount.

Referenced by action_waitevent(), and process_events().

◆ AO2_GLOBAL_OBJ_STATIC() [1/2]

static AO2_GLOBAL_OBJ_STATIC ( event_docs  )
static

A container of event documentation nodes.

◆ AO2_GLOBAL_OBJ_STATIC() [2/2]

static AO2_GLOBAL_OBJ_STATIC ( mgr_sessions  )
static

Active manager connection sessions container.

◆ aocmessage_get_unit_entry()

static int aocmessage_get_unit_entry ( const struct message m,
struct ast_aoc_unit_entry entry,
unsigned int  entry_num 
)
static

Definition at line 5499 of file manager.c.

5500 {
5501  const char *unitamount;
5502  const char *unittype;
5503  struct ast_str *str = ast_str_alloca(32);
5504 
5505  memset(entry, 0, sizeof(*entry));
5506 
5507  ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
5508  unitamount = astman_get_header(m, ast_str_buffer(str));
5509 
5510  ast_str_set(&str, 0, "UnitType(%u)", entry_num);
5511  unittype = astman_get_header(m, ast_str_buffer(str));
5512 
5513  if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
5514  entry->valid_amount = 1;
5515  }
5516 
5517  if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
5518  entry->valid_type = 1;
5519  }
5520 
5521  return 0;
5522 }
const char * str
Definition: app_jack.c:147

References ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), astman_get_header(), and str.

Referenced by action_aocmessage().

◆ append_channel_vars()

static void append_channel_vars ( struct ast_str **  pbuf,
struct ast_channel chan 
)
static

Definition at line 7093 of file manager.c.

7094 {
7095  struct varshead *vars;
7096  struct ast_var_t *var;
7097 
7098  vars = ast_channel_get_manager_vars(chan);
7099  if (!vars) {
7100  return;
7101  }
7102 
7103  AST_LIST_TRAVERSE(vars, var, entries) {
7104  ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, var->value);
7105  }
7106  ao2_ref(vars, -1);
7107 }
struct varshead * ast_channel_get_manager_vars(struct ast_channel *chan)
Gets the variables for a given channel, as specified by ast_channel_set_manager_vars().
Definition: channel.c:8066
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
struct ast_var_t::@239 entries

References ao2_ref, ast_channel_get_manager_vars(), ast_channel_name(), AST_LIST_TRAVERSE, ast_str_append(), and var.

Referenced by __manager_event_sessions_va().

◆ append_event()

static int append_event ( const char *  str,
int  category 
)
static

events are appended to a queue from where they can be dispatched to clients.

Definition at line 7069 of file manager.c.

7070 {
7071  struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
7072  static int seq; /* sequence number */
7073 
7074  if (!tmp) {
7075  return -1;
7076  }
7077 
7078  /* need to init all fields, because ast_malloc() does not */
7079  tmp->usecount = 0;
7080  tmp->category = category;
7081  tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
7082  tmp->tv = ast_tvnow();
7083  AST_RWLIST_NEXT(tmp, eq_next) = NULL;
7084  strcpy(tmp->eventdata, str);
7085 
7089 
7090  return 0;
7091 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741

References ast_atomic_fetchadd_int(), ast_malloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_NEXT, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvnow(), NULL, seq, str, and tmp().

Referenced by __init_manager(), and __manager_event_sessions_va().

◆ ast_hook_send_action()

int ast_hook_send_action ( struct manager_custom_hook hook,
const char *  msg 
)

access for hooks to send action messages to ami

Registered hooks can call this function to invoke actions and they will receive responses through registered callback.

Definition at line 2944 of file manager.c.

2945 {
2946  const char *action;
2947  int ret = 0;
2948  struct manager_action *act_found;
2949  struct mansession s = {.session = NULL, };
2950  struct message m = { 0 };
2951  char *dup_str;
2952  char *src;
2953  int x = 0;
2954  int curlen;
2955 
2956  if (hook == NULL) {
2957  return -1;
2958  }
2959 
2960  /* Create our own copy of the AMI action msg string. */
2961  src = dup_str = ast_strdup(msg);
2962  if (!dup_str) {
2963  return -1;
2964  }
2965 
2966  /* convert msg string to message struct */
2967  curlen = strlen(src);
2968  for (x = 0; x < curlen; x++) {
2969  int cr; /* set if we have \r */
2970  if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
2971  cr = 2; /* Found. Update length to include \r\n */
2972  else if (src[x] == '\n')
2973  cr = 1; /* also accept \n only */
2974  else
2975  continue;
2976  /* don't keep empty lines */
2977  if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
2978  /* ... but trim \r\n and terminate the header string */
2979  src[x] = '\0';
2980  m.headers[m.hdrcount++] = src;
2981  }
2982  x += cr;
2983  curlen -= x; /* remaining size */
2984  src += x; /* update pointer */
2985  x = -1; /* reset loop */
2986  }
2987 
2988  action = astman_get_header(&m, "Action");
2989 
2990  do {
2991  if (!strcasecmp(action, "login")) {
2992  break;
2993  }
2994 
2995  act_found = action_find(action);
2996  if (!act_found) {
2997  break;
2998  }
2999 
3000  /*
3001  * we have to simulate a session for this action request
3002  * to be able to pass it down for processing
3003  * This is necessary to meet the previous design of manager.c
3004  */
3005  s.hook = hook;
3006 
3007  ret = -1;
3008  ao2_lock(act_found);
3009  if (act_found->registered && act_found->func) {
3010  struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
3011 
3012  ao2_unlock(act_found);
3013  /* If the action is in a module it must be running. */
3014  if (!act_found->module || mod_ref) {
3015  ret = act_found->func(&s, &m);
3016  ast_module_unref(mod_ref);
3017  }
3018  } else {
3019  ao2_unlock(act_found);
3020  }
3021  ao2_t_ref(act_found, -1, "done with found action object");
3022  } while (0);
3023 
3024  ast_free(dup_str);
3025  return ret;
3026 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
static struct manager_action * action_find(const char *name)
Definition: manager.c:1711
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
struct ast_module * module
Definition: manager.h:172
int(* func)(struct mansession *s, const struct message *m)
Definition: manager.h:171
unsigned int registered
TRUE if the AMI action is registered and the callback can be called.
Definition: manager.h:183
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:1632
struct manager_custom_hook * hook
Definition: manager.c:1638

References action_find(), ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_free, ast_module_running_ref, ast_module_unref, ast_strdup, astman_get_header(), manager_action::func, message::hdrcount, message::headers, mansession::hook, manager_action::module, NULL, manager_action::registered, and mansession::session.

Referenced by hook_send().

◆ ast_instring()

static int ast_instring ( const char *  bigstr,
const char *  smallstr,
const char  delim 
)
static

Tells you if smallstr exists inside bigstr which is delim by delim and uses no buf or stringsep ast_instring("this|that|more","this",'|') == 1;

feel free to move this to app.c -anthm

Definition at line 2119 of file manager.c.

2120 {
2121  const char *val = bigstr, *next;
2122 
2123  do {
2124  if ((next = strchr(val, delim))) {
2125  if (!strncmp(val, smallstr, (next - val))) {
2126  return 1;
2127  } else {
2128  continue;
2129  }
2130  } else {
2131  return !strcmp(smallstr, val);
2132  }
2133  } while (*(val = (next + 1)));
2134 
2135  return 0;
2136 }
Definition: ast_expr2.c:325

Referenced by get_perm().

◆ ast_manager_check_enabled()

int ast_manager_check_enabled ( void  )

Check if AMI is enabled.

Definition at line 1956 of file manager.c.

1957 {
1958  return manager_enabled;
1959 }
static int manager_enabled
Definition: manager.c:1481

References manager_enabled.

Referenced by handle_show_settings().

◆ ast_manager_get_message_router()

struct stasis_message_router* ast_manager_get_message_router ( void  )

Get the stasis_message_router for AMI.

Since
12
Returns
The stasis_message_router for AMI
Return values
NULLon error

Definition at line 1732 of file manager.c.

1733 {
1734  return stasis_router;
1735 }
static struct stasis_message_router * stasis_router
The stasis_message_router for all Stasis Message Bus API messages.
Definition: manager.c:1500

References stasis_router.

Referenced by manager_bridging_init(), manager_channels_init(), manager_mwi_init(), and manager_system_init().

◆ ast_manager_get_topic()

struct stasis_topic* ast_manager_get_topic ( void  )

Get the Stasis Message Bus API topic for AMI.

Since
12
Returns
The Stasis Message Bus API topic for AMI
Return values
NULLon error

Definition at line 1727 of file manager.c.

1728 {
1729  return manager_topic;
1730 }
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1497

References manager_topic.

Referenced by aoc_publish_blob(), ast_manager_publish_event(), endpoint_state_cb(), load_module(), manager_bridging_init(), manager_channels_init(), manager_mwi_init(), manager_system_init(), publish_load_message_type(), and queue_publish_member_blob().

◆ ast_manager_publish_event()

void ast_manager_publish_event ( const char *  type,
int  class_type,
struct ast_json obj 
)

Publish an event to AMI.

Since
12
Parameters
typeThe type of AMI event to publish
class_typeThe class on which to publish the event
objThe event data to be published.

Publishes a message to the Stasis Message Bus API message bus solely for the consumption of AMI. The message will be of the type provided by ast_manager_get_generic_type, and will be published to the topic provided by ast_manager_get_topic. As such, the JSON must be constructed as defined by the ast_manager_get_generic_type message.

Definition at line 1910 of file manager.c.

1911 {
1912  RAII_VAR(struct ast_json *, event_info, NULL, ast_json_unref);
1913  RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
1915 
1916  if (!obj || !ast_manager_get_generic_type()) {
1917  return;
1918  }
1919 
1920  ast_json_ref(obj);
1921  event_info = ast_json_pack("{s: s, s: i, s: o}",
1922  "type", type,
1923  "class_type", class_type,
1924  "event", obj);
1925  if (!event_info) {
1926  return;
1927  }
1928 
1929  payload = ast_json_payload_create(event_info);
1930  if (!payload) {
1931  return;
1932  }
1934  if (!message) {
1935  return;
1936  }
1938 }
static const char type[]
Definition: chan_ooh323.c:109
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:1727
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json_payload * ast_json_payload_create(struct ast_json *json)
Create an ao2 object to pass json blobs as data payloads for stasis.
Definition: json.c:735
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1513
Abstract JSON element (object, array, string, int, ...).
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:936

References ao2_cleanup, ast_json_pack(), ast_json_payload_create(), ast_json_ref(), ast_json_unref(), ast_manager_get_generic_type(), ast_manager_get_topic(), NULL, RAII_VAR, stasis_message_create(), stasis_publish(), and type.

Referenced by analog_publish_channel_alarm_clear(), analog_publish_dnd_state(), publish_channel_alarm(), publish_channel_alarm_clear(), publish_dnd_state(), publish_fully_booted(), publish_qualify_peer_done(), publish_span_alarm(), publish_span_alarm_clear(), and really_quit().

◆ ast_manager_register2()

int ast_manager_register2 ( const char *  action,
int  auth,
int(*)(struct mansession *s, const struct message *m)  func,
struct ast_module module,
const char *  synopsis,
const char *  description 
)

register a new command with manager, including online help. This is the preferred way to register a manager command

Register a manager command with the manager interface.

Definition at line 7394 of file manager.c.

7395 {
7396  struct manager_action *cur;
7397 
7398  cur = ao2_t_alloc(sizeof(*cur), action_destroy, action);
7399  if (!cur) {
7400  return -1;
7401  }
7402  if (ast_string_field_init(cur, 128)) {
7403  ao2_t_ref(cur, -1, "action object creation failed");
7404  return -1;
7405  }
7406 
7407  cur->action = action;
7408  cur->authority = auth;
7409  cur->func = func;
7410  cur->module = module;
7411 #ifdef AST_XML_DOCS
7413  char *tmpxml;
7414 
7415  tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
7416  ast_string_field_set(cur, synopsis, tmpxml);
7417  ast_free(tmpxml);
7418 
7419  tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
7420  ast_string_field_set(cur, syntax, tmpxml);
7421  ast_free(tmpxml);
7422 
7423  tmpxml = ast_xmldoc_build_description("manager", action, NULL);
7424  ast_string_field_set(cur, description, tmpxml);
7425  ast_free(tmpxml);
7426 
7427  tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
7428  ast_string_field_set(cur, seealso, tmpxml);
7429  ast_free(tmpxml);
7430 
7431  tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
7432  ast_string_field_set(cur, arguments, tmpxml);
7433  ast_free(tmpxml);
7434 
7437 
7438  cur->docsrc = AST_XML_DOC;
7439  } else
7440 #endif
7441  {
7444 #ifdef AST_XML_DOCS
7445  cur->docsrc = AST_STATIC_DOC;
7446 #endif
7447  }
7448  if (ast_manager_register_struct(cur)) {
7449  ao2_t_ref(cur, -1, "action object registration failed");
7450  return -1;
7451  }
7452 
7453  ao2_t_ref(cur, -1, "action object registration successful");
7454  return 0;
7455 }
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:407
static char * synopsis
Definition: func_enum.c:154
static int ast_manager_register_struct(struct manager_action *act)
Definition: manager.c:7339
static void action_destroy(void *obj)
Definition: manager.c:7380
const ast_string_field description
Definition: manager.h:163
enum ast_doc_src docsrc
Definition: manager.h:174
const ast_string_field seealso
Definition: manager.h:163
const ast_string_field syntax
Definition: manager.h:163
const ast_string_field arguments
Definition: manager.h:163
char * ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
Generate the [arguments] tag based on type of node ('application', 'function' or 'agi') and name.
Definition: xmldoc.c:2077
char * ast_xmldoc_build_seealso(const char *type, const char *name, const char *module)
Parse the <see-also> node content.
Definition: xmldoc.c:1698
char * ast_xmldoc_build_syntax(const char *type, const char *name, const char *module)
Get the syntax for a specified application or function.
Definition: xmldoc.c:1253
struct ast_xml_doc_item * ast_xmldoc_build_final_response(const char *type, const char *name, const char *module)
Generate the [final response] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2530
struct ast_xml_doc_item * ast_xmldoc_build_list_responses(const char *type, const char *name, const char *module)
Generate the [list responses] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2465
@ AST_XML_DOC
Definition: xmldoc.h:31
@ AST_STATIC_DOC
Definition: xmldoc.h:32
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:2252
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:2229

References manager_action::action, action_destroy(), ao2_t_alloc, ao2_t_ref, ast_free, ast_manager_register_struct(), AST_STATIC_DOC, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_final_response(), ast_xmldoc_build_list_responses(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), manager_action::authority, manager_action::docsrc, manager_action::final_response, manager_action::func, manager_action::list_responses, manager_action::module, NULL</