Mostrando las entradas con la etiqueta agi. Mostrar todas las entradas
Mostrando las entradas con la etiqueta agi. Mostrar todas las entradas

martes, 12 de julio de 2011

Benchmarking AGI performance in C, PHP, and Perl

En Venture Voip nos hallamos un artículo de unas pruebas de Benchmarking entre varios lenguajes de programación para determinar su rendimiento con AGI, aquí el artículo en ingles:thumnail

jueves, 26 de mayo de 2011

Cómo programar un AGI en PHP sin librerías raras

Un excelente artículo que Elio Rojano nos comparte en su blog de Sinologic. Una de las personas que más respeto en este ambito de la voz ip


 


Muchas personas que están aprendiendo Asterisk y que ya conocen las posibilidades de esta aplicación, quieren 


 


 


 


empezar a desarrollar sus propias soluciones para que Asterisk pueda interactuar con bases de datos, archivos del sistema de ficheros y en función de algún valor, conseguir que Asterisk haga una llamada, reproduzca una locución, o mil cosas más.


 


 


Esto se realiza gracias a un concepto en Asterisk llamado AGI (Asterisk Gateway Interface) y que viene a ser un programa desarrollado por nosotros (o por otro usuario) que Asterisk ejecuta (importante esto último) y que sirve para que interactúe Asterisk con el sistema Linux, pudiendo acceder a archivos locales, puertos físicos (usb, puertos series, paralelos, etc.), bases de datos, páginas webs, y prácticamente cualquier otra cosa que pueda manejar nuestro sistema Linux.


 


No voy a entrar en la “profundidad” en la que se entra en el curso Asterisk Advanced, pero sí ofrecer un esqueleto básico de un AGI programado en PHP sin necesidad de librerías externas y utilizando una programación muy sencilla (ideal para empezar a familiarizarse con este tipo de sistemas de integración Asterisk-*)


A continuación tenéis un ejemplo ultra-básico sobre cómo puede ser un AGI programado en PHP y sin necesidad de librerías tipo “php-agi” ni “AstPHPAGI”, ni ninguna otra, tan solo tu Asterisk, tú y PHP con sus modulitos.


Debo decir que este ejemplo no lo he programado yo, pero para ilustrar el ejemplo sirve igualmente.


Los comentarios sí son míos y creo que ayudan bastante a entender cómo funciona y qué precauciones debemos tomar antes, durante y después de programar un AGI.


También sé que para muchos, programar un AGI no tiene ninguna ciencia, pero hay que entender que muchos lectores se consideran muy, muy novatos, así que para seguir aprendiendo, aquí tenéis este ejemplo:


#!/usr/bin/php
<?php

// Lo primero es entrar en el Asterisk y ejecutar el comando: "agi set debug on" para ver 
// qué va haciendo el AGI.

// Hay que evitar enviar por la "salida estandar" nada, salvo los comandos para el Asterisk.

// El Asterisk nada más ejecutar el AGI, nos envía información para aburrir...
$agivars = array();
while (!feof(STDIN)) {
$agivar = trim(fgets(STDIN));
if ($agivar === '') {
break;
}
$agivar = explode(':', $agivar);
$agivars[$agivar[0]] = trim($agivar[1]);
}

// la variable $agivars es un array bidimensional con los datos recogidos por el Asterisk
// Un ejemplo de esto puede ser:
// exten=>00,1,AGI(prueba.php,600123456)
/*
Array
(
[agi_request] => prueba.php    ;; Nombre del archivo que contiene el AGI que está ejecutando.
[agi_channel] => SIP/100-00000008   ;; Canal SIP que llama al AGI. (canal, que no usuario)
[agi_language] => en           ;; Idioma por defecto del canal
[agi_type] => SIP              ;; tipo de Tecnología utilizada para llamar al AGI
[agi_uniqueid] => 1305795790.9 ;; UniqueID de la "llamada al AGI"
[agi_version] => 1.8.4         ;; Versio? del sistema AGI utilizado. ¿coincide con el Asterisk?
[agi_callerid] => 100          ;; CallerID del usuario que ejecuta el AGI
[agi_calleridname] => 100      ;; CallerIDname del usuario que ejecuta el AGI
[agi_callingpres] => 0         ;; ...
[agi_callingani2] => 0         ;; ...
[agi_callington] => 0          ;; ...
[agi_callingtns] => 0          ;; ...
[agi_dnid] => 00               ;; Número marcado en el dialplan para llamar al AGI
[agi_rdnis] => unknown         ;; ...
[agi_context] => salientes     ;; Contexto donde se ejecuta el AGI
[agi_extension] => 00          ;; Extensión donde se ejecuta el AGI
[agi_priority] => 1            ;; Prioridad donde se ejecuta el AGI
[agi_enhanced] => 0.0          ;; Agi "mejorado" 
[agi_accountcode] =>           ;; El AccountCode (si lo hemos definido)
[agi_threadid] => -1239581840  ;; ...
[agi_arg_1] => 600123456       ;; Argumento 1 del AGI (el Argumento 0 es el nombre del AGI)
[agi_arg_2] =>                 ;; Argumento 2 del AGI
...                     ;; ...
)
*/

// Vamos a decirle a Asterisk que haga un Dial al número que le hemos pasado por parámetro:

echo "EXEC Dial DAHDI/g1/".$agivars[agi_arg_1];

// Podemos usar los comandos propios de los AGI (como hemos usado el 'EXEC') que podemos obtener
// ejecutando en la consola "agi show commands" o "agi show commands topic <comando>" para una
// información más detallada de cada comando.

// Importante... despues del "?" y el ">" del 'fin del PHP' no debe haber ni siquiera un [ENTER]... 
// ya que en caso contrario, Asterisk devolverá un error del tipo:
// ERROR[24598]: utils.c:1133 ast_carefulwrite: write() returned error: Broken pipe
?>

El código no puede ser más sencillo, quizá lo más interesante pueden ser los comentarios que explican el comienzo y los comandos básicos para programar un AGI.


Sin más me queda agradecer de nuevo a Elio Rojano por sus grandes aporte a la comunidad de Asterisk


Fuente: Sinologic.net

lunes, 24 de enero de 2011

Agispeedy - faster than AGI and performance improved 10 times comparing with AGI

 


agispeedy_workflow


The Agispeedy is robust implemention of AGI in asterisk. Agispeedy is inconceivable faster than AGI. The result of test shows that by using Agispeedy in asterisk, the performance of system would be improved more than 10 times comparing with AGI.


Agispeedy Features:


* implemention of AGI(FastAGI) over TCP Sockets 
* Work in Stabilize Prefork Mode and Written by Pure Perl. 
* Easy to Maintain, unlike FastAGI(Dynamic Load AGI no need restart Agispeedy services) 
* Providing possibility of running AGI on a remote server(Inheriting the FastAGI) 
* Fast Database Connect(system can hook database connection in child process)


agispeedy_cluster


Table of asterisk extend tech:


 




































name



speed



reliability



cluster



asterisk module



top faster



easy crash



no



agi



slowly



strong



no



fastagi



faster



maybe crash



yes



agispeedy



faster



strong



yes



 


Get Agispeedy


get source files from SVN:
>svn export http://darwin.freeiris.org/svn/freeiris/addition/agispeedy/

Installation


Under the agispeedy, install agispeedy by run the script: ./install.pl You also can add -–prefix=path to other directory, for example, you can add agispeedy to system boot by copying contrib/agispeedy.init.centos to /etc/init.d/


please note: sudo as root

>cd agispeedy
>chmod +x install.pl
>./install.pl

[RESPONSE] Agispeedy Installer
[INPUT] continue to install agispeedy to /agispeedy (yes/no)?yes
......
[RESPONSE] set /etc/agispeedy
[RESPONSE] set agispeedy services

Command Line


More parameters to run AGIspeedy:


-?, –help Display this help and exit. 
-V, –version Output version information and exit. 
-v, –verbose Display more messages on screen(debug level 4). 
-q, –quiet Start Agispeedy as background. 
-c, –config=path Specify Config files directory. 
-L, –log=path Specify Log files directory. 
-l, –lib=lib Specify Agispeedy include directory. 
-P, –pid=path Specify pid file directory. 
-a, –var=path Specify Agispeedy script modules directory.


run DEBUG mode: 
./agispeedy –verbose


will output all messages from agispeedy services


Run Normal Commandline: 
./agispeedy –quiet


agispeedy will quiet and slience run in background and write messages to log_files.


run Services: 
/etc/init.d/agispeedy start


If you are not use redhat, you have to manually install init scripts.


 


checking process:

>ps ax|grep agispeedy
32424 ? Ss 0:00 /usr/bin/perl /agispeedy/bin/agispeedy -q -c /etc/agispeedy
32425 ? S 0:00 /usr/bin/perl /agispeedy/bin/agispeedy -q -c /etc/agispeedy
32426 ? S 0:00 /usr/bin/perl /agispeedy/bin/agispeedy -q -c /etc/agispeedy
32427 ? S 0:00 /usr/bin/perl /agispeedy/bin/agispeedy -q -c /etc/agispeedy
32428 ? S 0:00 /usr/bin/perl /agispeedy/bin/agispeedy -q -c /etc/agispeedy
32430 ? S 0:00 /usr/bin/perl /agispeedy/bin/agispeedy -q -c /etc/agispeedy
32431 ? S 0:00 /usr/bin/perl /agispeedy/bin/agispeedy -q -c /etc/agispeedy

 

how does agispeedy work

example : 
exten => 123456,n,AGI(agi://127.0.0.1/demo_dynamic?number=7890)

* asterisk send socket request scriptname demo_dynamic with args 
* agispeedy get one child to response asterisk 
* child find demo_dynamic static module in memory 
* child find demo_dynamic.dam in /agispeedy/var/ 
* child do args parse and push to hash table 
* child synatx checking and complie demo_dynamic.dam 
* child run entry function demo_dynamic() 
* child exit


Fuente: Voip Today

lunes, 15 de marzo de 2010

Asterisk AGI y Fast AGI

En estos dias he estado leyendome un libro de Asterisk, se trata de Asterisk AGI(Asterisk Gateway Interface), salen diez reglas que se deben tener en cuenta a la hora de programar AGI, haré un breve resumen de estas diez asi como de algunos puntos que me parecieron importantes, al final del post dejaré algunos links donde podrán ahondar más en el tema, ahora manos a la obra que ya me dió sueño jaja, ojo todo esta ingles espero que entiendan

How does AGI work:



As the previous diagram illustrates, an AGI script communicates with Asteriskvia two standard data streams—STDIN (Standard Input) and STDOUT (StandardOutput). From the AGI script point-of-view, any input coming in from Asteriskwould be considered STDIN, while output to Asterisk would be consideredas STDOUT.The idea of using STDIN/STDOUT data streams with applications isn't a new one,even if you're a junior level programmer. Think of it as regarding any input fromAsterisk with a read directive and outputting to Asterisk with a print or echodirective. When thinking about it in such a simplistic manner, it is clear that AGIscripts can be written in any scripting or programming language, ranging fromBASH scripting, through PERL/PHP scripting, to even writing C/C++ programs toperform the same task.



FastAGI Frameworks



AGI Frameworks




The AGI execution flow

Once an AGI script has been invoked, a preset information flow is performed between the AGI script and Asterisk. It is imperative to understand this information flow, as the structure of your AGI script depends on this flow. The following diagram describes the steps that occur when an AGI script is executed from within the Asterisk dialplan:



The ten rules of AGI development

Developers, who are given the task of developing an AGI script for the first time, tend to superimpose their traditional development techniques over the development of AGI scripts. By far, this is the most dangerous thing that can be done, as AGI scripting and traditional programming vary immensely. The following section will list the do's and don'ts that need to be followed, so that your AGI scripts work and function properly.

Rule #1: An AGI script should terminate as fast as possible

First-time AGI developers tend to develop their entire application within an AGI script. As you develop your entire application within an AGI script, you may gain the power of the scripting language, but will incur a cost of performance. Always make sure that the AGI scripts that you develop terminate their execution as fast as possible, returning to the dialplan as fast as possible. This concept dictates that each AGI script being run should behave quickly as an atomic unit—hence the name "Atomic AGI".
Rule #2: Blocking applications have no place in AGI

As a direct continuation to rule #1, you should never execute a blocking application from within an AGI script. Initiating a blocking application from within an AGI script will make your Asterisk environment explode slowly. Why is that? Because for every blocking application that you run from within the AGI script, you will have both your AGI script and the blocking application running for the duration of the lock. Imagine that you were to initiate the Dial application from within an AGI script, and the call created would last over thirty minutes. For those thirty minutes, your AGI script is still active. This isn't much of a problem when dealing with small-scale systems. But when trying to run 50 concurrent scripts, be prepared for failure. Blocking applications include the following: Dial, MeetMe, MusicOnHold, Playback (when dealing with long playbacks), Monitor, ChanSpy, and other applications that have an unknown execution duration.

Rule #3: Asterisk channels are stateful—use them

An Asterisk channel, once operational, is like a big bucket of information. Channel variables can be used to carry information from your AGI script to the dialplan and back. The variables remain as part of the channel untill the channel is terminated, when memory is then freed. Using this "bucket" enables you to carry variables and information obtained via an AGI script and then pass these to an application in the dialplan. For example, imagine that you are developing a pre-paid platform. A decision on the call timeout is taken via an AGI script. However, the actual dialling of the call is performed from the dialplan itself.

Rule #4: AGI scripts should manipulate data—no more

Most developers tend to think of AGI scripting as a functional unit, meaning that they enclose multiple functionalities into the AGI script. While AGI is fully capable of performing telephony functionality, it is best to leave this functionality to the dialplan. Utilize your AGI script to set and reset channel variables and communicate with out-of-band information systems. The concept of allowing out-of-band information flow into Asterisk's operational flow of channel, enables new functionality and possibilities. Not all logic should be handled by your AGI script. Sometimes, it is better to use the AGI script as a data conduit, while letting an external information system handle the data manipulation.

Rule #5: VM based languages are bad for AGI scripting

Virtual machine based programming languages' are bad for AGI scripting. Putting aside the rules #1 and #2, imagine that your application is built using an AGI script using the Java programming language. If you are familiar with Java, you most probably know that for each program that you execute using Java, a full Java virtual machine is invoked.

While this practice may seem fairly normal for information systems, Asterisk and IVR development vary. Imagine that our system is required to handle a maximum number of 120 concurrent channels, which means that the maximum number of concurrent AGI scripts will be 120. According to this concept, our Java environment will be fully invoked for each of these 120 instances. In other words, too many resources are being used just for the VM. If you really feel that you want to develop AGI scripts using Java, FastAGI is the way to go for you.

Rule #6: Binary-compiled AGI is not always the answer

While evaluating rules #1, #2 and #5, we can't but reach an almost immediate conclusion that we need to have our AGI script binary compiled. While in terms of efficiency and performance, a binary compiled AGI may provide better performance, the time required to develop it may be longer. In some cases, scripting languages such as PHP, PERL, and Python may provide near-similar performance at a lesser cost.

Also, when using binary compiled AGI scripts, you are always in charge of the memory allocation and cleanup. Even the most experienced developer can commit errors while dealing with memory allocation, so binary compiled AGI need not be the solution always.

If your system truly requires the performance edge of a binary compiled AGI, we encourage you to develop a prototype using a scripting language. Once you have your prototype working, start developing your binary version.

Rule #7: Balance your scripts with dialplan logic

While evaluating rules #1, #2 and #4, we must keep in mind that developing IVR systems with Asterisk resembles a high-wire balancing act. The fine art of balancing your dialplan with AGI scripts proves to be a powerful tool, especially when developing complex IVR systems.

Many developers tend to externalize functionality from the dialplan into AGI, while the same functionality can be achieved by writing dialplan macros or dialplan contexts. Using Asterisk's branching commands (goto, gotoif, exec, execif, gosub and gosubif) can easily remove redundant AGI code, passing the control from the AGI back to the dialplan.

Rule #8: Balance your scripts with web services

When evaluating rule #4, one may ask: "What is an out-of-band information system?" We shall explain now. Most Asterisk developers tend to develop their systems with the data information system—either embedded into their Asterisk server or communicating with an information system installed on the same server with the Asterisk server.

While, for small systems, this proves to be both efficient and economic, when developing a high-end ystem that requires scalability and redundancy, this methodology proves to be counter-productive. One of the methodologies (although many others exist) for interconnecting Asterisk with an out-of-band information system is web services. Communication to the web service is performed via AGI; the web-service protocol—you can use your favourite one. The choice of protocol isn't that important, as almost any protocol type used for web services would do. Be it SOAP, WSDL, XML-RPC, WDDX or any other, take your pick, and the performance and scalability should be similar in any of these.

Rule #9: Syslog is your friend—use it

Every developer knows that using log files for debugging and monitoring purposes is a must. Be it for using a binary compiled AGI or a scripting language based AGI, make sure to utilize the logging facility. Trying to debug an AGI application from within the Asterisk console, though possible, can prove to be a tedious task. Sending log entries to a well-formatted log can save you much time and headache.

Scripting languages, such as PHP and PERL, do not offer a direct debugging facility, making the debugging of such AGI scripts even harder. Using log files as a debugging point for your AGI script will prove very useful when developing highly complex systems.

In order to make your syslog more readable, assign a self-created unique ID to each of your calls. When writing to your log, make sure that the unique ID appears in each log entry, so that you can trace a specific

session flow through Asterisk. Remember, an Asterisk channel is stateful. The unique ID will remain as part of the channel untill it is removed from the system.

Rule #10: The Internet is for Asterisk

As bad as the following may sound, if you have a problem or an idea, remember that someone else had almost definitely come across it before you did. I don't want to discourage you, but actually, I want you to make use of the multitude of Asterisk resources available on the Internet.

Básicamente esa seria toda la informaicón hasta ahora, aquí les dejo los links: