Tue Nov 4 13:20:40 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 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(), expire_register(), 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(), update_registry(), and zt_handle_event().

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

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

02781 {
02782    int result = 0;
02783    struct mansession *s;
02784 
02785    AST_LIST_LOCK(&sessions);
02786    AST_LIST_TRAVERSE(&sessions, s, list) {
02787       ast_mutex_lock(&s->__lock);
02788       if ((s->managerid == ident) && (s->readperm & perm)) {
02789          result = 1;
02790          ast_mutex_unlock(&s->__lock);
02791          break;
02792       }
02793       ast_mutex_unlock(&s->__lock);
02794    }
02795    AST_LIST_UNLOCK(&sessions);
02796    return result;
02797 }

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

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

02800 {
02801    int result = 0;
02802    struct mansession *s;
02803 
02804    AST_LIST_LOCK(&sessions);
02805    AST_LIST_TRAVERSE(&sessions, s, list) {
02806       ast_mutex_lock(&s->__lock);
02807       if ((s->managerid == ident) && (s->writeperm & perm)) {
02808          result = 1;
02809          ast_mutex_unlock(&s->__lock);
02810          break;
02811       }
02812       ast_mutex_unlock(&s->__lock);
02813    }
02814    AST_LIST_UNLOCK(&sessions);
02815    return result;
02816 }

void const char int init_manager ( void   ) 

Called by Asterisk initialization

Definition at line 3018 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().

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

int reload_manager ( void   ) 

Definition at line 3309 of file manager.c.

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

03310 {
03311    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
03312    return init_manager();
03313 }


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 Tue Nov 4 13:20:40 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7