Asterisk - The Open Source Telephony Project GIT-master-3dae2cf
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  event_filter_entry
 
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  originate_permissions_entry
 
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 = 0 , FILTER_ALLOC_FAILED , FILTER_COMPILE_FAIL , FILTER_FORMAT_ERROR }
 
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  event_filter_match_type {
  FILTER_MATCH_REGEX = 0 , FILTER_MATCH_EXACT , FILTER_MATCH_STARTS_WITH , FILTER_MATCH_ENDS_WITH ,
  FILTER_MATCH_CONTAINS , FILTER_MATCH_NONE
}
 
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 struct ast_aoc_decodedaction_aoc_de_message (struct mansession *s, const struct message *m)
 
static struct ast_aoc_decodedaction_aoc_s_message (struct mansession *s, const struct message *m)
 
static int action_aoc_s_submessage (struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
 
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_coreshowchannelmap (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannelMap" - Lists all channels connected to the specified channel. 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 int app_match (const char *app, const char *data, const char *search)
 
static int appdata_match (const char *app, const char *data, const char *search)
 
static void append_channel_vars (struct ast_str **pbuf, struct ast_channel *chan)
 
static int append_event (const char *str, int event_name_hash, 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...
 
int ast_manager_hangup_helper (struct mansession *s, const struct message *m, manager_hangup_handler_t hangup_handler, manager_hangup_cause_validator_t cause_validator)
 A manager helper function that hangs up a channel using a supplied channel type specific hangup function and cause code validator. 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_live_dangerously (int new_live_dangerously)
 Enable/disable the inclusion of 'dangerous' configurations outside of the ast_config_AST_CONFIG_DIR. 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 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 int coreshowchannelmap_add_connected_channels (struct ao2_container *channel_map, struct ast_channel_snapshot *channel_snapshot, struct ast_bridge_snapshot *bridge_snapshot)
 Recursive function to get all channels in a bridge. Follow local channels as well. More...
 
static int coreshowchannelmap_add_to_map (struct ao2_container *c, const char *s)
 Helper function to add a channel name to the vector. More...
 
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 file_in_modules_dir (const char *filename)
 Check if the given file path is in the modules dir or not. More...
 
static int filter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
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_kickmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager kick session. More...
 
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 int is_originate_app_permitted (const char *app, const char *data, int permission)
 
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 *criteria, const char *filter_pattern, struct ao2_container *includefilters, struct ao2_container *excludefilters)
 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_eventdata (struct event_filter_entry *entry, const char *eventdata)
 Test eventdata against a filter entry. More...
 
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 int purge_sessions (int n_max)
 remove at most n_max stale session from the list. More...
 
static int queue_match (const char *app, const char *data, const char *search)
 
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 restrictedFile (const char *filename)
 Check if a file is restricted or not. More...
 
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 should_send_event (struct ao2_container *includefilters, struct ao2_container *excludefilters, struct eventqent *eqe)
 
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...
 

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 int live_dangerously
 Set to true (non-zero) to globally allow all dangerous AMI actions to run. More...
 
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 char * match_type_names []
 
static struct originate_permissions_entry originate_app_permissions []
 
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 568 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 1876 of file manager.c.

◆ DEFAULT_REALM

#define DEFAULT_REALM   "asterisk"

Definition at line 178 of file manager.c.

◆ EVENT_FLAG_SHUTDOWN

#define EVENT_FLAG_SHUTDOWN   -1

Fake event class used to end sessions at shutdown.

Definition at line 211 of file manager.c.

◆ GET_HEADER_FIRST_MATCH

#define GET_HEADER_FIRST_MATCH   0

Definition at line 1576 of file manager.c.

◆ GET_HEADER_LAST_MATCH

#define GET_HEADER_LAST_MATCH   1

Definition at line 1577 of file manager.c.

◆ GET_HEADER_SKIP_EMPTY

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 1578 of file manager.c.

◆ MANAGER_EVENT_BUF_INITSIZE

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 7447 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 565 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 777 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 223 of file manager.c.

◆ MAX_VARS

#define MAX_VARS   128

Definition at line 208 of file manager.c.

◆ MGR_SHOW_TERMINAL_WIDTH

#define MGR_SHOW_TERMINAL_WIDTH   80

Definition at line 206 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 1924 of file manager.c.

Enumeration Type Documentation

◆ add_filter_result

Enumerator
FILTER_SUCCESS 
FILTER_ALLOC_FAILED 
FILTER_COMPILE_FAIL 
FILTER_FORMAT_ERROR 

Definition at line 126 of file manager.c.

126 {
127 FILTER_SUCCESS = 0,
131};
@ FILTER_SUCCESS
Definition: manager.c:127
@ FILTER_FORMAT_ERROR
Definition: manager.c:130
@ FILTER_COMPILE_FAIL
Definition: manager.c:129
@ FILTER_ALLOC_FAILED
Definition: manager.c:128

◆ 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 111 of file manager.c.

111 {
112 UNKNOWN_ACTION = 1,
124};
@ FAILURE_EMPTYCAT
Definition: manager.c:119
@ FAILURE_UPDATE
Definition: manager.c:120
@ FAILURE_NEWCAT
Definition: manager.c:117
@ FAILURE_DELETE
Definition: manager.c:121
@ FAILURE_APPEND
Definition: manager.c:122
@ UNKNOWN_CATEGORY
Definition: manager.c:113
@ FAILURE_DELCAT
Definition: manager.c:118
@ FAILURE_ALLOCATION
Definition: manager.c:116
@ FAILURE_TEMPLATE
Definition: manager.c:123
@ UNSPECIFIED_CATEGORY
Definition: manager.c:114
@ UNSPECIFIED_ARGUMENT
Definition: manager.c:115
@ UNKNOWN_ACTION
Definition: manager.c:112

◆ event_filter_match_type

Enumerator
FILTER_MATCH_REGEX 
FILTER_MATCH_EXACT 
FILTER_MATCH_STARTS_WITH 
FILTER_MATCH_ENDS_WITH 
FILTER_MATCH_CONTAINS 
FILTER_MATCH_NONE 

Definition at line 388 of file manager.c.

388 {
395};
@ FILTER_MATCH_ENDS_WITH
Definition: manager.c:392
@ FILTER_MATCH_CONTAINS
Definition: manager.c:393
@ FILTER_MATCH_STARTS_WITH
Definition: manager.c:391
@ FILTER_MATCH_REGEX
Definition: manager.c:389
@ FILTER_MATCH_NONE
Definition: manager.c:394
@ FILTER_MATCH_EXACT
Definition: manager.c:390

◆ mansession_message_parsing

Enumerator
MESSAGE_OKAY 
MESSAGE_LINE_TOO_LONG 

Definition at line 316 of file manager.c.

316 {
319};
@ MESSAGE_OKAY
Definition: manager.c:317
@ MESSAGE_LINE_TOO_LONG
Definition: manager.c:318

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 7581 of file manager.c.

7584{
7585 struct ao2_container *sessions = ao2_global_obj_ref(mgr_sessions);
7586 va_list ap;
7587 int res;
7588
7590 /* Nobody is listening */
7592 return 0;
7593 }
7594
7595 va_start(ap, fmt);
7597 file, line, func, fmt, ap);
7598 va_end(ap);
7600 return res;
7601}
#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 struct unistimsession * sessions
static int chancount
Definition: channel.c:93
#define any_manager_listeners(sessions)
Definition: manager.c:568
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:7449
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, chancount, make_ari_stubs::file, and sessions.

◆ __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 1593 of file manager.c.

1594{
1595 int x, l = strlen(var);
1596 const char *result = "";
1597
1598 if (!m) {
1599 return result;
1600 }
1601
1602 for (x = 0; x < m->hdrcount; x++) {
1603 const char *h = m->headers[x];
1604 if (!strncasecmp(var, h, l) && h[l] == ':') {
1605 const char *value = h + l + 1;
1606 value = ast_skip_blanks(value); /* ignore leading spaces in the value */
1607 /* found a potential candidate */
1608 if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
1609 continue; /* not interesting */
1610 }
1611 if (mode & GET_HEADER_LAST_MATCH) {
1612 result = value; /* record the last match so far */
1613 } else {
1614 return value;
1615 }
1616 }
1617 }
1618
1619 return result;
1620}
#define var
Definition: ast_expr2f.c:605
static PGresult * result
Definition: cel_pgsql.c:84
#define GET_HEADER_LAST_MATCH
Definition: manager.c:1577
#define GET_HEADER_SKIP_EMPTY
Definition: manager.c:1578
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
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 action_aoc_s_submessage(), 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 1871 of file manager.c.

1879{

◆ __init_manager_event_buf()

static void __init_manager_event_buf ( void  )
static

Definition at line 7446 of file manager.c.

7460{

◆ __init_userevent_buf()

static void __init_userevent_buf ( void  )
static

Definition at line 1873 of file manager.c.

1879{

◆ __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 7559 of file manager.c.

7570{
7571 va_list ap;
7572 int res;
7573
7574 va_start(ap, fmt);
7576 chancount, chans, file, line, func, fmt, ap);
7577 va_end(ap);
7578 return res;
7579}

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

◆ __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 7449 of file manager.c.

7460{
7462 const char *cat_str;
7463 struct timeval now;
7464 struct ast_str *buf;
7465 int i;
7466 int event_name_hash;
7467
7470 ast_debug(3, "AMI Event '%s' is globally disabled, skipping\n", event);
7471 /* Event is globally disabled */
7472 return -1;
7473 }
7474 }
7475
7477 if (!buf) {
7478 return -1;
7479 }
7480
7481 cat_str = authority_to_str(category, &auth);
7482 ast_str_set(&buf, 0,
7483 "Event: %s\r\n"
7484 "Privilege: %s\r\n",
7485 event, cat_str);
7486
7487 if (timestampevents) {
7488 now = ast_tvnow();
7489 ast_str_append(&buf, 0,
7490 "Timestamp: %ld.%06lu\r\n",
7491 (long)now.tv_sec, (unsigned long) now.tv_usec);
7492 }
7493 if (manager_debug) {
7494 static int seq;
7495
7496 ast_str_append(&buf, 0,
7497 "SequenceNumber: %d\r\n",
7499 ast_str_append(&buf, 0,
7500 "File: %s\r\n"
7501 "Line: %d\r\n"
7502 "Func: %s\r\n",
7503 file, line, func);
7504 }
7506 ast_str_append(&buf, 0,
7507 "SystemName: %s\r\n",
7509 }
7510
7511 ast_str_append_va(&buf, 0, fmt, ap);
7512 for (i = 0; i < chancount; i++) {
7514 }
7515
7516 ast_str_append(&buf, 0, "\r\n");
7517
7518 event_name_hash = ast_str_hash(event);
7519
7520 append_event(ast_str_buffer(buf), event_name_hash, category);
7521
7522 /* Wake up any sleeping sessions */
7523 if (sessions) {
7524 struct ao2_iterator iter;
7526
7527 iter = ao2_iterator_init(sessions, 0);
7528 while ((session = ao2_iterator_next(&iter))) {
7529 ast_mutex_lock(&session->notify_lock);
7530 if (session->waiting_thread != AST_PTHREADT_NULL) {
7531 pthread_kill(session->waiting_thread, SIGURG);
7532 } else {
7533 /* We have an event to process, but the mansession is
7534 * not waiting for it. We still need to indicate that there
7535 * is an event waiting so that get_input processes the pending
7536 * event instead of polling.
7537 */
7538 session->pending_event = 1;
7539 }
7540 ast_mutex_unlock(&session->notify_lock);
7542 }
7543 ao2_iterator_destroy(&iter);
7544 }
7545
7546 if (category != EVENT_FLAG_SHUTDOWN && !AST_RWLIST_EMPTY(&manager_hooks)) {
7547 struct manager_custom_hook *hook;
7548
7550 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
7551 hook->helper(category, event, ast_str_buffer(buf));
7552 }
7554 }
7555
7556 return 0;
7557}
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 int append_event(const char *str, int event_name_hash, int category)
events are appended to a queue from where they can be dispatched to clients.
Definition: manager.c:7404
static struct ast_threadstorage manager_event_buf
Definition: manager.c:7446
static int manager_debug
Definition: manager.c:172
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
Definition: manager.c:7429
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:917
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:818
#define MAX_AUTH_PERM_STRING
Definition: manager.c:777
static int timestampevents
Definition: manager.c:166
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:211
#define MANAGER_EVENT_BUF_INITSIZE
Definition: manager.c:7447
static char * manager_disabledevents
Definition: manager.c:176
#define ast_debug(level,...)
Log a DEBUG message.
#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:190
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:757
#define ast_mutex_lock(a)
Definition: lock.h:189
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:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259
#define ast_str_alloca(init_len)
Definition: strings.h:848
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:433
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
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:1048
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:909
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:623
manager_hook_t helper
Definition: manager.h:117
list of hooks registered
Definition: manager.c:369
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

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_debug, ast_in_delimited_string(), 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_hash(), 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_disabledevents, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, MAX_AUTH_PERM_STRING, seq, session, sessions, 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 10030 of file manager.c.

10032{
10034 return;
10035 }
10036
10037 /* For now, this is going to be performed simply and just execute a forced reload. */
10038 ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
10039 __init_manager(1, 1);
10040}
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:9533
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 234 of file manager.c.

235{
236 if (!acl_change_sub) {
241 }
242}
static struct stasis_subscription * acl_change_sub
Definition: manager.c:182
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:10030
#define NULL
Definition: resample.c:96
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
@ 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:1024
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:1078
#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 244 of file manager.c.

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

References acl_change_sub, and stasis_unsubscribe_and_join().

Referenced by __init_manager(), and manager_shutdown().

◆ action_aoc_de_message()

static struct ast_aoc_decoded * action_aoc_de_message ( struct mansession s,
const struct message m 
)
static

Definition at line 4411 of file manager.c.

4412{
4413 const char *msgtype = astman_get_header(m, "MsgType");
4414 const char *chargetype = astman_get_header(m, "ChargeType");
4415 const char *currencyname = astman_get_header(m, "CurrencyName");
4416 const char *currencyamount = astman_get_header(m, "CurrencyAmount");
4417 const char *mult = astman_get_header(m, "CurrencyMultiplier");
4418 const char *totaltype = astman_get_header(m, "TotalType");
4419 const char *aocbillingid = astman_get_header(m, "AOCBillingId");
4420 const char *association_id= astman_get_header(m, "ChargingAssociationId");
4421 const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
4422 const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
4423
4424 enum ast_aoc_type _msgtype;
4425 enum ast_aoc_charge_type _chargetype;
4427 enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
4428 enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
4429 unsigned int _currencyamount = 0;
4430 int _association_id = 0;
4431 unsigned int _association_plan = 0;
4432
4433 struct ast_aoc_decoded *decoded = NULL;
4434
4435 if (ast_strlen_zero(chargetype)) {
4436 astman_send_error(s, m, "ChargeType not specified");
4437 goto aocmessage_cleanup;
4438 }
4439
4440 _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
4441
4442 if (!strcasecmp(chargetype, "NA")) {
4443 _chargetype = AST_AOC_CHARGE_NA;
4444 } else if (!strcasecmp(chargetype, "Free")) {
4445 _chargetype = AST_AOC_CHARGE_FREE;
4446 } else if (!strcasecmp(chargetype, "Currency")) {
4447 _chargetype = AST_AOC_CHARGE_CURRENCY;
4448 } else if (!strcasecmp(chargetype, "Unit")) {
4449 _chargetype = AST_AOC_CHARGE_UNIT;
4450 } else {
4451 astman_send_error(s, m, "Invalid ChargeType");
4452 goto aocmessage_cleanup;
4453 }
4454
4455 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4456
4457 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
4458 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
4459 goto aocmessage_cleanup;
4460 }
4461
4462 if (ast_strlen_zero(mult)) {
4463 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
4464 goto aocmessage_cleanup;
4465 } else if (!strcasecmp(mult, "onethousandth")) {
4467 } else if (!strcasecmp(mult, "onehundredth")) {
4469 } else if (!strcasecmp(mult, "onetenth")) {
4470 _mult = AST_AOC_MULT_ONETENTH;
4471 } else if (!strcasecmp(mult, "one")) {
4472 _mult = AST_AOC_MULT_ONE;
4473 } else if (!strcasecmp(mult, "ten")) {
4474 _mult = AST_AOC_MULT_TEN;
4475 } else if (!strcasecmp(mult, "hundred")) {
4476 _mult = AST_AOC_MULT_HUNDRED;
4477 } else if (!strcasecmp(mult, "thousand")) {
4478 _mult = AST_AOC_MULT_THOUSAND;
4479 } else {
4480 astman_send_error(s, m, "Invalid ChargeMultiplier");
4481 goto aocmessage_cleanup;
4482 }
4483 }
4484
4485 /* create decoded object and start setting values */
4486 if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
4487 astman_send_error(s, m, "Message Creation Failed");
4488 goto aocmessage_cleanup;
4489 }
4490
4491 if (_msgtype == AST_AOC_D) {
4492 if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
4493 _totaltype = AST_AOC_SUBTOTAL;
4494 }
4495
4496 if (ast_strlen_zero(aocbillingid)) {
4497 /* ignore this is optional */
4498 } else if (!strcasecmp(aocbillingid, "Normal")) {
4499 _billingid = AST_AOC_BILLING_NORMAL;
4500 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4501 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4502 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4503 _billingid = AST_AOC_BILLING_CREDIT_CARD;
4504 } else {
4505 astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
4506 goto aocmessage_cleanup;
4507 }
4508 } else {
4509 if (ast_strlen_zero(aocbillingid)) {
4510 /* ignore this is optional */
4511 } else if (!strcasecmp(aocbillingid, "Normal")) {
4512 _billingid = AST_AOC_BILLING_NORMAL;
4513 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4514 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4515 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4516 _billingid = AST_AOC_BILLING_CREDIT_CARD;
4517 } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
4519 } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
4520 _billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
4521 } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
4523 } else if (!strcasecmp(aocbillingid, "CallDeflection")) {
4525 } else if (!strcasecmp(aocbillingid, "CallTransfer")) {
4526 _billingid = AST_AOC_BILLING_CALL_TRANSFER;
4527 } else {
4528 astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
4529 goto aocmessage_cleanup;
4530 }
4531
4532 if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
4533 astman_send_error(s, m, "Invalid ChargingAssociationId");
4534 goto aocmessage_cleanup;
4535 }
4536 if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
4537 astman_send_error(s, m, "Invalid ChargingAssociationPlan");
4538 goto aocmessage_cleanup;
4539 }
4540
4541 if (_association_id) {
4542 ast_aoc_set_association_id(decoded, _association_id);
4543 } else if (!ast_strlen_zero(association_num)) {
4544 ast_aoc_set_association_number(decoded, association_num, _association_plan);
4545 }
4546 }
4547
4548 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4549 ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
4550 } else if (_chargetype == AST_AOC_CHARGE_UNIT) {
4552 int i;
4553
4554 /* multiple unit entries are possible, lets get them all */
4555 for (i = 0; i < 32; i++) {
4556 if (aocmessage_get_unit_entry(m, &entry, i)) {
4557 break; /* that's the end then */
4558 }
4559
4560 ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
4561 }
4562
4563 /* at least one unit entry is required */
4564 if (!i) {
4565 astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
4566 goto aocmessage_cleanup;
4567 }
4568
4569 }
4570
4571 ast_aoc_set_billing_id(decoded, _billingid);
4572 ast_aoc_set_total_type(decoded, _totaltype);
4573
4574 return decoded;
4575
4576aocmessage_cleanup:
4577
4578 ast_aoc_destroy_decoded(decoded);
4579 return NULL;
4580}
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
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
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
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
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
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
ast_aoc_total_type
Definition: aoc.h:82
@ AST_AOC_TOTAL
Definition: aoc.h:83
@ AST_AOC_SUBTOTAL
Definition: aoc.h:84
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1969
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:1630
static int aocmessage_get_unit_entry(const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
Definition: manager.c:4386
Definition: aoc.h:178
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_E, 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_strlen_zero(), astman_get_header(), astman_send_error(), and NULL.

Referenced by action_aocmessage().

◆ action_aoc_s_message()

static struct ast_aoc_decoded * action_aoc_s_message ( struct mansession s,
const struct message m 
)
static

Definition at line 4806 of file manager.c.

4808{
4809 struct ast_aoc_decoded *decoded = NULL;
4810 int hdrlen;
4811 int x;
4812 static const char hdr[] = "ChargedItem:";
4813 struct message sm = { 0 };
4814 int rates = 0;
4815
4816 if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
4817 astman_send_error(s, m, "Message Creation Failed");
4818 goto aocmessage_cleanup;
4819 }
4820
4821 hdrlen = strlen(hdr);
4822 for (x = 0; x < m->hdrcount; x++) {
4823 if (strncasecmp(hdr, m->headers[x], hdrlen) == 0) {
4824 if (rates > ast_aoc_s_get_count(decoded)) {
4825 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
4826 goto aocmessage_cleanup;
4827 }
4828 }
4829 ++rates;
4830 }
4831
4832 sm.headers[sm.hdrcount] = m->headers[x];
4833 ++sm.hdrcount;
4834 }
4835 if (rates > ast_aoc_s_get_count(decoded)) {
4836 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
4837 goto aocmessage_cleanup;
4838 }
4839 }
4840
4841 return decoded;
4842
4843aocmessage_cleanup:
4844
4845 ast_aoc_destroy_decoded(decoded);
4846 return NULL;
4847}
@ AST_AOC_S
Definition: aoc.h:64
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
Definition: aoc.c:756
static int action_aoc_s_submessage(struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
Definition: manager.c:4582

References action_aoc_s_submessage(), ast_aoc_create(), ast_aoc_destroy_decoded(), AST_AOC_S, ast_aoc_s_get_count(), astman_send_error(), message::hdrcount, message::headers, and NULL.

Referenced by action_aocmessage().

◆ action_aoc_s_submessage()

static int action_aoc_s_submessage ( struct mansession s,
const struct message m,
struct ast_aoc_decoded decoded 
)
static

Definition at line 4582 of file manager.c.

4584{
4585 const char *chargeditem = __astman_get_header(m, "ChargedItem", GET_HEADER_LAST_MATCH);
4586 const char *ratetype = __astman_get_header(m, "RateType", GET_HEADER_LAST_MATCH);
4587 const char *currencyname = __astman_get_header(m, "CurrencyName", GET_HEADER_LAST_MATCH);
4588 const char *currencyamount = __astman_get_header(m, "CurrencyAmount", GET_HEADER_LAST_MATCH);
4589 const char *mult = __astman_get_header(m, "CurrencyMultiplier", GET_HEADER_LAST_MATCH);
4590 const char *time = __astman_get_header(m, "Time", GET_HEADER_LAST_MATCH);
4591 const char *timescale = __astman_get_header(m, "TimeScale", GET_HEADER_LAST_MATCH);
4592 const char *granularity = __astman_get_header(m, "Granularity", GET_HEADER_LAST_MATCH);
4593 const char *granularitytimescale = __astman_get_header(m, "GranularityTimeScale", GET_HEADER_LAST_MATCH);
4594 const char *chargingtype = __astman_get_header(m, "ChargingType", GET_HEADER_LAST_MATCH);
4595 const char *volumeunit = __astman_get_header(m, "VolumeUnit", GET_HEADER_LAST_MATCH);
4596 const char *code = __astman_get_header(m, "Code", GET_HEADER_LAST_MATCH);
4597
4598 enum ast_aoc_s_charged_item _chargeditem;
4599 enum ast_aoc_s_rate_type _ratetype;
4601 unsigned int _currencyamount = 0;
4602 unsigned int _code;
4603 unsigned int _time = 0;
4604 enum ast_aoc_time_scale _scale = 0;
4605 unsigned int _granularity = 0;
4606 enum ast_aoc_time_scale _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
4607 int _step = 0;
4608 enum ast_aoc_volume_unit _volumeunit = 0;
4609
4610 if (ast_strlen_zero(chargeditem)) {
4611 astman_send_error(s, m, "ChargedItem not specified");
4612 goto aocmessage_cleanup;
4613 }
4614
4615 if (ast_strlen_zero(ratetype)) {
4616 astman_send_error(s, m, "RateType not specified");
4617 goto aocmessage_cleanup;
4618 }
4619
4620 if (!strcasecmp(chargeditem, "NA")) {
4621 _chargeditem = AST_AOC_CHARGED_ITEM_NA;
4622 } else if (!strcasecmp(chargeditem, "SpecialArrangement")) {
4624 } else if (!strcasecmp(chargeditem, "BasicCommunication")) {
4626 } else if (!strcasecmp(chargeditem, "CallAttempt")) {
4627 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
4628 } else if (!strcasecmp(chargeditem, "CallSetup")) {
4629 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_SETUP;
4630 } else if (!strcasecmp(chargeditem, "UserUserInfo")) {
4632 } else if (!strcasecmp(chargeditem, "SupplementaryService")) {
4634 } else {
4635 astman_send_error(s, m, "Invalid ChargedItem");
4636 goto aocmessage_cleanup;
4637 }
4638
4639 if (!strcasecmp(ratetype, "NA")) {
4640 _ratetype = AST_AOC_RATE_TYPE_NA;
4641 } else if (!strcasecmp(ratetype, "Free")) {
4642 _ratetype = AST_AOC_RATE_TYPE_FREE;
4643 } else if (!strcasecmp(ratetype, "FreeFromBeginning")) {
4645 } else if (!strcasecmp(ratetype, "Duration")) {
4646 _ratetype = AST_AOC_RATE_TYPE_DURATION;
4647 } else if (!strcasecmp(ratetype, "Flat")) {
4648 _ratetype = AST_AOC_RATE_TYPE_FLAT;
4649 } else if (!strcasecmp(ratetype, "Volume")) {
4650 _ratetype = AST_AOC_RATE_TYPE_VOLUME;
4651 } else if (!strcasecmp(ratetype, "SpecialCode")) {
4653 } else {
4654 astman_send_error(s, m, "Invalid RateType");
4655 goto aocmessage_cleanup;
4656 }
4657
4658 if (_ratetype > AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
4659 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u",
4660 &_currencyamount) != 1)) {
4661 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when RateType is non-free");
4662 goto aocmessage_cleanup;
4663 }
4664
4665 if (ast_strlen_zero(mult)) {
4666 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
4667 goto aocmessage_cleanup;
4668 } else if (!strcasecmp(mult, "onethousandth")) {
4670 } else if (!strcasecmp(mult, "onehundredth")) {
4672 } else if (!strcasecmp(mult, "onetenth")) {
4673 _mult = AST_AOC_MULT_ONETENTH;
4674 } else if (!strcasecmp(mult, "one")) {
4675 _mult = AST_AOC_MULT_ONE;
4676 } else if (!strcasecmp(mult, "ten")) {
4677 _mult = AST_AOC_MULT_TEN;
4678 } else if (!strcasecmp(mult, "hundred")) {
4679 _mult = AST_AOC_MULT_HUNDRED;
4680 } else if (!strcasecmp(mult, "thousand")) {
4681 _mult = AST_AOC_MULT_THOUSAND;
4682 } else {
4683 astman_send_error(s, m, "Invalid ChargeMultiplier");
4684 goto aocmessage_cleanup;
4685 }
4686 }
4687
4688 if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
4689 if (ast_strlen_zero(timescale)) {
4690 astman_send_error(s, m, "TimeScale unspecified, TimeScale is required when RateType is Duration.");
4691 goto aocmessage_cleanup;
4692 } else if (!strcasecmp(timescale, "onehundredthsecond")) {
4694 } else if (!strcasecmp(timescale, "onetenthsecond")) {
4696 } else if (!strcasecmp(timescale, "second")) {
4698 } else if (!strcasecmp(timescale, "tenseconds")) {
4700 } else if (!strcasecmp(timescale, "minute")) {
4702 } else if (!strcasecmp(timescale, "hour")) {
4703 _scale = AST_AOC_TIME_SCALE_HOUR;
4704 } else if (!strcasecmp(timescale, "day")) {
4705 _scale = AST_AOC_TIME_SCALE_DAY;
4706 } else {
4707 astman_send_error(s, m, "Invalid TimeScale");
4708 goto aocmessage_cleanup;
4709 }
4710
4711 if (ast_strlen_zero(time) || (sscanf(time, "%30u", &_time) != 1)) {
4712 astman_send_error(s, m, "Invalid Time, Time is a required when RateType is Duration");
4713 goto aocmessage_cleanup;
4714 }
4715
4716 if (!ast_strlen_zero(granularity)) {
4717 if ((sscanf(time, "%30u", &_granularity) != 1)) {
4718 astman_send_error(s, m, "Invalid Granularity");
4719 goto aocmessage_cleanup;
4720 }
4721
4722 if (ast_strlen_zero(granularitytimescale)) {
4723 astman_send_error(s, m, "Invalid GranularityTimeScale, GranularityTimeScale is a required when Granularity is specified");
4724 } else if (!strcasecmp(granularitytimescale, "onehundredthsecond")) {
4725 _granularity_time_scale = AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
4726 } else if (!strcasecmp(granularitytimescale, "onetenthsecond")) {
4727 _granularity_time_scale = AST_AOC_TIME_SCALE_TENTH_SECOND;
4728 } else if (!strcasecmp(granularitytimescale, "second")) {
4729 _granularity_time_scale = AST_AOC_TIME_SCALE_SECOND;
4730 } else if (!strcasecmp(granularitytimescale, "tenseconds")) {
4731 _granularity_time_scale = AST_AOC_TIME_SCALE_TEN_SECOND;
4732 } else if (!strcasecmp(granularitytimescale, "minute")) {
4733 _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
4734 } else if (!strcasecmp(granularitytimescale, "hour")) {
4735 _granularity_time_scale = AST_AOC_TIME_SCALE_HOUR;
4736 } else if (!strcasecmp(granularitytimescale, "day")) {
4737 _granularity_time_scale = AST_AOC_TIME_SCALE_DAY;
4738 } else {
4739 astman_send_error(s, m, "Invalid GranularityTimeScale");
4740 goto aocmessage_cleanup;
4741 }
4742 }
4743
4744 if (ast_strlen_zero(chargingtype) || strcasecmp(chargingtype, "continuouscharging") == 0) {
4745 _step = 0;
4746 } else if (strcasecmp(chargingtype, "stepfunction") == 0 ) {
4747 _step = 1;
4748 } else {
4749 astman_send_error(s, m, "Invalid ChargingType");
4750 goto aocmessage_cleanup;
4751 }
4752 }
4753
4754 if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
4755 if (ast_strlen_zero(volumeunit)) {
4756 astman_send_error(s, m, "VolumeUnit unspecified, VolumeUnit is required when RateType is Volume.");
4757 goto aocmessage_cleanup;
4758 } else if (!strcasecmp(timescale, "octet")) {
4759 _volumeunit = AST_AOC_VOLUME_UNIT_OCTET;
4760 } else if (!strcasecmp(timescale, "segment")) {
4761 _volumeunit = AST_AOC_VOLUME_UNIT_SEGMENT;
4762 } else if (!strcasecmp(timescale, "message")) {
4763 _volumeunit = AST_AOC_VOLUME_UNIT_MESSAGE;
4764 }else {
4765 astman_send_error(s, m, "Invalid VolumeUnit");
4766 goto aocmessage_cleanup;
4767 }
4768 }
4769
4771 || _ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
4772 if (ast_strlen_zero(code) || (sscanf(code, "%30u", &_code) != 1)) {
4773 astman_send_error(s, m, "Invalid Code, Code is a required when ChargedItem is SpecialArrangement and when RateType is SpecialCode");
4774 goto aocmessage_cleanup;
4775 }
4776 }
4777
4778 if (_chargeditem == AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT) {
4779 ast_aoc_s_add_special_arrangement(decoded, _code);
4780 } else if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
4781 ast_aoc_s_add_rate_duration(decoded, _chargeditem, _currencyamount, _mult,
4782 currencyname, _time, _scale, _granularity, _granularity_time_scale, _step);
4783 } else if (_ratetype == AST_AOC_RATE_TYPE_FLAT) {
4784 ast_aoc_s_add_rate_flat(decoded, _chargeditem, _currencyamount, _mult,
4785 currencyname);
4786 } else if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
4787 ast_aoc_s_add_rate_volume(decoded, _chargeditem, _volumeunit, _currencyamount,
4788 _mult, currencyname);
4789 } else if (_ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
4790 ast_aoc_s_add_rate_special_charge_code(decoded, _chargeditem, _code);
4791 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE) {
4792 ast_aoc_s_add_rate_free(decoded, _chargeditem, 0);
4793 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
4794 ast_aoc_s_add_rate_free(decoded, _chargeditem, 1);
4795 } else if (_ratetype == AST_AOC_RATE_TYPE_NA) {
4796 ast_aoc_s_add_rate_na(decoded, _chargeditem);
4797 }
4798
4799 return 0;
4800
4801aocmessage_cleanup:
4802
4803 return -1;
4804}
int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name, unsigned long time, enum ast_aoc_time_scale time_scale, unsigned long granularity_time, enum ast_aoc_time_scale granularity_time_scale, int step_function)
Add AOC-S duration rate entry.
Definition: aoc.c:770
ast_aoc_s_charged_item
Definition: aoc.h:145
@ AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION
Definition: aoc.h:148
@ AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT
Definition: aoc.h:147
@ AST_AOC_CHARGED_ITEM_NA
Definition: aoc.h:146
@ AST_AOC_CHARGED_ITEM_USER_USER_INFO
Definition: aoc.h:151
@ AST_AOC_CHARGED_ITEM_CALL_SETUP
Definition: aoc.h:150
@ AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE
Definition: aoc.h:152
@ AST_AOC_CHARGED_ITEM_CALL_ATTEMPT
Definition: aoc.h:149
ast_aoc_time_scale
Definition: aoc.h:87
@ AST_AOC_TIME_SCALE_TEN_SECOND
Definition: aoc.h:91
@ AST_AOC_TIME_SCALE_DAY
Definition: aoc.h:94
@ AST_AOC_TIME_SCALE_TENTH_SECOND
Definition: aoc.h:89
@ AST_AOC_TIME_SCALE_MINUTE
Definition: aoc.h:92
@ AST_AOC_TIME_SCALE_SECOND
Definition: aoc.h:90
@ AST_AOC_TIME_SCALE_HOUR
Definition: aoc.h:93
@ AST_AOC_TIME_SCALE_HUNDREDTH_SECOND
Definition: aoc.h:88
ast_aoc_volume_unit
Definition: aoc.h:125
@ AST_AOC_VOLUME_UNIT_OCTET
Definition: aoc.h:126
@ AST_AOC_VOLUME_UNIT_SEGMENT
Definition: aoc.h:127
@ AST_AOC_VOLUME_UNIT_MESSAGE
Definition: aoc.h:128
int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int code)
Add AOC-S special rate entry.
Definition: aoc.c:844
int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, int from_beginning)
Add AOC-S indicating charge item is free.
Definition: aoc.c:857
int ast_aoc_s_add_special_arrangement(struct ast_aoc_decoded *decoded, unsigned int code)
Add AOC-S special arrangement entry.
Definition: aoc.c:880
int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S flat rate entry.
Definition: aoc.c:801
int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, enum ast_aoc_volume_unit volume_unit, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S volume rate entry.
Definition: aoc.c:822
int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item)
Add AOC-S entry indicating charge item is not available.
Definition: aoc.c:869
ast_aoc_s_rate_type
Definition: aoc.h:155
@ AST_AOC_RATE_TYPE_VOLUME
Definition: aoc.h:161
@ AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING
Definition: aoc.h:158
@ AST_AOC_RATE_TYPE_SPECIAL_CODE
Definition: aoc.h:162
@ AST_AOC_RATE_TYPE_NA
Definition: aoc.h:156
@ AST_AOC_RATE_TYPE_DURATION
Definition: aoc.h:159
@ AST_AOC_RATE_TYPE_FLAT
Definition: aoc.h:160
@ AST_AOC_RATE_TYPE_FREE
Definition: aoc.h:157
static const char * __astman_get_header(const struct message *m, char *var, int mode)
Return a matching header value.
Definition: manager.c:1593

References __astman_get_header(), AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION, AST_AOC_CHARGED_ITEM_CALL_ATTEMPT, AST_AOC_CHARGED_ITEM_CALL_SETUP, AST_AOC_CHARGED_ITEM_NA, AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT, AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE, AST_AOC_CHARGED_ITEM_USER_USER_INFO, 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_RATE_TYPE_DURATION, AST_AOC_RATE_TYPE_FLAT, AST_AOC_RATE_TYPE_FREE, AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING, AST_AOC_RATE_TYPE_NA, AST_AOC_RATE_TYPE_SPECIAL_CODE, AST_AOC_RATE_TYPE_VOLUME, ast_aoc_s_add_rate_duration(), ast_aoc_s_add_rate_flat(), ast_aoc_s_add_rate_free(), ast_aoc_s_add_rate_na(), ast_aoc_s_add_rate_special_charge_code(), ast_aoc_s_add_rate_volume(), ast_aoc_s_add_special_arrangement(), AST_AOC_TIME_SCALE_DAY, AST_AOC_TIME_SCALE_HOUR, AST_AOC_TIME_SCALE_HUNDREDTH_SECOND, AST_AOC_TIME_SCALE_MINUTE, AST_AOC_TIME_SCALE_SECOND, AST_AOC_TIME_SCALE_TEN_SECOND, AST_AOC_TIME_SCALE_TENTH_SECOND, AST_AOC_VOLUME_UNIT_MESSAGE, AST_AOC_VOLUME_UNIT_OCTET, AST_AOC_VOLUME_UNIT_SEGMENT, ast_strlen_zero(), astman_send_error(), and GET_HEADER_LAST_MATCH.

Referenced by action_aoc_s_message().

◆ action_aocmessage()

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

Definition at line 4849 of file manager.c.

4850{
4851 const char *msgtype = astman_get_header(m, "MsgType");
4852 const char *channel = astman_get_header(m, "Channel");
4853 const char *pchannel = astman_get_header(m, "ChannelPrefix");
4854
4855 struct ast_channel *chan = NULL;
4856
4857 struct ast_aoc_decoded *decoded = NULL;
4858 struct ast_aoc_encoded *encoded = NULL;
4859 size_t encoded_size = 0;
4860
4861 if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
4862 astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
4863 goto aocmessage_cleanup;
4864 }
4865
4866 if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
4867 chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
4868 }
4869
4870 if (!chan) {
4871 astman_send_error(s, m, "No such channel");
4872 goto aocmessage_cleanup;
4873 }
4874
4875 if (strcasecmp(msgtype, "d") == 0 || strcasecmp(msgtype, "e") == 0) {
4876 decoded = action_aoc_de_message(s, m);
4877 }
4878 else if (strcasecmp(msgtype, "s") == 0) {
4879 decoded = action_aoc_s_message(s, m);
4880 }
4881 else {
4882 astman_send_error(s, m, "Invalid MsgType");
4883 goto aocmessage_cleanup;
4884 }
4885
4886 if (!decoded) {
4887 goto aocmessage_cleanup;
4888 }
4889
4890 if ((encoded = ast_aoc_encode(decoded, &encoded_size, chan))
4891 && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
4892 astman_send_ack(s, m, "AOC Message successfully queued on channel");
4893 } else {
4894 astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
4895 }
4896
4897aocmessage_cleanup:
4898
4899 ast_aoc_destroy_decoded(decoded);
4900 ast_aoc_destroy_encoded(encoded);
4901
4902 if (chan) {
4903 chan = ast_channel_unref(chan);
4904 }
4905 return 0;
4906}
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:313
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_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1453
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:4672
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3004
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1473
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2001
static struct ast_aoc_decoded * action_aoc_s_message(struct mansession *s, const struct message *m)
Definition: manager.c:4806
static struct ast_aoc_decoded * action_aoc_de_message(struct mansession *s, const struct message *m)
Definition: manager.c:4411
@ AST_CONTROL_AOC
Main Channel structure associated with a channel.

References action_aoc_de_message(), action_aoc_s_message(), ast_aoc_destroy_decoded(), ast_aoc_destroy_encoded(), ast_aoc_encode(), 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 4059 of file manager.c.

4060{
4061 const char *name = astman_get_header(m, "Channel");
4062 const char *exten = astman_get_header(m, "Exten");
4063 const char *context = astman_get_header(m, "Context");
4064 struct ast_channel *chan = NULL;
4065 char feature_code[AST_FEATURE_MAX_LEN];
4066 const char *digit;
4067
4068 if (ast_strlen_zero(name)) {
4069 astman_send_error(s, m, "No channel specified");
4070 return 0;
4071 }
4072 if (ast_strlen_zero(exten)) {
4073 astman_send_error(s, m, "No extension specified");
4074 return 0;
4075 }
4076
4077 if (!(chan = ast_channel_get_by_name(name))) {
4078 astman_send_error(s, m, "Channel specified does not exist");
4079 return 0;
4080 }
4081
4082 ast_channel_lock(chan);
4083 if (ast_get_builtin_feature(chan, "atxfer", feature_code, sizeof(feature_code)) ||
4084 ast_strlen_zero(feature_code)) {
4085 ast_channel_unlock(chan);
4086 astman_send_error(s, m, "No attended transfer feature code found");
4087 ast_channel_unref(chan);
4088 return 0;
4089 }
4090 ast_channel_unlock(chan);
4091
4092 if (!ast_strlen_zero(context)) {
4093 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
4094 }
4095
4096 for (digit = feature_code; *digit; ++digit) {
4097 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4098 ast_queue_frame(chan, &f);
4099 }
4100
4101 for (digit = exten; *digit; ++digit) {
4102 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4103 ast_queue_frame(chan, &f);
4104 }
4105
4106 chan = ast_channel_unref(chan);
4107
4108 astman_send_ack(s, m, "Atxfer successfully queued");
4109
4110 return 0;
4111}
char digit
#define ast_channel_lock(chan)
Definition: channel.h:2968
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:1158
#define ast_channel_unlock(chan)
Definition: channel.h:2969
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.
char exten[AST_MAX_EXTENSION]
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(), voicemailpwcheck::context, digit, 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 4013 of file manager.c.

4014{
4015 const char *name = astman_get_header(m, "Channel");
4016 const char *exten = astman_get_header(m, "Exten");
4017 const char *context = astman_get_header(m, "Context");
4018 struct ast_channel *chan;
4019
4020 if (ast_strlen_zero(name)) {
4021 astman_send_error(s, m, "No channel specified");
4022 return 0;
4023 }
4024
4025 if (ast_strlen_zero(exten)) {
4026 astman_send_error(s, m, "No extension specified");
4027 return 0;
4028 }
4029
4031 if (!chan) {
4032 astman_send_error(s, m, "Channel specified does not exist");
4033 return 0;
4034 }
4035
4036 if (ast_strlen_zero(context)) {
4038 }
4039
4040 switch (ast_bridge_transfer_blind(1, chan, exten, context, NULL, NULL)) {
4042 astman_send_error(s, m, "Transfer not permitted");
4043 break;
4045 astman_send_error(s, m, "Transfer invalid");
4046 break;
4048 astman_send_error(s, m, "Transfer failed");
4049 break;
4051 astman_send_ack(s, m, "Transfer succeeded");
4052 break;
4053 }
4054
4055 ast_channel_unref(chan);
4056 return 0;
4057}
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:4425
@ 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(), voicemailpwcheck::context, 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 4113 of file manager.c.

4114{
4115 const char *name = astman_get_header(m, "Channel");
4116 struct ast_channel *chan = NULL;
4117 char *feature_code;
4118 const char *digit;
4119
4120 if (ast_strlen_zero(name)) {
4121 astman_send_error(s, m, "No channel specified");
4122 return 0;
4123 }
4124
4125 if (!(chan = ast_channel_get_by_name(name))) {
4126 astman_send_error(s, m, "Channel specified does not exist");
4127 return 0;
4128 }
4129
4130 ast_channel_lock(chan);
4131 feature_code = ast_get_chan_features_atxferabort(chan);
4132 ast_channel_unlock(chan);
4133
4134 if (!feature_code) {
4135 astman_send_error(s, m, "No disconnect feature code found");
4136 ast_channel_unref(chan);
4137 return 0;
4138 }
4139
4140 for (digit = feature_code; *digit; ++digit) {
4141 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4142 ast_queue_frame(chan, &f);
4143 }
4144 ast_free(feature_code);
4145
4146 chan = ast_channel_unref(chan);
4147
4148 astman_send_ack(s, m, "CancelAtxfer successfully queued");
4149
4150 return 0;
4151}
#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 3324 of file manager.c.

3325{
3326 const char *authtype = astman_get_header(m, "AuthType");
3327
3328 if (!strcasecmp(authtype, "MD5")) {
3330 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
3331 }
3332 mansession_lock(s);
3333 astman_start_ack(s, m);
3334 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
3336 } else {
3337 astman_send_error(s, m, "Must specify AuthType");
3338 }
3339 return 0;
3340}
static void mansession_unlock(struct mansession *s)
Unlock the 'mansession' structure.
Definition: manager.c:2067
static void mansession_lock(struct mansession *s)
Lock the 'mansession' structure.
Definition: manager.c:2061
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2006
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1890
char challenge[10]
Definition: manager.c:293
struct mansession_session * session
Definition: manager.c:327
long int ast_random(void)
Definition: utils.c:2312

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 4190 of file manager.c.

4191{
4192 const char *cmd = astman_get_header(m, "Command");
4193 char *buf = NULL, *final_buf = NULL, *delim, *output;
4194 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
4195 int fd, ret;
4196 off_t len;
4197
4198 if (ast_strlen_zero(cmd)) {
4199 astman_send_error(s, m, "No command provided");
4200 return 0;
4201 }
4202
4203 if (check_blacklist(cmd)) {
4204 astman_send_error(s, m, "Command blacklisted");
4205 return 0;
4206 }
4207
4208 if ((fd = mkstemp(template)) < 0) {
4209 astman_send_error_va(s, m, "Failed to create temporary file: %s", strerror(errno));
4210 return 0;
4211 }
4212
4213 ret = ast_cli_command(fd, cmd);
4214 astman_send_response_full(s, m, ret == RESULT_SUCCESS ? "Success" : "Error", MSG_MOREDATA, NULL);
4215
4216 /* Determine number of characters available */
4217 if ((len = lseek(fd, 0, SEEK_END)) < 0) {
4218 astman_append(s, "Message: Failed to determine number of characters: %s\r\n", strerror(errno));
4219 goto action_command_cleanup;
4220 }
4221
4222 /* This has a potential to overflow the stack. Hence, use the heap. */
4223 buf = ast_malloc(len + 1);
4224 final_buf = ast_malloc(len + 1);
4225
4226 if (!buf || !final_buf) {
4227 astman_append(s, "Message: Memory allocation failure\r\n");
4228 goto action_command_cleanup;
4229 }
4230
4231 if (lseek(fd, 0, SEEK_SET) < 0) {
4232 astman_append(s, "Message: Failed to set position on temporary file: %s\r\n", strerror(errno));
4233 goto action_command_cleanup;
4234 }
4235
4236 if (read(fd, buf, len) < 0) {
4237 astman_append(s, "Message: Failed to read from temporary file: %s\r\n", strerror(errno));
4238 goto action_command_cleanup;
4239 }
4240
4241 buf[len] = '\0';
4242 term_strip(final_buf, buf, len);
4243 final_buf[len] = '\0';
4244
4245 /* Trim trailing newline */
4246 if (len && final_buf[len - 1] == '\n') {
4247 final_buf[len - 1] = '\0';
4248 }
4249
4250 astman_append(s, "Message: Command output follows\r\n");
4251
4252 delim = final_buf;
4253 while ((output = strsep(&delim, "\n"))) {
4254 astman_append(s, "Output: %s\r\n", output);
4255 }
4256
4257action_command_cleanup:
4258 astman_append(s, "\r\n");
4259
4260 close(fd);
4261 unlink(template);
4262
4263 ast_free(buf);
4264 ast_free(final_buf);
4265
4266 return 0;
4267}
#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:1974
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:1933
static int check_blacklist(const char *cmd)
Definition: manager.c:4154
#define MSG_MOREDATA
Definition: manager.c:1924
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 6374 of file manager.c.

6375{
6376 const char *actionid = astman_get_header(m, "ActionID");
6377 char idText[150];
6378
6379 if (!ast_strlen_zero(actionid)) {
6380 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6381 } else {
6382 idText[0] = '\0';
6383 }
6384
6385 astman_append(s, "Response: Success\r\n"
6386 "%s"
6387 "AMIversion: %s\r\n"
6388 "AsteriskVersion: %s\r\n"
6389 "SystemName: %s\r\n"
6390 "CoreMaxCalls: %d\r\n"
6391 "CoreMaxLoadAvg: %f\r\n"
6392 "CoreRunUser: %s\r\n"
6393 "CoreRunGroup: %s\r\n"
6394 "CoreMaxFilehandles: %d\r\n"
6395 "CoreRealTimeEnabled: %s\r\n"
6396 "CoreCDRenabled: %s\r\n"
6397 "CoreHTTPenabled: %s\r\n"
6398 "SoundsSearchCustomDir: %s\r\n"
6399 "\r\n",
6400 idText,
6413 );
6414 return 0;
6415}
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:2927
#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:688
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:3551
#define AMI_VERSION
Definition: manager.h:57
#define ast_opt_sounds_search_custom
Definition: options.h:138
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_opt_sounds_search_custom, 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_coreshowchannelmap()

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

Manager command "CoreShowChannelMap" - Lists all channels connected to the specified channel.

Definition at line 6658 of file manager.c.

6659{
6660 const char *actionid = astman_get_header(m, "ActionID");
6661 const char *channel_name = astman_get_header(m, "Channel");
6662 char *current_channel_name;
6663 char id_text[256];
6664 int total = 0;
6665 struct ao2_container *channel_map;
6666 struct ao2_iterator i;
6667 RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
6668 RAII_VAR(struct ast_channel_snapshot *, channel_snapshot, NULL, ao2_cleanup);
6669
6670 if (!ast_strlen_zero(actionid)) {
6671 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
6672 } else {
6673 id_text[0] = '\0';
6674 }
6675
6676 if (ast_strlen_zero(channel_name)) {
6677 astman_send_error(s, m, "CoreShowChannelMap requires a channel.\n");
6678 return 0;
6679 }
6680
6681 channel_snapshot = ast_channel_snapshot_get_latest_by_name(channel_name);
6682 if (!channel_snapshot) {
6683 astman_send_error(s, m, "Could not get channel snapshot\n");
6684 return 0;
6685 }
6686
6687 if (ast_strlen_zero(channel_snapshot->bridge->id)) {
6688 astman_send_listack(s, m, "Channel map will follow", "start");
6689 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
6691 return 0;
6692 }
6693
6694 bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(channel_snapshot->bridge->id);
6695 if (!bridge_snapshot) {
6696 astman_send_listack(s, m, "Channel map will follow", "start");
6697 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
6699 return 0;
6700 }
6701
6703 if (!channel_map) {
6704 astman_send_error(s, m, "Could not create channel map\n");
6705 return 0;
6706 }
6707
6708 astman_send_listack(s, m, "Channel map will follow", "start");
6709
6710 if (coreshowchannelmap_add_connected_channels(channel_map, channel_snapshot, bridge_snapshot)) {
6711 astman_send_error(s, m, "Could not complete channel map\n");
6712 ao2_ref(channel_map, -1);
6713 return 0;
6714 }
6715
6716 i = ao2_iterator_init(channel_map, 0);
6717 while ((current_channel_name = ao2_iterator_next(&i))) {
6718 astman_append(s,
6719 "Event: CoreShowChannelMap\r\n"
6720 "%s"
6721 "Channel: %s\r\n"
6722 "ConnectedChannel: %s\r\n\r\n",
6723 id_text,
6724 channel_name,
6725 current_channel_name);
6726 total++;
6727 }
6729
6730 ao2_ref(channel_map, -1);
6731 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", total);
6733
6734 return 0;
6735}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT
Reject duplicate objects in container.
Definition: astobj2.h:1201
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:2011
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:2047
static int coreshowchannelmap_add_connected_channels(struct ao2_container *channel_map, struct ast_channel_snapshot *channel_snapshot, struct ast_bridge_snapshot *bridge_snapshot)
Recursive function to get all channels in a bridge. Follow local channels as well.
Definition: manager.c:6574
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2055
struct ast_channel_snapshot * ast_channel_snapshot_get_latest_by_name(const char *name)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
static int total
Definition: res_adsi.c:970
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
Definition: strings.c:200
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
Structure representing a snapshot of channel state.
#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:941

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_bridge_get_snapshot_by_uniqueid(), ast_channel_snapshot_get_latest_by_name(), ast_str_container_alloc_options(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), coreshowchannelmap_add_connected_channels(), NULL, RAII_VAR, and total.

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 6490 of file manager.c.

6491{
6492 const char *actionid = astman_get_header(m, "ActionID");
6493 char idText[256];
6494 int numchans = 0;
6495 struct ao2_container *channels;
6496 struct ao2_iterator it_chans;
6497 struct ast_channel_snapshot *cs;
6498
6499 if (!ast_strlen_zero(actionid)) {
6500 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6501 } else {
6502 idText[0] = '\0';
6503 }
6504
6506
6507 astman_send_listack(s, m, "Channels will follow", "start");
6508
6509 it_chans = ao2_iterator_init(channels, 0);
6510 for (; (cs = ao2_iterator_next(&it_chans)); ao2_ref(cs, -1)) {
6512 char durbuf[16] = "";
6513
6514 if (!built) {
6515 continue;
6516 }
6517
6518 if (!ast_tvzero(cs->base->creationtime)) {
6519 int duration, durh, durm, durs;
6520
6521 duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
6522 durh = duration / 3600;
6523 durm = (duration % 3600) / 60;
6524 durs = duration % 60;
6525 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
6526 }
6527
6528 astman_append(s,
6529 "Event: CoreShowChannel\r\n"
6530 "%s"
6531 "%s"
6532 "Application: %s\r\n"
6533 "ApplicationData: %s\r\n"
6534 "Duration: %s\r\n"
6535 "BridgeId: %s\r\n"
6536 "\r\n",
6537 idText,
6538 ast_str_buffer(built),
6539 cs->dialplan->appl,
6540 cs->dialplan->data,
6541 durbuf,
6542 cs->bridge->id);
6543
6544 numchans++;
6545
6546 ast_free(built);
6547 }
6548 ao2_iterator_destroy(&it_chans);
6549
6550 astman_send_list_complete(s, m, "CoreShowChannelsComplete", numchans);
6551
6552 ao2_ref(channels, -1);
6553 return 0;
6554}
static struct channel_usage channels
static void astman_send_list_complete(struct mansession *s, const struct message *m, const char *event_name, int count)
Definition: manager.c:2038
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
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:117
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107

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 6418 of file manager.c.

6419{
6420 const char *actionid = astman_get_header(m, "ActionID");
6421 char idText[150];
6422 char startuptime[150], startupdate[150];
6423 char reloadtime[150], reloaddate[150];
6424 struct ast_tm tm;
6425
6426 if (!ast_strlen_zero(actionid)) {
6427 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6428 } else {
6429 idText[0] = '\0';
6430 }
6431
6433 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
6434 ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
6436 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
6437 ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
6438
6439 astman_append(s, "Response: Success\r\n"
6440 "%s"
6441 "CoreStartupDate: %s\r\n"
6442 "CoreStartupTime: %s\r\n"
6443 "CoreReloadDate: %s\r\n"
6444 "CoreReloadTime: %s\r\n"
6445 "CoreCurrentCalls: %d\r\n"
6446 "\r\n",
6447 idText,
6448 startupdate,
6449 startuptime,
6450 reloaddate,
6451 reloadtime,
6453 );
6454 return 0;
6455}
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
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
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 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 3070 of file manager.c.

3071{
3072 int fd;
3073 const char *fn = astman_get_header(m, "Filename");
3074 struct ast_str *filepath = ast_str_alloca(PATH_MAX);
3075 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
3076 ast_str_append(&filepath, 0, "%s", fn);
3077
3078 if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
3079 close(fd);
3080 astman_send_ack(s, m, "New configuration file created successfully");
3081 } else {
3082 astman_send_error(s, m, strerror(errno));
3083 }
3084
3085 return 0;
3086}
#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 7718 of file manager.c.

7719{
7720 struct manager_action *doomed = obj;
7721
7722 if (doomed->synopsis) {
7723 /* The string fields were initialized. */
7725 }
7726 ao2_cleanup(doomed->final_response);
7727 ao2_cleanup(doomed->list_responses);
7728}
#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 3225 of file manager.c.

3226{
3227 const char *mask = astman_get_header(m, "EventMask");
3228 int res, x;
3229 const char *id = astman_get_header(m, "ActionID");
3230 char id_text[256];
3231
3232 if (!ast_strlen_zero(id)) {
3233 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3234 } else {
3235 id_text[0] = '\0';
3236 }
3237
3238 res = set_eventmask(s, mask);
3240 /* if this option is set we should not return a response on
3241 * error, or when all events are set */
3242
3243 if (res > 0) {
3244 for (x = 0; x < ARRAY_LEN(perms); x++) {
3245 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
3246 return 0;
3247 }
3248 }
3249 astman_append(s, "Response: Success\r\n%s"
3250 "Events: On\r\n\r\n", id_text);
3251 } else if (res == 0)
3252 astman_append(s, "Response: Success\r\n%s"
3253 "Events: Off\r\n\r\n", id_text);
3254 return 0;
3255 }
3256
3257 if (res > 0)
3258 astman_append(s, "Response: Success\r\n%s"
3259 "Events: On\r\n\r\n", id_text);
3260 else if (res == 0)
3261 astman_append(s, "Response: Success\r\n%s"
3262 "Events: Off\r\n\r\n", id_text);
3263 else
3264 astman_send_error(s, m, "Invalid event mask");
3265
3266 return 0;
3267}
static int broken_events_action
Definition: manager.c:168
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:2076
static const struct permalias perms[]
int num
Definition: manager.c:750
#define ARRAY_LEN(a)
Definition: utils.h:666

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 5375 of file manager.c.

5376{
5377 const char *exten = astman_get_header(m, "Exten");
5378 const char *context = astman_get_header(m, "Context");
5379 char hint[256];
5380 int status;
5381
5382 if (ast_strlen_zero(exten)) {
5383 astman_send_error(s, m, "Extension not specified");
5384 return 0;
5385 }
5386 if (ast_strlen_zero(context)) {
5387 context = "default";
5388 }
5390 hint[0] = '\0';
5391 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
5392 astman_start_ack(s, m);
5393 astman_append(s, "Message: Extension Status\r\n"
5394 "Exten: %s\r\n"
5395 "Context: %s\r\n"
5396 "Hint: %s\r\n"
5397 "Status: %d\r\n"
5398 "StatusText: %s\r\n"
5399 "\r\n",
5400 exten, context, hint, status,
5402 return 0;
5403}
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:3126
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:4137
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:3170

References ast_extension_state(), ast_extension_state2str(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), voicemailpwcheck::context, 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 5597 of file manager.c.

5598{
5599 const char *match_criteria = astman_get_header(m, "MatchCriteria");
5600 const char *filter = astman_get_header(m, "Filter");
5601 const char *operation = astman_get_header(m, "Operation");
5602 int res;
5603
5604 if (!strcasecmp(operation, "Add")) {
5605 char *criteria;
5606 int have_match = !ast_strlen_zero(match_criteria);
5607
5608 /* Create an eventfilter expression.
5609 * eventfilter[(match_criteria)]
5610 */
5611 res = ast_asprintf(&criteria, "eventfilter%s%s%s",
5612 S_COR(have_match, "(", ""), S_OR(match_criteria, ""),
5613 S_COR(have_match, ")", ""));
5614 if (res <= 0) {
5615 astman_send_error(s, m, "Internal Error. Failed to allocate storage for filter type");
5616 return 0;
5617 }
5618
5620 ast_std_free(criteria);
5621 if (res != FILTER_SUCCESS) {
5622 if (res == FILTER_ALLOC_FAILED) {
5623 astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
5624 return 0;
5625 } else if (res == FILTER_COMPILE_FAIL) {
5626 astman_send_error(s, m,
5627 "Filter did not compile. Check the syntax of the filter given.");
5628 return 0;
5629 } else if (res == FILTER_FORMAT_ERROR) {
5630 astman_send_error(s, m,
5631 "Filter was formatted incorrectly. Check the syntax of the filter given.");
5632 return 0;
5633 } else {
5634 astman_send_error(s, m, "Internal Error. Failed adding filter.");
5635 return 0;
5636 }
5637 }
5638
5639 astman_send_ack(s, m, "Success");
5640 return 0;
5641 }
5642
5643 astman_send_error(s, m, "Unknown operation");
5644 return 0;
5645}
void ast_std_free(void *ptr)
Definition: astmm.c:1734
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:807
static enum add_filter_result manager_add_filter(const char *criteria, const char *filter_pattern, struct ao2_container *includefilters, struct ao2_container *excludefilters)
Add an event filter to a manager session.
Definition: manager.c:5664
#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
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
struct ao2_container * excludefilters
Definition: manager.c:300
struct ao2_container * includefilters
Definition: manager.c:299

References ast_asprintf, ast_std_free(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), mansession_session::excludefilters, filter(), FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL, FILTER_FORMAT_ERROR, FILTER_SUCCESS, mansession_session::includefilters, manager_add_filter(), S_COR, S_OR, and mansession::session.

Referenced by __init_manager().

◆ action_find()

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

Definition at line 437 of file manager.c.

438{
439 struct manager_action *act;
440
442 AST_RWLIST_TRAVERSE(&actions, act, list) {
443 if (!strcasecmp(name, act->action)) {
444 ao2_t_ref(act, +1, "found action object");
445 break;
446 }
447 }
449
450 return act;
451}
#define ao2_t_ref(o, delta, tag)
Definition: astobj2.h:460
list of actions registered
Definition: manager.c:366
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 2484 of file manager.c.

2485{
2486 struct ast_config *cfg;
2487 const char *fn = astman_get_header(m, "Filename");
2488 const char *category = astman_get_header(m, "Category");
2489 const char *filter = astman_get_header(m, "Filter");
2490 const char *category_name;
2491 int catcount = 0;
2492 int lineno = 0;
2493 int ret = 0;
2494 struct ast_category *cur_category = NULL;
2495 struct ast_variable *v;
2496 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2497
2498 if (ast_strlen_zero(fn)) {
2499 astman_send_error(s, m, "Filename not specified");
2500 return 0;
2501 }
2502
2503 ret = restrictedFile(fn);
2504 if (ret == 1) {
2505 astman_send_error(s, m, "File requires escalated priveledges");
2506 return 0;
2507 } else if (ret == -1) {
2508 astman_send_error(s, m, "Config file not found");
2509 return 0;
2510 }
2511
2512 cfg = ast_config_load2(fn, "manager", config_flags);
2513 if (cfg == CONFIG_STATUS_FILEMISSING) {
2514 astman_send_error(s, m, "Config file not found");
2515 return 0;
2516 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2517 astman_send_error(s, m, "Config file has invalid format");
2518 return 0;
2519 }
2520
2521 astman_start_ack(s, m);
2522 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
2523 struct ast_str *templates;
2524
2525 category_name = ast_category_get_name(cur_category);
2526 lineno = 0;
2527 astman_append(s, "Category-%06d: %s\r\n", catcount, category_name);
2528
2529 if (ast_category_is_template(cur_category)) {
2530 astman_append(s, "IsTemplate-%06d: %d\r\n", catcount, 1);
2531 }
2532
2533 if ((templates = ast_category_get_templates(cur_category))
2534 && ast_str_strlen(templates) > 0) {
2535 astman_append(s, "Templates-%06d: %s\r\n", catcount, ast_str_buffer(templates));
2537 }
2538
2539 for (v = ast_category_first(cur_category); v; v = v->next) {
2540 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
2541 }
2542
2543 catcount++;
2544 }
2545
2546 if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2547 astman_append(s, "No categories found\r\n");
2548 }
2549
2550 ast_config_destroy(cfg);
2551 astman_append(s, "\r\n");
2552
2553 return 0;
2554}
static int restrictedFile(const char *filename)
Check if a file is restricted or not.
Definition: manager.c:2451
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1118
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:3328
#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:1128
#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:1123
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1247
@ CONFIG_FLAG_NOCACHE
@ CONFIG_FLAG_WITHCOMMENTS
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:1425
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:730
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, restrictedFile(), 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 2622 of file manager.c.

2623{
2624 struct ast_config *cfg;
2625 const char *fn = astman_get_header(m, "Filename");
2626 const char *filter = astman_get_header(m, "Filter");
2627 const char *category = astman_get_header(m, "Category");
2628 struct ast_category *cur_category = NULL;
2629 const char *category_name;
2630 struct ast_variable *v;
2631 int comma1 = 0;
2632 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2633
2634 if (ast_strlen_zero(fn)) {
2635 astman_send_error(s, m, "Filename not specified");
2636 return 0;
2637 }
2638
2639 if (restrictedFile(fn)) {
2640 astman_send_error(s, m, "File requires escalated priveledges");
2641 return 0;
2642 }
2643
2644 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2645 astman_send_error(s, m, "Config file not found");
2646 return 0;
2647 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2648 astman_send_error(s, m, "Config file has invalid format");
2649 return 0;
2650 }
2651
2652 astman_start_ack(s, m);
2653 astman_append(s, "JSON: {");
2654 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
2655 int comma2 = 0;
2656 struct ast_str *templates;
2657
2658 category_name = ast_category_get_name(cur_category);
2659 astman_append(s, "%s\"", comma1 ? "," : "");
2660 astman_append_json(s, category_name);
2661 astman_append(s, "\":{");
2662 comma1 = 1;
2663
2664 if (ast_category_is_template(cur_category)) {
2665 astman_append(s, "\"istemplate\":1");
2666 comma2 = 1;
2667 }
2668
2669 if ((templates = ast_category_get_templates(cur_category))
2670 && ast_str_strlen(templates) > 0) {
2671 astman_append(s, "%s", comma2 ? "," : "");
2672 astman_append(s, "\"templates\":\"%s\"", ast_str_buffer(templates));
2674 comma2 = 1;
2675 }
2676
2677 for (v = ast_category_first(cur_category); v; v = v->next) {
2678 astman_append(s, "%s\"", comma2 ? "," : "");
2679 astman_append_json(s, v->name);
2680 astman_append(s, "\":\"");
2682 astman_append(s, "\"");
2683 comma2 = 1;
2684 }
2685
2686 astman_append(s, "}");
2687 }
2688 astman_append(s, "}\r\n\r\n");
2689
2690 ast_config_destroy(cfg);
2691
2692 return 0;
2693}
static void astman_append_json(struct mansession *s, const char *str)
Definition: manager.c:2613

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, restrictedFile(), 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 3502 of file manager.c.

3503{
3504 struct ast_channel *c = NULL;
3505 const char *name = astman_get_header(m, "Channel");
3506 const char *varname = astman_get_header(m, "Variable");
3507 char *varval;
3508 char workspace[1024];
3509
3510 if (ast_strlen_zero(varname)) {
3511 astman_send_error(s, m, "No variable specified");
3512 return 0;
3513 }
3514
3515 /* We don't want users with insufficient permissions using certain functions. */
3517 astman_send_error(s, m, "GetVar Access Forbidden: Variable");
3518 return 0;
3519 }
3520
3521 if (!ast_strlen_zero(name)) {
3522 if (!(c = ast_channel_get_by_name(name))) {
3523 astman_send_error(s, m, "No such channel");
3524 return 0;
3525 }
3526 }
3527
3528 workspace[0] = '\0';
3529 if (varname[strlen(varname) - 1] == ')') {
3530 if (!c) {
3532 if (c) {
3533 ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
3534 } else
3535 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
3536 } else {
3537 ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
3538 }
3539 varval = workspace;
3540 } else {
3541 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
3542 }
3543
3544 if (c) {
3546 }
3547
3548 astman_start_ack(s, m);
3549 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
3550
3551 return 0;
3552}
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1328
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:780
#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.
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 3463 of file manager.c.

3464{
3465 return ast_manager_hangup_helper(s, m,
3467}
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
int ast_manager_hangup_helper(struct mansession *s, const struct message *m, manager_hangup_handler_t hangup_handler, manager_hangup_cause_validator_t cause_validator)
A manager helper function that hangs up a channel using a supplied channel type specific hangup funct...
Definition: manager.c:3342

References ast_channel_softhangup_withcause_locked(), ast_manager_hangup_helper(), and NULL.

Referenced by __init_manager().

◆ action_listcategories()

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

Definition at line 2556 of file manager.c.

2557{
2558 struct ast_config *cfg;
2559 const char *fn = astman_get_header(m, "Filename");
2560 const char *match = astman_get_header(m, "Match");
2561 struct ast_category *category = NULL;
2562 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2563 int catcount = 0;
2564
2565 if (ast_strlen_zero(fn)) {
2566 astman_send_error(s, m, "Filename not specified");
2567 return 0;
2568 }
2569
2570 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2571 astman_send_error(s, m, "Config file not found");
2572 return 0;
2573 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2574 astman_send_error(s, m, "Config file has invalid format");
2575 return 0;
2576 }
2577
2578 astman_start_ack(s, m);
2579 while ((category = ast_category_browse_filtered(cfg, NULL, category, match))) {
2580 astman_append(s, "Category-%06d: %s\r\n", catcount, ast_category_get_name(category));
2581 catcount++;
2582 }
2583
2584 if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2585 astman_append(s, "Error: no categories found\r\n");
2586 }
2587
2588 ast_config_destroy(cfg);
2589 astman_append(s, "\r\n");
2590
2591 return 0;
2592}
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:2362

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 3206 of file manager.c.

3207{
3208 struct manager_action *cur;
3210
3211 astman_start_ack(s, m);
3213 AST_RWLIST_TRAVERSE(&actions, cur, list) {
3214 if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
3215 astman_append(s, "%s: %s (Priv: %s)\r\n",
3216 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
3217 }
3218 }
3220 astman_append(s, "\r\n");
3221
3222 return 0;
3223}

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 6739 of file manager.c.

6740{
6741 if (ast_logger_rotate()) {
6742 astman_send_error(s, m, "Failed to reload the logger and rotate log files");
6743 return 0;
6744 }
6745
6746 astman_send_ack(s, m, "Reloaded the logger and rotated log files");
6747 return 0;
6748}
int ast_logger_rotate(void)
Reload logger while rotating log files.
Definition: logger.c:1327

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 3275 of file manager.c.

3276{
3277
3278 /* still authenticated - don't process again */
3279 if (s->session->authenticated) {
3280 astman_send_ack(s, m, "Already authenticated");
3281 return 0;
3282 }
3283
3284 if (authenticate(s, m)) {
3285 sleep(1);
3286 astman_send_error(s, m, "Authentication failed");
3287 return -1;
3288 }
3289 s->session->authenticated = 1;
3292 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
3293 }
3294 astman_send_ack(s, m, "Authentication accepted");
3299 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
3300 long uptime = 0;
3301 long lastreloaded = 0;
3302 struct timeval tmp;
3303 struct timeval curtime = ast_tvnow();
3304
3305 if (ast_startuptime.tv_sec) {
3306 tmp = ast_tvsub(curtime, ast_startuptime);
3307 uptime = tmp.tv_sec;
3308 }
3309
3310 if (ast_lastreloadtime.tv_sec) {
3311 tmp = ast_tvsub(curtime, ast_lastreloadtime);
3312 lastreloaded = tmp.tv_sec;
3313 }
3314
3315 astman_append(s, "Event: FullyBooted\r\n"
3316 "Privilege: %s\r\n"
3317 "Uptime: %ld\r\n"
3318 "LastReload: %ld\r\n"
3319 "Status: Fully Booted\r\n\r\n", cat_str, uptime, lastreloaded);
3320 }
3321 return 0;
3322}
static int tmp()
Definition: bt_open.c:389
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1062
static int unauth_sessions
Definition: manager.c:181
static int authenticate(struct mansession *s, const struct message *m)
Definition: manager.c:2315
struct ast_flags ast_options
Definition: options.c:61
@ AST_OPT_FLAG_FULLY_BOOTED
Definition: options.h:58
#define ast_verb(level,...)
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
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
struct ast_sockaddr addr
Definition: manager.c:283
uint32_t managerid
Definition: manager.c:288
char username[80]
Definition: manager.c:292
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 3269 of file manager.c.

3270{
3271 astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
3272 return -1;
3273}
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition: manager.c:1964

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 5354 of file manager.c.

5355{
5356 const char *mailbox = astman_get_header(m, "Mailbox");
5357 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
5358
5359 if (ast_strlen_zero(mailbox)) {
5360 astman_send_error(s, m, "Mailbox not specified");
5361 return 0;
5362 }
5363 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
5364 astman_start_ack(s, m);
5365 astman_append(s, "Message: Mailbox Message Count\r\n"
5366 "Mailbox: %s\r\n"
5367 "UrgMessages: %d\r\n"
5368 "NewMessages: %d\r\n"
5369 "OldMessages: %d\r\n"
5370 "\r\n",
5371 mailbox, urgentmsgs, newmsgs, oldmsgs);
5372 return 0;
5373}
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:619

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

Referenced by __init_manager().

◆ action_mailboxstatus()

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

Definition at line 5337 of file manager.c.

5338{
5339 const char *mailbox = astman_get_header(m, "Mailbox");
5340 int ret;
5341
5342 if (ast_strlen_zero(mailbox)) {
5343 astman_send_error(s, m, "Mailbox not specified");
5344 return 0;
5345 }
5347 astman_start_ack(s, m);
5348 astman_append(s, "Message: Mailbox Status\r\n"
5349 "Mailbox: %s\r\n"
5350 "Waiting: %d\r\n\r\n", mailbox, ret);
5351 return 0;
5352}
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:582

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

Referenced by __init_manager().

◆ action_originate()

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

Definition at line 5142 of file manager.c.

5143{
5144 const char *name = astman_get_header(m, "Channel");
5145 const char *exten = astman_get_header(m, "Exten");
5146 const char *context = astman_get_header(m, "Context");
5147 const char *priority = astman_get_header(m, "Priority");
5148 const char *timeout = astman_get_header(m, "Timeout");
5149 const char *callerid = astman_get_header(m, "CallerID");
5150 const char *account = astman_get_header(m, "Account");
5151 const char *app = astman_get_header(m, "Application");
5152 const char *appdata = astman_get_header(m, "Data");
5153 const char *async = astman_get_header(m, "Async");
5154 const char *id = astman_get_header(m, "ActionID");
5155 const char *codecs = astman_get_header(m, "Codecs");
5156 const char *early_media = astman_get_header(m, "Earlymedia");
5157 struct ast_assigned_ids assignedids = {
5158 .uniqueid = astman_get_header(m, "ChannelId"),
5159 .uniqueid2 = astman_get_header(m, "OtherChannelId"),
5160 };
5161 const char *gosub = astman_get_header(m, "PreDialGoSub");
5162
5163 struct ast_variable *vars = NULL;
5164 char *tech, *data;
5165 char *l = NULL, *n = NULL;
5166 int pi = 0;
5167 int res;
5168 int to = 30000;
5169 int reason = 0;
5170 char tmp[256];
5171 char tmp2[256];
5173 pthread_t th;
5174 int bridge_early = 0;
5175
5176 if (!cap) {
5177 astman_send_error(s, m, "Internal Error. Memory allocation failure.");
5178 return 0;
5179 }
5181
5182 if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
5183 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
5184 astman_send_error_va(s, m, "Uniqueid length exceeds maximum of %d\n",
5186 res = 0;
5187 goto fast_orig_cleanup;
5188 }
5189
5190 if (ast_strlen_zero(name)) {
5191 astman_send_error(s, m, "Channel not specified");
5192 res = 0;
5193 goto fast_orig_cleanup;
5194 }
5195 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
5196 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
5197 astman_send_error(s, m, "Invalid priority");
5198 res = 0;
5199 goto fast_orig_cleanup;
5200 }
5201 }
5202 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
5203 astman_send_error(s, m, "Invalid timeout");
5204 res = 0;
5205 goto fast_orig_cleanup;
5206 }
5207 ast_copy_string(tmp, name, sizeof(tmp));
5208 tech = tmp;
5209 data = strchr(tmp, '/');
5210 if (!data) {
5211 astman_send_error(s, m, "Invalid channel");
5212 res = 0;
5213 goto fast_orig_cleanup;
5214 }
5215 *data++ = '\0';
5216 ast_copy_string(tmp2, callerid, sizeof(tmp2));
5217 ast_callerid_parse(tmp2, &n, &l);
5218 if (n) {
5219 if (ast_strlen_zero(n)) {
5220 n = NULL;
5221 }
5222 }
5223 if (l) {
5225 if (ast_strlen_zero(l)) {
5226 l = NULL;
5227 }
5228 }
5229 if (!ast_strlen_zero(codecs)) {
5232 }
5233
5234 if (!ast_strlen_zero(app) && s->session) {
5235 if (!is_originate_app_permitted(app, appdata, s->session->writeperm)) {
5236 astman_send_error(s, m, "Originate Access Forbidden: app or data blacklisted");
5237 res = 0;
5238 goto fast_orig_cleanup;
5239 }
5240 }
5241
5242 /* Check early if the extension exists. If not, we need to bail out here. */
5243 if (exten && context && pi) {
5244 if (! ast_exists_extension(NULL, context, exten, pi, l)) {
5245 /* The extension does not exist. */
5246 astman_send_error(s, m, "Extension does not exist.");
5247 res = 0;
5248 goto fast_orig_cleanup;
5249 }
5250 }
5251
5252 /* Allocate requested channel variables */
5253 vars = astman_get_variables(m);
5254 if (s->session && s->session->chanvars) {
5255 struct ast_variable *v, *old;
5256 old = vars;
5257 vars = NULL;
5258
5259 /* The variables in the AMI originate action are appended at the end of the list, to override any user variables that apply */
5260
5262 if (old) {
5263 for (v = vars; v->next; v = v->next );
5264 v->next = old; /* Append originate variables at end of list */
5265 }
5266 }
5267
5268 /* For originate async - we can bridge in early media stage */
5269 bridge_early = ast_true(early_media);
5270
5271 if (ast_true(async)) {
5272 struct fast_originate_helper *fast;
5273
5274 fast = ast_calloc(1, sizeof(*fast));
5275 if (!fast || ast_string_field_init(fast, 252)) {
5276 ast_free(fast);
5278 res = -1;
5279 } else {
5280 if (!ast_strlen_zero(id)) {
5281 ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
5282 }
5287 ast_string_field_set(fast, cid_num, l);
5292 ast_string_field_set(fast, channelid, assignedids.uniqueid);
5293 ast_string_field_set(fast, otherchannelid, assignedids.uniqueid2);
5294 fast->vars = vars;
5295 fast->cap = cap;
5296 cap = NULL; /* transfered originate helper the capabilities structure. It is now responsible for freeing it. */
5297 fast->timeout = to;
5298 fast->early_media = bridge_early;
5299 fast->priority = pi;
5302 res = -1;
5303 } else {
5304 res = 0;
5305 }
5306 }
5307 } else if (!ast_strlen_zero(app)) {
5308 res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason,
5310 assignedids.uniqueid ? &assignedids : NULL);
5312 } else {
5313 if (exten && context && pi) {
5315 context, exten, pi, &reason, AST_OUTGOING_WAIT,
5316 l, n, vars, account, NULL, bridge_early,
5317 assignedids.uniqueid ? &assignedids : NULL , gosub);
5319 } else {
5320 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
5322 res = 0;
5323 goto fast_orig_cleanup;
5324 }
5325 }
5326 if (!res) {
5327 astman_send_ack(s, m, "Originate successfully queued");
5328 } else {
5329 astman_send_error(s, m, "Originate failed");
5330 }
5331
5332fast_orig_cleanup:
5334 return 0;
5335}
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:1162
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:1101
static int priority
#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
static int is_originate_app_permitted(const char *app, const char *data, int permission)
Definition: manager.c:5036
static void destroy_fast_originate_helper(struct fast_originate_helper *doomed)
Definition: manager.c:4298
struct ast_variable * astman_get_variables(const struct message *m)
Get a linked list of the Variable: headers.
Definition: manager.c:1716
static void * fast_originate(void *data)
Definition: manager.c:4306
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:544
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:4180
int ast_pbx_outgoing_exten_predial(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, const char *predial_callee)
Definition: pbx.c:7926
@ AST_OUTGOING_WAIT
Definition: pbx.h:1141
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.
Definition: pbx.c:7980
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:4175
#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: utils.c:2199
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:606
const char * uniqueid2
Definition: channel.h:608
const char * uniqueid
Definition: channel.h:607
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
helper function for originate
Definition: manager.c:4270
const ast_string_field appdata
Definition: manager.c:4288
struct ast_variable * vars
Definition: manager.c:4290
const ast_string_field cid_num
Definition: manager.c:4288
const ast_string_field account
Definition: manager.c:4288
const ast_string_field tech
Definition: manager.c:4288
const ast_string_field data
Definition: manager.c:4288
const ast_string_field channelid
Definition: manager.c:4288
const ast_string_field otherchannelid
Definition: manager.c:4288
struct ast_format_cap * cap
Definition: manager.c:4272
const ast_string_field exten
Definition: manager.c:4288
const ast_string_field idtext
Definition: manager.c:4288
const ast_string_field cid_name
Definition: manager.c:4288
struct ast_variable * chanvars
Definition: manager.c:301
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588

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_predial(), 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, codecs, voicemailpwcheck::context, destroy_fast_originate_helper(), fast_originate_helper::early_media, fast_originate(), is_originate_app_permitted(), name, ast_variable::next, NULL, priority, fast_originate_helper::priority, mansession::session, 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 2412 of file manager.c.

2413{
2414 const char *actionid = astman_get_header(m, "ActionID");
2415 struct timeval now = ast_tvnow();
2416
2417 astman_append(s, "Response: Success\r\n");
2418 if (!ast_strlen_zero(actionid)){
2419 astman_append(s, "ActionID: %s\r\n", actionid);
2420 }
2422 s,
2423 "Ping: Pong\r\n"
2424 "Timestamp: %ld.%06lu\r\n"
2425 "\r\n",
2426 (long) now.tv_sec, (unsigned long) now.tv_usec);
2427 return 0;
2428}

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 5405 of file manager.c.

5406{
5407 const char *provider = astman_get_header(m, "Provider");
5409 char *subtype;
5410 char *message;
5411
5413 astman_send_error(s, m, "No provider specified");
5414 return 0;
5415 }
5416
5418 if (state == AST_PRESENCE_INVALID) {
5419 astman_send_error_va(s, m, "Invalid provider %s or provider in invalid state", provider);
5420 return 0;
5421 }
5422
5423 astman_start_ack(s, m);
5424 astman_append(s, "Message: Presence State\r\n"
5425 "State: %s\r\n", ast_presence_state2str(state));
5426
5427 if (!ast_strlen_zero(subtype)) {
5428 astman_append(s, "Subtype: %s\r\n", subtype);
5429 }
5430
5431 if (!ast_strlen_zero(message)) {
5432 /* XXX The Message header here is deprecated as it
5433 * duplicates the action response header 'Message'.
5434 * Remove it in the next major revision of AMI.
5435 */
5436 astman_append(s, "Message: %s\r\n"
5437 "PresenceMessage: %s\r\n",
5438 message, message);
5439 }
5440 astman_append(s, "\r\n");
5441
5442 return 0;
5443}
static struct prometheus_metrics_provider provider
Definition: bridges.c:201
enum cc_state state
Definition: ccss.c:393
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 3868 of file manager.c.

3869{
3870 char buf[256];
3871 const char *name = astman_get_header(m, "Channel");
3872 const char *name2 = astman_get_header(m, "ExtraChannel");
3873 const char *exten = astman_get_header(m, "Exten");
3874 const char *exten2 = astman_get_header(m, "ExtraExten");
3875 const char *context = astman_get_header(m, "Context");
3876 const char *context2 = astman_get_header(m, "ExtraContext");
3877 const char *priority = astman_get_header(m, "Priority");
3878 const char *priority2 = astman_get_header(m, "ExtraPriority");
3879 struct ast_channel *chan;
3880 struct ast_channel *chan2;
3881 int pi = 0;
3882 int pi2 = 0;
3883 int res;
3884 int chan1_wait = 0;
3885 int chan2_wait = 0;
3886
3887 if (ast_strlen_zero(name)) {
3888 astman_send_error(s, m, "Channel not specified");
3889 return 0;
3890 }
3891
3892 if (ast_strlen_zero(context)) {
3893 astman_send_error(s, m, "Context not specified");
3894 return 0;
3895 }
3896 if (ast_strlen_zero(exten)) {
3897 astman_send_error(s, m, "Exten not specified");
3898 return 0;
3899 }
3901 astman_send_error(s, m, "Priority not specified");
3902 return 0;
3903 }
3904 if (sscanf(priority, "%30d", &pi) != 1) {
3906 }
3907 if (pi < 1) {
3908 astman_send_error(s, m, "Priority is invalid");
3909 return 0;
3910 }
3911
3912 if (!ast_strlen_zero(name2) && !ast_strlen_zero(context2)) {
3913 /* We have an ExtraChannel and an ExtraContext */
3914 if (ast_strlen_zero(exten2)) {
3915 astman_send_error(s, m, "ExtraExten not specified");
3916 return 0;
3917 }
3918 if (ast_strlen_zero(priority2)) {
3919 astman_send_error(s, m, "ExtraPriority not specified");
3920 return 0;
3921 }
3922 if (sscanf(priority2, "%30d", &pi2) != 1) {
3923 pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL);
3924 }
3925 if (pi2 < 1) {
3926 astman_send_error(s, m, "ExtraPriority is invalid");
3927 return 0;
3928 }
3929 }
3930
3932 if (!chan) {
3933 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
3934 astman_send_error(s, m, buf);
3935 return 0;
3936 }
3937 if (ast_check_hangup_locked(chan)) {
3938 astman_send_error(s, m, "Redirect failed, channel not up.");
3939 chan = ast_channel_unref(chan);
3940 return 0;
3941 }
3942
3943 if (ast_strlen_zero(name2)) {
3944 /* Single channel redirect in progress. */
3945 res = ast_async_goto(chan, context, exten, pi);
3946 if (!res) {
3947 astman_send_ack(s, m, "Redirect successful");
3948 } else {
3949 astman_send_error(s, m, "Redirect failed");
3950 }
3951 chan = ast_channel_unref(chan);
3952 return 0;
3953 }
3954
3955 chan2 = ast_channel_get_by_name(name2);
3956 if (!chan2) {
3957 snprintf(buf, sizeof(buf), "ExtraChannel does not exist: %s", name2);
3958 astman_send_error(s, m, buf);
3959 chan = ast_channel_unref(chan);
3960 return 0;
3961 }
3962 if (ast_check_hangup_locked(chan2)) {
3963 astman_send_error(s, m, "Redirect failed, extra channel not up.");
3964 chan2 = ast_channel_unref(chan2);
3965 chan = ast_channel_unref(chan);
3966 return 0;
3967 }
3968
3969 /* Dual channel redirect in progress. */
3970 ast_channel_lock(chan);
3971 if (ast_channel_is_bridged(chan)) {
3973 chan1_wait = 1;
3974 }
3975 ast_channel_unlock(chan);
3976
3977 ast_channel_lock(chan2);
3978 if (ast_channel_is_bridged(chan2)) {
3980 chan2_wait = 1;
3981 }
3982 ast_channel_unlock(chan2);
3983
3984 res = ast_async_goto(chan, context, exten, pi);
3985 if (!res) {
3986 if (!ast_strlen_zero(context2)) {
3987 res = ast_async_goto(chan2, context2, exten2, pi2);
3988 } else {
3989 res = ast_async_goto(chan2, context, exten, pi);
3990 }
3991 if (!res) {
3992 astman_send_ack(s, m, "Dual Redirect successful");
3993 } else {
3994 astman_send_error(s, m, "Secondary redirect failed");
3995 }
3996 } else {
3997 astman_send_error(s, m, "Redirect failed");
3998 }
3999
4000 /* Release the bridge wait. */
4001 if (chan1_wait) {
4003 }
4004 if (chan2_wait) {
4006 }
4007
4008 chan2 = ast_channel_unref(chan2);
4009 chan = ast_channel_unref(chan);
4010 return 0;
4011}
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11056
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10567
@ AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT
Definition: channel.h:1055
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.
Definition: pbx.c:6969
#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, voicemailpwcheck::context, 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 6458 of file manager.c.

6459{
6460 const char *module = astman_get_header(m, "Module");
6462
6463 switch (res) {
6465 astman_send_error(s, m, "No such module");
6466 break;
6468 astman_send_error(s, m, "Module does not support reload");
6469 break;
6471 astman_send_error(s, m, "An unknown error occurred");
6472 break;
6474 astman_send_error(s, m, "A reload is in progress");
6475 break;
6477 astman_send_error(s, m, "Module not initialized");
6478 break;
6481 /* Treat a queued request as success */
6482 astman_send_ack(s, m, "Module Reloaded");
6483 break;
6484 }
6485 return 0;
6486}
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:1721

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 3825 of file manager.c.

3826{
3827 struct ast_channel *c;
3828 const char *name = astman_get_header(m, "Channel");
3829 const char *textmsg = astman_get_header(m, "Message");
3830 const char *content_type = astman_get_header(m, "Content-Type");
3831 int res;
3832
3833 if (ast_strlen_zero(name)) {
3834 astman_send_error(s, m, "No channel specified");
3835 return 0;
3836 }
3837
3838 if (ast_strlen_zero(textmsg)) {
3839 astman_send_error(s, m, "No Message specified");
3840 return 0;
3841 }
3842
3844 if (!c) {
3845 astman_send_error(s, m, "No such channel");
3846 return 0;
3847 }
3848
3849 /*
3850 * If the "extra" data is not available, then send using "string" only.
3851 * Doing such maintains backward compatibilities.
3852 */
3853 res = ast_strlen_zero(content_type) ? queue_sendtext(c, textmsg) :
3854 queue_sendtext_data(c, textmsg, content_type);
3855
3857
3858 if (res >= 0) {
3859 astman_send_ack(s, m, "Success");
3860 } else {
3861 astman_send_error(s, m, "Failure");
3862 }
3863
3864 return 0;
3865}
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:3806
static int queue_sendtext(struct ast_channel *chan, const char *body)
Queue a read action to send a text message.
Definition: manager.c:3790

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 3469 of file manager.c.

3470{
3471 struct ast_channel *c = NULL;
3472 const char *name = astman_get_header(m, "Channel");
3473 const char *varname = astman_get_header(m, "Variable");
3474 const char *varval = astman_get_header(m, "Value");
3475 int res = 0;
3476
3477 if (ast_strlen_zero(varname)) {
3478 astman_send_error(s, m, "No variable specified");
3479 return 0;
3480 }
3481
3482 if (!ast_strlen_zero(name)) {
3483 if (!(c = ast_channel_get_by_name(name))) {
3484 astman_send_error(s, m, "No such channel");
3485 return 0;
3486 }
3487 }
3488
3489 res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
3490
3491 if (c) {
3493 }
3494 if (res == 0) {
3495 astman_send_ack(s, m, "Variable Set");
3496 } else {
3497 astman_send_error(s, m, "Variable not set");
3498 }
3499 return 0;
3500}

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 3669 of file manager.c.

3670{
3671 const char *name = astman_get_header(m, "Channel");
3672 const char *chan_variables = astman_get_header(m, "Variables");
3673 const char *all_chan_variables = astman_get_header(m, "AllVariables");
3674 int all_variables = 0;
3675 const char *id = astman_get_header(m, "ActionID");
3676 char *variables = ast_strdupa(S_OR(chan_variables, ""));
3677 struct ast_channel *chan;
3678 int channels = 0;
3679 int all = ast_strlen_zero(name); /* set if we want all channels */
3680 char id_text[256];
3681 struct ast_channel_iterator *it_chans = NULL;
3683 AST_APP_ARG(name)[100];
3684 );
3685
3686 if (!ast_strlen_zero(all_chan_variables)) {
3687 all_variables = ast_true(all_chan_variables);
3688 }
3689
3691 astman_send_error(s, m, "Status Access Forbidden: Variables");
3692 return 0;
3693 }
3694
3695 if (all) {
3696 if (!(it_chans = ast_channel_iterator_all_new())) {
3697 astman_send_error(s, m, "Memory Allocation Failure");
3698 return 1;
3699 }
3700 chan = ast_channel_iterator_next(it_chans);
3701 } else {
3703 if (!chan) {
3704 astman_send_error(s, m, "No such channel");
3705 return 0;
3706 }
3707 }
3708
3709 astman_send_listack(s, m, "Channel status will follow", "start");
3710
3711 if (!ast_strlen_zero(id)) {
3712 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3713 } else {
3714 id_text[0] = '\0';
3715 }
3716
3717 if (!ast_strlen_zero(chan_variables)) {
3718 AST_STANDARD_APP_ARGS(vars, variables);
3719 }
3720
3721 /* if we look by name, we break after the first iteration */
3722 for (; chan; all ? chan = ast_channel_iterator_next(it_chans) : 0) {
3723 ast_channel_lock(chan);
3724
3725 generate_status(s, chan, vars.name, vars.argc, all_variables, id_text, &channels);
3726
3727 ast_channel_unlock(chan);
3728 chan = ast_channel_unref(chan);
3729 }
3730
3731 if (it_chans) {
3733 }
3734
3735 astman_send_list_complete_start(s, m, "StatusComplete", channels);
3736 astman_append(s, "Items: %d\r\n", channels);
3738
3739 return 0;
3740}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1379
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1441
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1427
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:3554
#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 5445 of file manager.c.

5446{
5447 struct ast_channel *c;
5448 const char *name = astman_get_header(m, "Channel");
5449 double timeout = atof(astman_get_header(m, "Timeout"));
5450 struct timeval when = { timeout, 0 };
5451
5452 if (ast_strlen_zero(name)) {
5453 astman_send_error(s, m, "No channel specified");
5454 return 0;
5455 }
5456
5457 if (!timeout || timeout < 0) {
5458 astman_send_error(s, m, "No timeout specified");
5459 return 0;
5460 }
5461
5462 if (!(c = ast_channel_get_by_name(name))) {
5463 astman_send_error(s, m, "No such channel");
5464 return 0;
5465 }
5466
5467 when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
5468
5473
5474 astman_send_ack(s, m, "Timeout Set");
5475
5476 return 0;
5477}
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 2979 of file manager.c.

2980{
2981 struct ast_config *cfg;
2982 const char *sfn = astman_get_header(m, "SrcFilename");
2983 const char *dfn = astman_get_header(m, "DstFilename");
2984 int res;
2985 const char *rld = astman_get_header(m, "Reload");
2986 int preserve_effective_context = CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT;
2987 const char *preserve_effective_context_string = astman_get_header(m, "PreserveEffectiveContext");
2988 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2989 enum error_type result;
2990
2991 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
2992 astman_send_error(s, m, "Filename not specified");
2993 return 0;
2994 }
2995 if (restrictedFile(sfn) || restrictedFile(dfn)) {
2996 astman_send_error(s, m, "File requires escalated priveledges");
2997 return 0;
2998 }
2999 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
3000 astman_send_error(s, m, "Config file not found");
3001 return 0;
3002 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3003 astman_send_error(s, m, "Config file has invalid format");
3004 return 0;
3005 }
3006 result = handle_updates(s, m, cfg, dfn);
3007 if (!result) {
3008 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
3009 if (!ast_strlen_zero(preserve_effective_context_string) && !ast_true(preserve_effective_context_string)) {
3010 preserve_effective_context = CONFIG_SAVE_FLAG_NONE;
3011 }
3012 res = ast_config_text_file_save2(dfn, cfg, "Manager", preserve_effective_context);
3013 ast_config_destroy(cfg);
3014 if (res) {
3015 astman_send_error(s, m, "Save of config failed");
3016 return 0;
3017 }
3018 astman_send_ack(s, m, NULL);
3019 if (!ast_strlen_zero(rld)) {
3020 if (ast_true(rld)) {
3021 ast_module_reload(NULL); /* Reload everything */
3022 } else if (!ast_false(rld)) {
3023 ast_module_reload(rld); /* Reload the specific module */
3024 }
3025 }
3026 } else {
3027 ast_config_destroy(cfg);
3028 switch(result) {
3029 case UNKNOWN_ACTION:
3030 astman_send_error(s, m, "Unknown action command");
3031 break;
3032 case UNKNOWN_CATEGORY:
3033 astman_send_error(s, m, "Given category does not exist");
3034 break;
3036 astman_send_error(s, m, "Category not specified");
3037 break;
3039 astman_send_error(s, m, "Problem with category, value, or line (if required)");
3040 break;
3041 case FAILURE_ALLOCATION:
3042 astman_send_error(s, m, "Memory allocation failure, this should not happen");
3043 break;
3044 case FAILURE_NEWCAT:
3045 astman_send_error(s, m, "Create category did not complete successfully");
3046 break;
3047 case FAILURE_DELCAT:
3048 astman_send_error(s, m, "Delete category did not complete successfully");
3049 break;
3050 case FAILURE_EMPTYCAT:
3051 astman_send_error(s, m, "Empty category did not complete successfully");
3052 break;
3053 case FAILURE_UPDATE:
3054 astman_send_error(s, m, "Update did not complete successfully");
3055 break;
3056 case FAILURE_DELETE:
3057 astman_send_error(s, m, "Delete did not complete successfully");
3058 break;
3059 case FAILURE_APPEND:
3060 astman_send_error(s, m, "Append did not complete successfully");
3061 break;
3062 case FAILURE_TEMPLATE:
3063 astman_send_error(s, m, "Template category not found");
3064 break;
3065 }
3066 }
3067 return 0;
3068}
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:2696
error_type
Definition: manager.c:111
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
Definition: main/config.c:384
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:2732
@ CONFIG_SAVE_FLAG_NONE
@ CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: utils.c:2216

References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save2(), ast_false(), 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, restrictedFile(), 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 6353 of file manager.c.

6354{
6355 const char *event = astman_get_header(m, "UserEvent");
6356 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
6357 int x;
6358
6359 ast_str_reset(body);
6360
6361 for (x = 0; x < m->hdrcount; x++) {
6362 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:")) &&
6363 strncasecmp("Action:", m->headers[x], strlen("Action:"))) {
6364 ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
6365 }
6366 }
6367
6368 astman_send_ack(s, m, "Event Sent");
6369 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
6370 return 0;
6371}
static struct ast_threadstorage userevent_buf
Definition: manager.c:1873
#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:693

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 3088 of file manager.c.

3089{
3090 const char *timeouts = astman_get_header(m, "Timeout");
3091 int timeout = -1;
3092 int x;
3093 int needexit = 0;
3094 const char *id = astman_get_header(m, "ActionID");
3095 char idText[256];
3096
3097 if (!ast_strlen_zero(id)) {
3098 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
3099 } else {
3100 idText[0] = '\0';
3101 }
3102
3103 if (!ast_strlen_zero(timeouts)) {
3104 sscanf(timeouts, "%30i", &timeout);
3105 if (timeout < -1) {
3106 timeout = -1;
3107 }
3108 /* XXX maybe put an upper bound, or prevent the use of 0 ? */
3109 }
3110
3113 pthread_kill(s->session->waiting_thread, SIGURG);
3114 }
3116
3117 ao2_lock(s->session);
3118
3119 if (s->session->managerid) { /* AMI-over-HTTP session */
3120 /*
3121 * Make sure the timeout is within the expire time of the session,
3122 * as the client will likely abort the request if it does not see
3123 * data coming after some amount of time.
3124 */
3125 time_t now = time(NULL);
3126 int max = s->session->sessiontimeout - now - 10;
3127
3128 if (max < 0) { /* We are already late. Strange but possible. */
3129 max = 0;
3130 }
3131 if (timeout < 0 || timeout > max) {
3132 timeout = max;
3133 }
3134 if (!s->session->send_events) { /* make sure we record events */
3135 s->session->send_events = -1;
3136 }
3137 }
3138 ao2_unlock(s->session);
3139
3141 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
3143 ast_debug(1, "Starting waiting for an event!\n");
3144
3145 for (x = 0; x < timeout || timeout < 0; x++) {
3146 ao2_lock(s->session);
3147 if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
3148 needexit = 1;
3149 }
3150 if (s->session->needdestroy) {
3151 needexit = 1;
3152 }
3153 ao2_unlock(s->session);
3154 /* We can have multiple HTTP session point to the same mansession entry.
3155 * The way we deal with it is not very nice: newcomers kick out the previous
3156 * HTTP session. XXX this needs to be improved.
3157 */
3159 if (s->session->waiting_thread != pthread_self()) {
3160 needexit = 1;
3161 }
3163 if (needexit) {
3164 break;
3165 }
3166 if (s->session->managerid == 0) { /* AMI session */
3168 break;
3169 }
3170 } else { /* HTTP session */
3171 sleep(1);
3172 }
3173 }
3174 ast_debug(1, "Finished waiting for an event!\n");
3175
3177 if (s->session->waiting_thread == pthread_self()) {
3178 struct eventqent *eqe = s->session->last_ev;
3179
3182
3183 ao2_lock(s->session);
3184 astman_send_response(s, m, "Success", "Waiting for Event completed.");
3185 while ((eqe = advance_event(eqe))) {
3186 if (((s->session->readperm & eqe->category) == eqe->category)
3187 && ((s->session->send_events & eqe->category) == eqe->category)
3189 astman_append(s, "%s", eqe->eventdata);
3190 }
3191 s->session->last_ev = eqe;
3192 }
3193 astman_append(s,
3194 "Event: WaitEventComplete\r\n"
3195 "%s"
3196 "\r\n", idText);
3197 ao2_unlock(s->session);
3198 } else {
3200 ast_debug(1, "Abandoning event request!\n");
3201 }
3202
3203 return 0;
3204}
#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:1563
static int should_send_event(struct ao2_container *includefilters, struct ao2_container *excludefilters, struct eventqent *eqe)
Definition: manager.c:5560
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition: iostream.c:85
#define AST_RWLIST_NEXT
Definition: linkedlists.h:441
int category
Definition: manager.c:154
ast_mutex_t notify_lock
Definition: manager.c:311
pthread_t waiting_thread
Definition: manager.c:287
struct ast_iostream * stream
Definition: manager.c:284
struct eventqent * last_ev
Definition: manager.c:303
time_t sessiontimeout
Definition: manager.c:291
int ast_wait_for_input(int fd, int ms)
Definition: utils.c:1698

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::excludefilters, mansession_session::includefilters, mansession_session::last_ev, mansession_session::managerid, max, mansession_session::needdestroy, mansession_session::notify_lock, NULL, mansession_session::readperm, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, should_send_event(), 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 1563 of file manager.c.

1564{
1565 struct eventqent *next;
1566
1568 if ((next = AST_RWLIST_NEXT(e, eq_next))) {
1571 }
1573 return next;
1574}
int usecount
Definition: manager.c:153

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 4386 of file manager.c.

4387{
4388 const char *unitamount;
4389 const char *unittype;
4390 struct ast_str *str = ast_str_alloca(32);
4391
4392 memset(entry, 0, sizeof(*entry));
4393
4394 ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
4395 unitamount = astman_get_header(m, ast_str_buffer(str));
4396
4397 ast_str_set(&str, 0, "UnitType(%u)", entry_num);
4398 unittype = astman_get_header(m, ast_str_buffer(str));
4399
4400 if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
4401 entry->valid_amount = 1;
4402 }
4403
4404 if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
4405 entry->valid_type = 1;
4406 }
4407
4408 return 0;
4409}
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_aoc_de_message().

◆ app_match()

static int app_match ( const char *  app,
const char *  data,
const char *  search 
)
static

Definition at line 4924 of file manager.c.

4925{
4926 /*
4927 * We use strcasestr so we don't have to trim any blanks
4928 * from the front or back of the string.
4929 */
4930 return !!(strcasestr(app, search));
4931}
char * strcasestr(const char *, const char *)

References app, and strcasestr().

◆ appdata_match()

static int appdata_match ( const char *  app,
const char *  data,
const char *  search 
)
static

Definition at line 4943 of file manager.c.

4944{
4945 if (ast_strlen_zero(data)) {
4946 return 0;
4947 }
4948 return !!(strstr(data, search));
4949}

References ast_strlen_zero().

◆ append_channel_vars()

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

Definition at line 7429 of file manager.c.

7430{
7431 struct varshead *vars;
7432 struct ast_var_t *var;
7433
7434 vars = ast_channel_get_manager_vars(chan);
7435 if (!vars) {
7436 return;
7437 }
7438
7439 AST_LIST_TRAVERSE(vars, var, entries) {
7440 ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, var->value);
7441 }
7442 ao2_ref(vars, -1);
7443}
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:8005
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
struct ast_var_t::@211 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  event_name_hash,
int  category 
)
static

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

Definition at line 7404 of file manager.c.