[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