Mon Jul 14 17:25:20 2008

Asterisk developer's documentation


manager.h File Reference

The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party software. More...

#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/lock.h"

Include dependency graph for manager.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  manager_action
struct  message

Defines

#define ast_manager_register(a, b, c, d)   ast_manager_register2(a, b, c, d, NULL)
#define AST_MAX_MANHEADERS   128
#define DEFAULT_MANAGER_PORT   5038
#define EVENT_FLAG_AGENT   (1 << 5)
#define EVENT_FLAG_CALL   (1 << 1)
#define EVENT_FLAG_COMMAND   (1 << 4)
#define EVENT_FLAG_CONFIG   (1 << 7)
#define EVENT_FLAG_EXTENSIONSTATUS   (1 << 8)
#define EVENT_FLAG_LOG   (1 << 2)
#define EVENT_FLAG_SYSTEM   (1 << 0)
#define EVENT_FLAG_USER   (1 << 6)
#define EVENT_FLAG_VERBOSE   (1 << 3)

Functions

void __attribute__ ((format(printf, 2, 3))) astman_append(struct mansession *s
int __attribute__ ((format(printf, 3, 4))) manager_event(int category
int ast_manager_register2 (const char *action, int authority, int(*func)(struct mansession *s, const struct message *m), 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
int ast_manager_unregister (char *action)
int const char const char
const char * 
astman_get_header (const struct message *m, char *var)
ast_variableastman_get_variables (const struct message *m)
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
void astman_send_error (struct mansession *s, const struct message *m, char *error)
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
int astman_verify_session_readpermissions (uint32_t ident, int perm)
 Verify a session's read permissions against a permission mask.
int astman_verify_session_writepermissions (uint32_t ident, int perm)
 Verify a session's write permissions against a permission mask.
void const char int init_manager (void)
int reload_manager (void)

Variables

int const char const char * contents
int const char * event
void const char * fmt


Detailed Description

The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party software.

Manager protocol packages are text fields of the form a: b. There is always exactly one space after the colon.

The first header type is the "Event" header. Other headers vary from event to event. Headers end with standard
termination. The last line of the manager response or event is an empty line. (
)

Please try to re-use existing headers to simplify manager message parsing in clients. Don't re-use an existing header with a new meaning, please. You can find a reference of standard headers in doc/manager.txt

Definition in file manager.h.


Define Documentation

#define ast_manager_register ( a,
b,
c,
 )     ast_manager_register2(a, b, c, d, NULL)

Definition at line 86 of file manager.h.

Referenced by astdb_init(), init_manager(), and load_module().

#define AST_MAX_MANHEADERS   128

Definition at line 61 of file manager.h.

Referenced by do_message().

#define DEFAULT_MANAGER_PORT   5038

Definition at line 48 of file manager.h.

Referenced by init_manager().

#define EVENT_FLAG_AGENT   (1 << 5)

Definition at line 55 of file manager.h.

Referenced by __login_exec(), action_agent_callback_login(), add_to_queue(), agent_logoff_maintenance(), load_module(), record_abandoned(), remove_from_queue(), ring_entry(), set_member_paused(), try_calling(), and update_status().

#define EVENT_FLAG_CALL   (1 << 1)

Definition at line 51 of file manager.h.

Referenced by ast_autoanswer_login(), ast_hold_call(), ast_monitor_stop(), autoanswer_exec(), bridge_exec(), change_hold_state(), conf_run(), do_autoanswer_thread(), fast_originate(), init_manager(), join_queue(), leave_queue(), load_module(), manager_log(), notify_new_message(), park_call_full(), park_exec(), pbx_extension_helper(), post_manager_event(), realtime_exec(), senddialevent(), socket_process(), and vm_execmain().

#define EVENT_FLAG_COMMAND   (1 << 4)

Definition at line 54 of file manager.h.

Referenced by init_manager(), and load_module().

#define EVENT_FLAG_CONFIG   (1 << 7)

Definition at line 57 of file manager.h.

Referenced by init_manager().

#define EVENT_FLAG_EXTENSIONSTATUS   (1 << 8)

Definition at line 58 of file manager.h.

Referenced by manager_state_cb().

#define EVENT_FLAG_LOG   (1 << 2)

Definition at line 52 of file manager.h.

#define EVENT_FLAG_SYSTEM   (1 << 0)

Definition at line 50 of file manager.h.

Referenced by __expire_registry(), __iax2_poke_noanswer(), ast_log(), astdb_init(), expire_register(), handle_init_event(), handle_response_peerpoke(), handle_response_register(), iax2_ack_registry(), load_module(), parse_register_contact(), quit_handler(), register_verify(), reload_logger(), reload_manager(), sip_poke_noanswer(), sip_reg_timeout(), socket_process(), ss_thread(), update_registry(), and zt_handle_event().

#define EVENT_FLAG_USER   (1 << 6)

Definition at line 56 of file manager.h.

Referenced by action_userevent(), aji_log_hook(), init_manager(), and userevent_exec().

#define EVENT_FLAG_VERBOSE   (1 << 3)

Definition at line 53 of file manager.h.


Function Documentation

void __attribute__ ( (format(printf, 2, 3))   ) 

int __attribute__ ( (format(printf, 3, 4))   ) 

Parameters:
category Event category, matches manager authorization
event Event name
contents Contents of event

int astman_verify_session_readpermissions ( uint32_t  ident,
int  perm 
)

Verify a session's read permissions against a permission mask.

Parameters:
ident session identity
perm permission mask to verify
Returns:
1 if the session has the permission mask capabilities, otherwise 0

Definition at line 2739 of file manager.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), s, and sessions.

02740 {
02741    int result = 0;
02742    struct mansession *s;
02743 
02744    AST_LIST_LOCK(&sessions);
02745    AST_LIST_TRAVERSE(&sessions, s, list) {
02746       ast_mutex_lock(&s->__lock);
02747       if ((s->managerid == ident) && (s->readperm & perm)) {
02748          result = 1;
02749          ast_mutex_unlock(&s->__lock);
02750          break;
02751       }
02752       ast_mutex_unlock(&s->__lock);
02753    }
02754    AST_LIST_UNLOCK(&sessions);
02755    return result;
02756 }

int astman_verify_session_writepermissions ( uint32_t  ident,
int  perm 
)

Verify a session's write permissions against a permission mask.

Parameters:
ident session identity
perm permission mask to verify
Returns:
1 if the session has the permission mask capabilities, otherwise 0

Definition at line 2758 of file manager.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), s, and sessions.

02759 {
02760    int result = 0;
02761    struct mansession *s;
02762 
02763    AST_LIST_LOCK(&sessions);
02764    AST_LIST_TRAVERSE(&sessions, s, list) {
02765       ast_mutex_lock(&s->__lock);
02766       if ((s->managerid == ident) && (s->writeperm & perm)) {
02767          result = 1;
02768          ast_mutex_unlock(&s->__lock);
02769          break;
02770       }
02771       ast_mutex_unlock(&s->__lock);
02772    }
02773    AST_LIST_UNLOCK(&sessions);
02774    return result;
02775 }

void const char int init_manager ( void   ) 

Called by Asterisk initialization

Definition at line 2977 of file manager.c.

References action_command(), action_events(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_listcommands(), action_logoff(), action_mailboxcount(), action_mailboxstatus(), action_message(), action_originate(), action_ping(), action_redirect(), action_setvar(), action_status(), action_timeout(), action_updateconfig(), action_userevent(), action_waitevent(), append_event(), asock, ast_calloc, ast_category_browse(), ast_cli_register_multiple(), ast_config_load(), ast_extension_state_add(), ast_get_manager_by_name_locked(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, ast_log(), ast_manager_register, ast_manager_register2(), ast_strdup, ast_true(), ast_variable_browse(), ast_variable_retrieve(), block_sockets, cli_manager, DEFAULT_MANAGER_PORT, ast_manager_user::deny, ast_manager_user::displayconnects, displayconnects, enabled, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, EVENT_FLAG_CONFIG, EVENT_FLAG_USER, ast_channel::flags, free, ast_manager_user::keep, LOG_DEBUG, LOG_WARNING, manager_state_cb(), ast_manager_user::permit, portno, ast_manager_user::read, ast_manager_user::secret, timestampevents, users, var, and ast_manager_user::write.

Referenced by main(), and reload_manager().

02978 {
02979    struct ast_config *cfg = NULL, *ucfg = NULL;
02980    const char *val;
02981    char *cat = NULL;
02982    int oldportno = portno;
02983    static struct sockaddr_in ba;
02984    int x = 1;
02985    int flags;
02986    int webenabled = 0;
02987    int newhttptimeout = 60;
02988    struct ast_manager_user *user = NULL;
02989 
02990    if (!registered) {
02991       /* Register default actions */
02992       ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping);
02993       ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events);
02994       ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff);
02995       ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup);
02996       ast_manager_register2("Message", EVENT_FLAG_CALL, action_message, "Send Message", mandescr_message);
02997       ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" );
02998       ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar );
02999       ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar );
03000       ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig);
03001       ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig);
03002       ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect );
03003       ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate);
03004       ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command );
03005       ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate );
03006       ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout );
03007       ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus );
03008       ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount );
03009       ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands);
03010       ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent);
03011       ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent);
03012 
03013       ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry));
03014       ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
03015       registered = 1;
03016       /* Append placeholder event so master_eventq never runs dry */
03017       append_event("Event: Placeholder\r\n\r\n", 0);
03018    }
03019    portno = DEFAULT_MANAGER_PORT;
03020    displayconnects = 1;
03021    cfg = ast_config_load("manager.conf");
03022    if (!cfg) {
03023       ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf.  Call management disabled.\n");
03024       return 0;
03025    }
03026    val = ast_variable_retrieve(cfg, "general", "enabled");
03027    if (val)
03028       enabled = ast_true(val);
03029 
03030    val = ast_variable_retrieve(cfg, "general", "block-sockets");
03031    if (val)
03032       block_sockets = ast_true(val);
03033 
03034    val = ast_variable_retrieve(cfg, "general", "webenabled");
03035    if (val)
03036       webenabled = ast_true(val);
03037 
03038    if ((val = ast_variable_retrieve(cfg, "general", "port"))) {
03039       if (sscanf(val, "%d", &portno) != 1) {
03040          ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
03041          portno = DEFAULT_MANAGER_PORT;
03042       }
03043    }
03044 
03045    if ((val = ast_variable_retrieve(cfg, "general", "displayconnects")))
03046       displayconnects = ast_true(val);
03047 
03048    if ((val = ast_variable_retrieve(cfg, "general", "timestampevents")))
03049       timestampevents = ast_true(val);
03050 
03051    if ((val = ast_variable_retrieve(cfg, "general", "httptimeout")))
03052       newhttptimeout = atoi(val);
03053 
03054    memset(&ba, 0, sizeof(ba));
03055    ba.sin_family = AF_INET;
03056    ba.sin_port = htons(portno);
03057 
03058    if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) {
03059       if (!inet_aton(val, &ba.sin_addr)) { 
03060          ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val);
03061          memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
03062       }
03063    }
03064    
03065 
03066    if ((asock > -1) && ((portno != oldportno) || !enabled)) {
03067 #if 0
03068       /* Can't be done yet */
03069       close(asock);
03070       asock = -1;
03071 #else
03072       ast_log(LOG_WARNING, "Unable to change management port / enabled\n");
03073 #endif
03074    }
03075 
03076    AST_LIST_LOCK(&users);
03077 
03078    if ((ucfg = ast_config_load("users.conf"))) {
03079       while ((cat = ast_category_browse(ucfg, cat))) {
03080          int hasmanager = 0;
03081          struct ast_variable *var = NULL;
03082 
03083          if (!strcasecmp(cat, "general")) {
03084             continue;
03085          }
03086 
03087          if (!(hasmanager = ast_true(ast_variable_retrieve(ucfg, cat, "hasmanager")))) {
03088             continue;
03089          }
03090 
03091          /* Look for an existing entry, if none found - create one and add it to the list */
03092          if (!(user = ast_get_manager_by_name_locked(cat))) {
03093             if (!(user = ast_calloc(1, sizeof(*user)))) {
03094                break;
03095             }
03096             /* Copy name over */
03097             ast_copy_string(user->username, cat, sizeof(user->username));
03098             /* Insert into list */
03099             AST_LIST_INSERT_TAIL(&users, user, list);
03100          }
03101 
03102          /* Make sure we keep this user and don't destroy it during cleanup */
03103          user->keep = 1;
03104 
03105          for (var = ast_variable_browse(ucfg, cat); var; var = var->next) {
03106             if (!strcasecmp(var->name, "secret")) {
03107                if (user->secret) {
03108                   free(user->secret);
03109                }
03110                user->secret = ast_strdup(var->value);
03111             } else if (!strcasecmp(var->name, "deny") ) {
03112                if (user->deny) {
03113                   free(user->deny);
03114                }
03115                user->deny = ast_strdup(var->value);
03116             } else if (!strcasecmp(var->name, "permit") ) {
03117                if (user->permit) {
03118                   free(user->permit);
03119                }
03120                user->permit = ast_strdup(var->value);
03121             } else if (!strcasecmp(var->name, "read") ) {
03122                if (user->read) {
03123                   free(user->read);
03124                }
03125                user->read = ast_strdup(var->value);
03126             } else if (!strcasecmp(var->name, "write") ) {
03127                if (user->write) {
03128                   free(user->write);
03129                }
03130                user->write = ast_strdup(var->value);
03131             } else if (!strcasecmp(var->name, "displayconnects") ) {
03132                user->displayconnects = ast_true(var->value);
03133             } else if (!strcasecmp(var->name, "hasmanager")) {
03134                /* already handled */
03135             } else {
03136                ast_log(LOG_DEBUG, "%s is an unknown option (to the manager module).\n", var->name);
03137             }
03138          }
03139       }
03140       ast_config_destroy(ucfg);
03141    }
03142 
03143    while ((cat = ast_category_browse(cfg, cat))) {
03144       struct ast_variable *var = NULL;
03145 
03146       if (!strcasecmp(cat, "general"))
03147          continue;
03148 
03149       /* Look for an existing entry, if none found - create one and add it to the list */
03150       if (!(user = ast_get_manager_by_name_locked(cat))) {
03151          if (!(user = ast_calloc(1, sizeof(*user))))
03152             break;
03153          /* Copy name over */
03154          ast_copy_string(user->username, cat, sizeof(user->username));
03155          /* Insert into list */
03156          AST_LIST_INSERT_TAIL(&users, user, list);
03157       }
03158 
03159       /* Make sure we keep this user and don't destroy it during cleanup */
03160       user->keep = 1;
03161 
03162       var = ast_variable_browse(cfg, cat);
03163       while (var) {
03164          if (!strcasecmp(var->name, "secret")) {
03165             if (user->secret)
03166                free(user->secret);
03167             user->secret = ast_strdup(var->value);
03168          } else if (!strcasecmp(var->name, "deny") ) {
03169             if (user->deny)
03170                free(user->deny);
03171             user->deny = ast_strdup(var->value);
03172          } else if (!strcasecmp(var->name, "permit") ) {
03173             if (user->permit)
03174                free(user->permit);
03175             user->permit = ast_strdup(var->value);
03176          }  else if (!strcasecmp(var->name, "read") ) {
03177             if (user->read)
03178                free(user->read);
03179             user->read = ast_strdup(var->value);
03180          }  else if (!strcasecmp(var->name, "write") ) {
03181             if (user->write)
03182                free(user->write);
03183             user->write = ast_strdup(var->value);
03184          }  else if (!strcasecmp(var->name, "displayconnects") )
03185             user->displayconnects = ast_true(var->value);
03186          else
03187             ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name);
03188          var = var->next;
03189       }
03190    }
03191 
03192    /* Perform cleanup - essentially prune out old users that no longer exist */
03193    AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) {
03194       if (user->keep) {
03195          user->keep = 0;
03196          continue;
03197       }
03198       /* We do not need to keep this user so take them out of the list */
03199       AST_LIST_REMOVE_CURRENT(&users, list);
03200       /* Free their memory now */
03201       if (user->secret)
03202          free(user->secret);
03203       if (user->deny)
03204          free(user->deny);
03205       if (user->permit)
03206          free(user->permit);
03207       if (user->read)
03208          free(user->read);
03209       if (user->write)
03210          free(user->write);
03211       free(user);
03212    }
03213    AST_LIST_TRAVERSE_SAFE_END
03214 
03215    AST_LIST_UNLOCK(&users);
03216 
03217    ast_config_destroy(cfg);
03218    
03219    if (webenabled && enabled) {
03220       if (!webregged) {
03221          ast_http_uri_link(&rawmanuri);
03222          ast_http_uri_link(&manageruri);
03223          ast_http_uri_link(&managerxmluri);
03224          webregged = 1;
03225       }
03226    } else {
03227       if (webregged) {
03228          ast_http_uri_unlink(&rawmanuri);
03229          ast_http_uri_unlink(&manageruri);
03230          ast_http_uri_unlink(&managerxmluri);
03231          webregged = 0;
03232       }
03233    }
03234 
03235    if (newhttptimeout > 0)
03236       httptimeout = newhttptimeout;
03237 
03238    /* If not enabled, do nothing */
03239    if (!enabled)
03240       return 0;
03241 
03242    if (asock < 0) {
03243       asock = socket(AF_INET, SOCK_STREAM, 0);
03244       if (asock < 0) {
03245          ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
03246          return -1;
03247       }
03248       setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
03249       if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) {
03250          ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno));
03251          close(asock);
03252          asock = -1;
03253          return -1;
03254       }
03255       if (listen(asock, 2)) {
03256          ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno));
03257          close(asock);
03258          asock = -1;
03259          return -1;
03260       }
03261       flags = fcntl(asock, F_GETFL);
03262       fcntl(asock, F_SETFL, flags | O_NONBLOCK);
03263       if (option_verbose)
03264          ast_verbose("Asterisk Management interface listening on port %d\n", portno);
03265       ast_pthread_create_background(&t, NULL, accept_thread, NULL);
03266    }
03267    return 0;
03268 }

int reload_manager ( void   ) 

Definition at line 3270 of file manager.c.

References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().

03271 {
03272    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
03273    return init_manager();
03274 }


Variable Documentation

int const char const char* contents

Definition at line 130 of file manager.h.

int const char* event

Definition at line 130 of file manager.h.

Referenced by action_userevent(), adsi_process(), ast_rtp_read(), handle_event_nt(), handle_frm(), handle_request_info(), handle_request_notify(), handle_request_subscribe(), handle_soft_key_event_message(), handle_stimulus_message(), log_events(), onevent(), process_cisco_dtmf(), process_rfc2833(), ql_exec(), receive_ademco_contact_id(), sla_handle_hold_event(), sla_queue_event_full(), sla_thread(), and write_event().

void const char* fmt

Definition at line 143 of file manager.h.

Referenced by __oh323_new(), add_codec_to_sdp(), ast_cdr_getvar(), ast_cli_netstats(), ast_codec_pref_getsize(), ast_openvstream(), ast_request_with_uniqueid(), ast_rtp_write(), ast_streamfile(), check_header(), get_filestream(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), local_new(), mgcp_new(), setformat(), sip_new(), skinny_new(), transmit_connect(), try_suggested_sip_codec(), and write_header().


Generated on Mon Jul 14 17:25:20 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1