Mon Nov 24 15:34:45 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"

Go to the source code of this file.

Data Structures

struct  manager_action
struct  message

Defines

#define AMI_VERSION   "1.0"
#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_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.
int check_manager_enabled (void)
 Check if AMI is enabled.
int check_webmanager_enabled (void)
 Check if AMI/HTTP is enabled.
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 AMI_VERSION   "1.0"

Definition at line 48 of file manager.h.

Referenced by action_coresettings().

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

Definition at line 92 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 49 of file manager.h.

Referenced by init_manager().

#define EVENT_FLAG_AGENT   (1 << 5)

Definition at line 56 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 52 of file manager.h.

Referenced by ast_change_name(), ast_channel_alloc(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_set_callerid(), ast_setstate(), change_hold_state(), conf_run(), fast_originate(), init_manager(), join_queue(), leave_queue(), load_module(), manager_log(), manager_state_cb(), 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 55 of file manager.h.

Referenced by init_manager().

#define EVENT_FLAG_CONFIG   (1 << 7)

Definition at line 58 of file manager.h.

Referenced by init_manager().

#define EVENT_FLAG_LOG   (1 << 2)

Definition at line 53 of file manager.h.

#define EVENT_FLAG_SYSTEM   (1 << 0)

Definition at line 51 of file manager.h.

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

#define EVENT_FLAG_USER   (1 << 6)

Definition at line 57 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 54 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 2789 of file manager.c.

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

02790 {
02791    int result = 0;
02792    struct mansession *s;
02793 
02794    AST_LIST_LOCK(&sessions);
02795    AST_LIST_TRAVERSE(&sessions, s, list) {
02796       ast_mutex_lock(&s->__lock);
02797       if ((s->managerid == ident) && (s->readperm & perm)) {
02798          result = 1;
02799          ast_mutex_unlock(&s->__lock);
02800          break;
02801       }
02802       ast_mutex_unlock(&s->__lock);
02803    }
02804    AST_LIST_UNLOCK(&sessions);
02805    return result;
02806 }

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

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

02809 {
02810    int result = 0;
02811    struct mansession *s;
02812 
02813    AST_LIST_LOCK(&sessions);
02814    AST_LIST_TRAVERSE(&sessions, s, list) {
02815       ast_mutex_lock(&s->__lock);
02816       if ((s->managerid == ident) && (s->writeperm & perm)) {
02817          result = 1;
02818          ast_mutex_unlock(&s->__lock);
02819          break;
02820       }
02821       ast_mutex_unlock(&s->__lock);
02822    }
02823    AST_LIST_UNLOCK(&sessions);
02824    return result;
02825 }

void const char int init_manager ( void   ) 

Called by Asterisk initialization

Definition at line 3027 of file manager.c.

References action_atxfer(), action_command(), action_coresettings(), action_corestatus(), action_events(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_listcommands(), action_logoff(), action_mailboxcount(), action_mailboxstatus(), 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, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, EVENT_FLAG_CONFIG, EVENT_FLAG_SYSTEM, EVENT_FLAG_USER, ast_channel::flags, free, ast_manager_user::keep, LOG_DEBUG, LOG_WARNING, manager_enabled, manager_state_cb(), ast_manager_user::permit, portno, ast_manager_user::read, ast_manager_user::secret, timestampevents, users, var, webmanager_enabled, and ast_manager_user::write.

Referenced by main(), and reload_manager().

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

int reload_manager ( void   ) 

Definition at line 3318 of file manager.c.

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

03319 {
03320    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
03321    return init_manager();
03322 }


Variable Documentation

int const char const char* contents

Definition at line 136 of file manager.h.

int const char* event

Definition at line 136 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 149 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(), 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 Nov 24 15:34:45 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7