[asterisk-dev] new feature
Rafael Vidal Aroca
rafael at 3WT.com.br
Sun Mar 5 08:05:07 MST 2006
Hi guys,
some days ago i was asking in this list how we could avoid 2 users
from simultaneosly connecting. Well, after some discussion, i decided to
implement a general solution, that should work for other problems too.
The idea is to execute an exeternal program every time a user
registers or unregisters, so we can setup scripts to insert data in
databases, or take some actions.
I made it for IAX2, but will implement that for SIP too, if needed.
An working example is:
Configure iax.conf
- In the section [general] add a parameter
exec=/tmp/script.sh
Then, create the /tmp/script.sh
#!/bin/sh
#Sun Mar 5 09:56:53 BRT 2006
#Rafael Aroca <rafael at 3wt.com.br>
#Test script executed by asterisk on registering and unregistering peers
echo "[`date`] Received from asterisk parameters $*" >> /tmp/output
Apply the patch, compile, copy the new channel_iax2.so, and run
asterisk.
Everytime asterisk receives an IAX2 message of REGISTER or a clients
gets UNREGISTERED, /tmp/output receives a new line. My output now after
some tests is:
root at gemini:/home/rafael/voip# cat /tmp/output
[Sun Mar 5 11:03:43 BRT 2006] Received from asterisk parameters
register 2005
[Sun Mar 5 11:03:51 BRT 2006] Received from asterisk parameters
unregister 2004
[Sun Mar 5 11:44:14 BRT 2006] Received from asterisk parameters
register 2005
[Sun Mar 5 11:44:40 BRT 2006] Received from asterisk parameters
register 2005
[Sun Mar 5 11:45:14 BRT 2006] Received from asterisk parameters
register 2005
[Sun Mar 5 11:45:40 BRT 2006] Received from asterisk parameters
register 2005
[Sun Mar 5 11:46:14 BRT 2006] Received from asterisk parameters
register 2005
[Sun Mar 5 11:47:24 BRT 2006] Received from asterisk parameters
unregister 2005
Based on that, we can connect to database, or do some other
interesting actions.
The patch for this feature follows attached. By the way, would it be
possible (if my code is safe and verified by someone else) to add this
to asterisk SVN?
thanks
[] Rafael.
-------------- next part --------------
--- asterisk-1.2.4/channels/chan_iax2.c 2006-01-19 23:00:46.000000000 -0200
+++ asterisk-1.2.4-tmp/channels/chan_iax2.c 2006-03-05 10:55:58.000000000 -0300
@@ -145,6 +145,7 @@
static char language[MAX_LANGUAGE] = "";
static char regcontext[AST_MAX_CONTEXT] = "";
+static char execOnRegister[100] = "";
static int max_retries = 4;
static int ping_time = 20;
@@ -5552,8 +5553,31 @@
static int expire_registry(void *data)
{
struct iax2_peer *p = data;
+ int res_fork, res_exec;
ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
+
+ res_fork = fork();
+ if (res_fork < 0) {
+ ast_log(LOG_NOTICE, "Could not fork");
+ }
+
+ if (res_fork == 0) {
+ //Example: works fine
+ //res_exec = execlp("ls", "ls", "-la", NULL);
+ res_exec = execlp(execOnRegister, execOnRegister, "unregister", p->name, NULL);
+ } else {
+ res_exec = -1;
+ }
+
+ if (res_exec < 0) {
+ ast_log(LOG_NOTICE, "Could not exec %s", execOnRegister);
+ } else {
+ ast_log(LOG_NOTICE, "Process spawned with PID %d", res_fork);
+ }
+
+
+
/* Reset the address */
memset(&p->addr, 0, sizeof(p->addr));
/* Reset expire notice */
@@ -5626,6 +5650,7 @@
char data[80];
char iabuf[INET_ADDRSTRLEN];
int version;
+ int res_fork, res_exec;
memset(&ied, 0, sizeof(ied));
@@ -5645,9 +5670,33 @@
snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expiry);
if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
ast_db_put("IAX/Registry", p->name, data);
+
+
+ ast_log(LOG_NOTICE, "Running %s for peer '%s'\n", execOnRegister, p->name);
+
+ res_fork = fork();
+ if (res_fork < 0) {
+ ast_log(LOG_NOTICE, "Could not fork");
+ }
+
+ if (res_fork == 0) {
+ //Example: works fine
+ //res_exec = execlp("ls", "ls", "-la", NULL);
+ res_exec = execlp(execOnRegister, execOnRegister, "register", p->name, NULL);
+ } else {
+ res_exec = -1;
+ }
+
+ if (res_exec < 0) {
+ ast_log(LOG_NOTICE, "Could not exec %s", execOnRegister);
+ } else {
+ ast_log(LOG_NOTICE, "Process spawned with PID %d", res_fork);
+ }
+
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
+
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
register_peer_exten(p, 1);
ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
@@ -8624,6 +8673,8 @@
portno = atoi(v->value);
} else if (!strcasecmp(v->name, "pingtime"))
ping_time = atoi(v->value);
+ else if (!strcasecmp(v->name, "exec"))
+ ast_copy_string(execOnRegister, v->value, sizeof(execOnRegister));
else if (!strcasecmp(v->name, "nochecksums")) {
#ifdef SO_NO_CHECK
if (ast_true(v->value))
More information about the asterisk-dev
mailing list