[Asterisk-Dev] Integration of AGI and Management API

David Pollak dpp-asterisk at projectsinmotion.com
Wed Aug 11 11:08:19 MST 2004


Matt,

I think we agree on the goals:

    * To minimize the number of threads and sockets on the machine
      running Asterisk to maximize the performance of the machine
      running Asterisk
    * To minimize the changes to Asterisk, but maximize the flexibility
      of Asterisk
    * To minimize the number of open Manager API connections

My proposal (and the code that I have already developed) allows the 
posting of AGI commands from the Manager API to a given channel and 
sending the response code for the commands from res_agi.c to the 
Manager.  The code simply pipes AGI commands from a source other than a 
pipe that's dedicated to a single AGI session.

Put another way, AGI is a lot like early CGI on web servers.  Over time, 
systems like mod_perl, etc. were developed to reduce load on systems.  
What the merger between Manager API and AGI does is allows a single 
manager connection to manage the execution of applications on an 
arbitrary number of channels.

mattf wrote:

>When you say 100 concurrent channels do you mean 50 SIP phones connected to
>50 Zap channels or 100 SIP phones in conversations with 100 other end
>points?
>  
>
The initial system that we're building primarily performs IVR.  All of 
the channels will be terminated SIP calls.

>Have you done any load testing ? What kind of system configuration are you
>planning on?
>  
>
Each of the Asterisk servers will be P4 3.x Ghz systems running Intel's 
875 chipset.

>How exactly would you go about "creating" a calling card AGI through the
>manager?
>  
>
Sending (or piping) the AGI commands through the Manager API so that 
they are posted to a Channel.  The exec_agi() routine in res_agi.c 
dequeues the AGI command from the channel rather than reading it from a 
file descriptor.  Once the command is read or dequeue, it's executed and 
the results are sent back to the fd or sent as a manager_event.

>What's wrong with just using AGI scripts?
>
>  
>
Please see my original posting.  With AGI scripts, there's a seperate 
process created for each AGI that's executed.  Hooking the AGI process 
to my central J2EE server means 2 open sockets for each running AGI.  
Monitoring 100 channels on 25 machines means 2,500 open sockets to my 
J2EE server.  On the other hand, sending AGI commands via the Manager 
API means only 25 open sockets for my J2EE server and only 1 open 
connection from the Asterisk instance to my server.

>A busy Asterisk server with 100 concurrent manager connections will not
>work, especially if you want to actually use those manager connecitons for
>anything.
>  
>
I think you're missing the point.  There will only be 1 open manager 
instance per Asterisk instance.  That single manager instance will 
control all the open channels.

>Attempting to run interactive programs like AGIs through the manager API
>would complicate the managerAPI by adding many new inputs, outputs and
>parsing rules to it and would slow it down even more, not to mention the
>fact that you are depending on that client socket connection to keep flowing
>perfectly in order to run your phone system and I can tell you that the
>manager API is not fault tolerant enough to handle that kind of volume,
>complexity and data-delivery-assurance with any kind of reliability.
>
>  
>
Nope.  Here's the total change to manager.c (okay, there's one other 
change where the action_magi function is registered, but that's an 
additional line in an array of functions):
static int action_magi(struct mansession *s, struct message *m)
{
  char *command = astman_get_header(m, "Command");
  char *channel = astman_get_header(m, "Channel");
  char *id = astman_get_header(m, "Uniqueid");

  if (!command || ast_strlen_zero(command)) {
    astman_send_error(s, m, "Command not specified");
    return 0;
  }

  if (!channel || ast_strlen_zero(channel)) {
    astman_send_error(s, m, "Channel not specified");
    return 0;
  }

  if (!id || ast_strlen_zero(id)) {
    astman_send_error(s, m, "UniqueID not specified");
    return 0;
  }

  struct ast_channel *theChan = ast_get_channel_by_name_locked(channel);

  if (!theChan) {
    astman_send_error(s, m, "Channel not found");
    return 0;
  }

  // allocate the structure here... it will be
  // free'ed if enqueuing fails or if
  struct ast_magi *magi = ast_magi_new();

  if (!magi) {
    astman_send_error(s, m, "MAGI not allocated -- out of memory");
    ast_mutex_unlock(&theChan->lock);
    return 0;
  }

  // being smart, cmd is 1 char longer than MAX_AGI_CMD_LEN
  // so we strncpy, and then set the last char to 0
  strncpy(magi->cmd, command, MAX_AGI_CMD_LEN);
  magi->cmd[MAX_AGI_CMD_LEN] = 0;

  // see above re field lengths
  strncpy(magi->uniqueid, id, MAX_MAGI_UNIQUE_ID);
  magi->uniqueid[MAX_MAGI_UNIQUE_ID] = 0;


  // if the add fails, this routine cleans up
  // the magi
  int added = ast_add_magi_to_channel(theChan, magi, 0);

  ast_mutex_unlock(&theChan->lock);

  if (!added) {
    astman_send_error(s, m, "MAGI not added to channel");
    return 0;
  }

  ast_cli(s->fd, "Response: Success\r\n"
      "Uniqueid: %s\r\n\r\n",
      id);

  return 0;
}

All of the parsing for the commands is done is reg_agi and the commands 
are treated *exactly* like the commands that came in from a pipe/file 
descriptor that the current AGI monitors.

If you can find anything in this code that will reduce the stability of 
the Manager or create a bottleneck, please let me know.

Thanks,

David

>MATT---
>
>
>-----Original Message-----
>From: David Pollak [mailto:dpp-asterisk at projectsinmotion.com]
>Sent: Tuesday, August 10, 2004 10:58 PM
>To: asterisk-dev at lists.digium.com
>Subject: Re: [Asterisk-Dev] Integration of AGI and Management API
>
>
>
>  
>My application will initially have 25 Asterisk servers managed by 1
>application server.  That number must be scalable to at least 500 Asterisk
>servers.
>
>Given the initial 25 servers, with 100 open channels each, that's 2,500
>channels to manage.  
>
> 
>
>So, I've been looking over the Asterisk source and I had an idea... what 
>if there was a merger of the Manager API and AGI.  Here's specifically 
>what I was thinking:
>    
>
>It looks like you've already done that above.  You already
>started using the AGI and the AMI, so that's where the
>merger is.  I could be wrong on this, but the rest of your
>message concerns how to put these two things back together.
>So you are making a circle, when a straight line would do.
>  
>I have not found a straight line from the Manager API that allows the
>execution of an application on a given channel with all the normal responses
>(e.g., waiting for DTMF, etc.)  If you can show me how to do that, I'd
>really appreciate it.
>  
>
>Yep... I can see originating a call to an application, but I cannot see how
>to respond to an existing channel.  For example, how would one create the
>Calling Card sample AGI application by originating a call?
>
>
>To my mind, all AGI scripts represent dynamic dial plans.  I haven't done
>the full analysis, but it seems that dial plans themselves are Turing
>complete.  However, it's really, really hard to build complex applications
>using dial plans.  Thus, AGI script allow for a better language to write
>dynamic dial plans.  My changes are simply to allow the AGI commands to be
>sent to a channel via the Manager API rather than via a pipe to a separate
>process.  In res_agi.c, the next command is recalled from the Channel rather
>than by reading from the pipe.  That's the fundimental difference.
>
>  
>I don't think that works.  I think the AGI was added to Asterisk because the
>ability to control a channel via the Manager API is limitted.  My changes
>have simply added a new way in which an AGI script can send commands to a
>Channel that's expecting AGI commands.
>
>Thanks,
>
>David
>_______________________________________________
>Asterisk-Dev mailing list
>Asterisk-Dev at lists.digium.com
>http://lists.digium.com/mailman/listinfo/asterisk-dev
>To UNSUBSCRIBE or update options visit:
>   http://lists.digium.com/mailman/listinfo/asterisk-dev
>  
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.digium.com/pipermail/asterisk-dev/attachments/20040811/86ece119/attachment.htm


More information about the asterisk-dev mailing list