Sat Nov 1 06:29:10 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_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 85 of file manager.h.

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

#define AST_MAX_MANHEADERS   128

Definition at line 60 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_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 54 of file manager.h.

Referenced by init_manager().

#define EVENT_FLAG_CONFIG   (1 << 7)

Definition at line 57 of file manager.h.

Referenced by init_manager().

#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(), dahdi_handle_event(), expire_register(), handle_alarms(), 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(), and update_registry().

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

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

02657 {
02658    int result = 0;
02659    struct mansession *s;
02660 
02661    AST_LIST_LOCK(&sessions);
02662    AST_LIST_TRAVERSE(&sessions, s, list) {
02663       ast_mutex_lock(&s->__lock);
02664       if ((s->managerid == ident) && (s->readperm & perm)) {
02665          result = 1;
02666          ast_mutex_unlock(&s->__lock);
02667          break;
02668       }
02669       ast_mutex_unlock(&s->__lock);
02670    }
02671    AST_LIST_UNLOCK(&sessions);
02672    return result;
02673 }

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

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

02676 {
02677    int result = 0;
02678    struct mansession *s;
02679 
02680    AST_LIST_LOCK(&sessions);
02681    AST_LIST_TRAVERSE(&sessions, s, list) {
02682       ast_mutex_lock(&s->__lock);
02683       if ((s->managerid == ident) && (s->writeperm & perm)) {
02684          result = 1;
02685          ast_mutex_unlock(&s->__lock);
02686          break;
02687       }
02688       ast_mutex_unlock(&s->__lock);
02689    }
02690    AST_LIST_UNLOCK(&sessions);
02691    return result;
02692 }

void const char int init_manager ( void   ) 

Called by Asterisk initialization

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

02895 {
02896    struct ast_config *cfg = NULL, *ucfg = NULL;
02897    const char *val;
02898    char *cat = NULL;
02899    int oldportno = portno;
02900    static struct sockaddr_in ba;
02901    int x = 1;
02902    int flags;
02903    int webenabled = 0;
02904    int newhttptimeout = 60;
02905    struct ast_manager_user *user = NULL;
02906 
02907    if (!registered) {
02908       /* Register default actions */
02909       ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping);
02910       ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events);
02911       ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff);
02912       ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup);
02913       ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" );
02914       ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar );
02915       ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar );
02916       ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig);
02917       ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig);
02918       ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect );
02919       ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate);
02920       ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command );
02921       ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate );
02922       ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout );
02923       ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus );
02924       ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount );
02925       ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands);
02926       ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent);
02927       ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent);
02928 
02929       ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry));
02930       ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
02931       registered = 1;
02932       /* Append placeholder event so master_eventq never runs dry */
02933       append_event("Event: Placeholder\r\n\r\n", 0);
02934    }
02935    portno = DEFAULT_MANAGER_PORT;
02936    displayconnects = 1;
02937    cfg = ast_config_load("manager.conf");
02938    if (!cfg) {
02939       ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf.  Call management disabled.\n");
02940       return 0;
02941    }
02942    val = ast_variable_retrieve(cfg, "general", "enabled");
02943    if (val)
02944       enabled = ast_true(val);
02945 
02946    val = ast_variable_retrieve(cfg, "general", "block-sockets");
02947    if (val)
02948       block_sockets = ast_true(val);
02949 
02950    val = ast_variable_retrieve(cfg, "general", "webenabled");
02951    if (val)
02952       webenabled = ast_true(val);
02953 
02954    if ((val = ast_variable_retrieve(cfg, "general", "port"))) {
02955       if (sscanf(val, "%d", &portno) != 1) {
02956          ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
02957          portno = DEFAULT_MANAGER_PORT;
02958       }
02959    }
02960 
02961    if ((val = ast_variable_retrieve(cfg, "general", "displayconnects")))
02962       displayconnects = ast_true(val);
02963 
02964    if ((val = ast_variable_retrieve(cfg, "general", "timestampevents")))
02965       timestampevents = ast_true(val);
02966 
02967    if ((val = ast_variable_retrieve(cfg, "general", "httptimeout")))
02968       newhttptimeout = atoi(val);
02969 
02970    memset(&ba, 0, sizeof(ba));
02971    ba.sin_family = AF_INET;
02972    ba.sin_port = htons(portno);
02973 
02974    if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) {
02975       if (!inet_aton(val, &ba.sin_addr)) { 
02976          ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val);
02977          memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
02978       }
02979    }
02980    
02981 
02982    if ((asock > -1) && ((portno != oldportno) || !enabled)) {
02983 #if 0
02984       /* Can't be done yet */
02985       close(asock);
02986       asock = -1;
02987 #else
02988       ast_log(LOG_WARNING, "Unable to change management port / enabled\n");
02989 #endif
02990    }
02991 
02992    AST_LIST_LOCK(&users);
02993 
02994    if ((ucfg = ast_config_load("users.conf"))) {
02995       while ((cat = ast_category_browse(ucfg, cat))) {
02996          int hasmanager = 0;
02997          struct ast_variable *var = NULL;
02998 
02999          if (!strcasecmp(cat, "general")) {
03000             continue;
03001          }
03002 
03003          if (!(hasmanager = ast_true(ast_variable_retrieve(ucfg, cat, "hasmanager")))) {
03004             continue;
03005          }
03006 
03007          /* Look for an existing entry, if none found - create one and add it to the list */
03008          if (!(user = ast_get_manager_by_name_locked(cat))) {
03009             if (!(user = ast_calloc(1, sizeof(*user)))) {
03010                break;
03011             }
03012             /* Copy name over */
03013             ast_copy_string(user->username, cat, sizeof(user->username));
03014             /* Insert into list */
03015             AST_LIST_INSERT_TAIL(&users, user, list);
03016          }
03017 
03018          /* Make sure we keep this user and don't destroy it during cleanup */
03019          user->keep = 1;
03020 
03021          for (var = ast_variable_browse(ucfg, cat); var; var = var->next) {
03022             if (!strcasecmp(var->name, "secret")) {
03023                if (user->secret) {
03024                   free(user->secret);
03025                }
03026                user->secret = ast_strdup(var->value);
03027             } else if (!strcasecmp(var->name, "deny") ) {
03028                if (user->deny) {
03029                   free(user->deny);
03030                }
03031                user->deny = ast_strdup(var->value);
03032             } else if (!strcasecmp(var->name, "permit") ) {
03033                if (user->permit) {
03034                   free(user->permit);
03035                }
03036                user->permit = ast_strdup(var->value);
03037             } else if (!strcasecmp(var->name, "read") ) {
03038                if (user->read) {
03039                   free(user->read);
03040                }
03041                user->read = ast_strdup(var->value);
03042             } else if (!strcasecmp(var->name, "write") ) {
03043                if (user->write) {
03044                   free(user->write);
03045                }
03046                user->write = ast_strdup(var->value);
03047             } else if (!strcasecmp(var->name, "displayconnects") ) {
03048                user->displayconnects = ast_true(var->value);
03049             } else if (!strcasecmp(var->name, "hasmanager")) {
03050                /* already handled */
03051             } else {
03052                ast_log(LOG_DEBUG, "%s is an unknown option (to the manager module).\n", var->name);
03053             }
03054          }
03055       }
03056       ast_config_destroy(ucfg);
03057    }
03058 
03059    while ((cat = ast_category_browse(cfg, cat))) {
03060       struct ast_variable *var = NULL;
03061 
03062       if (!strcasecmp(cat, "general"))
03063          continue;
03064 
03065       /* Look for an existing entry, if none found - create one and add it to the list */
03066       if (!(user = ast_get_manager_by_name_locked(cat))) {
03067          if (!(user = ast_calloc(1, sizeof(*user))))
03068             break;
03069          /* Copy name over */
03070          ast_copy_string(user->username, cat, sizeof(user->username));
03071          /* Insert into list */
03072          AST_LIST_INSERT_TAIL(&users, user, list);
03073       }
03074 
03075       /* Make sure we keep this user and don't destroy it during cleanup */
03076       user->keep = 1;
03077 
03078       var = ast_variable_browse(cfg, cat);
03079       while (var) {
03080          if (!strcasecmp(var->name, "secret")) {
03081             if (user->secret)
03082                free(user->secret);
03083             user->secret = ast_strdup(var->value);
03084          } else if (!strcasecmp(var->name, "deny") ) {
03085             if (user->deny)
03086                free(user->deny);
03087             user->deny = ast_strdup(var->value);
03088          } else if (!strcasecmp(var->name, "permit") ) {
03089             if (user->permit)
03090                free(user->permit);
03091             user->permit = ast_strdup(var->value);
03092          }  else if (!strcasecmp(var->name, "read") ) {
03093             if (user->read)
03094                free(user->read);
03095             user->read = ast_strdup(var->value);
03096          }  else if (!strcasecmp(var->name, "write") ) {
03097             if (user->write)
03098                free(user->write);
03099             user->write = ast_strdup(var->value);
03100          }  else if (!strcasecmp(var->name, "displayconnects") )
03101             user->displayconnects = ast_true(var->value);
03102          else
03103             ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name);
03104          var = var->next;
03105       }
03106    }
03107 
03108    /* Perform cleanup - essentially prune out old users that no longer exist */
03109    AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) {
03110       if (user->keep) {
03111          user->keep = 0;
03112          continue;
03113       }
03114       /* We do not need to keep this user so take them out of the list */
03115       AST_LIST_REMOVE_CURRENT(&users, list);
03116       /* Free their memory now */
03117       if (user->secret)
03118          free(user->secret);
03119       if (user->deny)
03120          free(user->deny);
03121       if (user->permit)
03122          free(user->permit);
03123       if (user->read)
03124          free(user->read);
03125       if (user->write)
03126          free(user->write);
03127       free(user);
03128    }
03129    AST_LIST_TRAVERSE_SAFE_END
03130 
03131    AST_LIST_UNLOCK(&users);
03132 
03133    ast_config_destroy(cfg);
03134    
03135    if (webenabled && enabled) {
03136       if (!webregged) {
03137          ast_http_uri_link(&rawmanuri);
03138          ast_http_uri_link(&manageruri);
03139          ast_http_uri_link(&managerxmluri);
03140          webregged = 1;
03141       }
03142    } else {
03143       if (webregged) {
03144          ast_http_uri_unlink(&rawmanuri);
03145          ast_http_uri_unlink(&manageruri);
03146          ast_http_uri_unlink(&managerxmluri);
03147          webregged = 0;
03148       }
03149    }
03150 
03151    if (newhttptimeout > 0)
03152       httptimeout = newhttptimeout;
03153 
03154    /* If not enabled, do nothing */
03155    if (!enabled)
03156       return 0;
03157 
03158    if (asock < 0) {
03159       asock = socket(AF_INET, SOCK_STREAM, 0);
03160       if (asock < 0) {
03161          ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
03162          return -1;
03163       }
03164       setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
03165       if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) {
03166          ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno));
03167          close(asock);
03168          asock = -1;
03169          return -1;
03170       }
03171       if (listen(asock, 2)) {
03172          ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno));
03173          close(asock);
03174          asock = -1;
03175          return -1;
03176       }
03177       flags = fcntl(asock, F_GETFL);
03178       fcntl(asock, F_SETFL, flags | O_NONBLOCK);
03179       if (option_verbose)
03180          ast_verbose("Asterisk Management interface listening on port %d\n", portno);
03181       ast_pthread_create_background(&t, NULL, accept_thread, NULL);
03182    }
03183    return 0;
03184 }

int reload_manager ( void   ) 

Definition at line 3186 of file manager.c.

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

03187 {
03188    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
03189    return init_manager();
03190 }


Variable Documentation

int const char const char* contents

Definition at line 129 of file manager.h.

int const char* event

Definition at line 129 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 142 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 Sat Nov 1 06:29:10 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1