[asterisk-commits] jdixon: branch jdixon/chan_usbradio-1.4 r143123 - /team/jdixon/chan_usbradio-...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Sep 15 01:50:36 CDT 2008


Author: jdixon
Date: Mon Sep 15 01:50:35 2008
New Revision: 143123

URL: http://svn.digium.com/view/asterisk?view=rev&rev=143123
Log:
Added reporting of link info to PC clients

Modified:
    team/jdixon/chan_usbradio-1.4/channels/chan_echolink.c

Modified: team/jdixon/chan_usbradio-1.4/channels/chan_echolink.c
URL: http://svn.digium.com/view/asterisk/team/jdixon/chan_usbradio-1.4/channels/chan_echolink.c?view=diff&rev=143123&r1=143122&r2=143123
==============================================================================
--- team/jdixon/chan_usbradio-1.4/channels/chan_echolink.c (original)
+++ team/jdixon/chan_usbradio-1.4/channels/chan_echolink.c Mon Sep 15 01:50:35 2008
@@ -33,7 +33,7 @@
 	<depend>zlib</depend>
  ***/
 
-/* Version 0.17, 09/14/2008
+/* Version 0.18, 09/14/2008
 Echolink channel driver for Asterisk/app_rpt.
 
 I wish to thank the following people for the immeasurable amount of
@@ -144,6 +144,9 @@
 #define EL_MAX_SERVERS 3
 #define EL_SERVERNAME_SIZE 63
 #define	EL_MAX_INSTANCES 100
+
+#define	DELIMCHR ','
+#define	QUOTECHR 34
 
 /* 
    If you want to compile/link this code
@@ -229,6 +232,7 @@
 	int fdr;
 	unsigned long seqno;
 	int confmode;
+	int irlpnode;
 	struct el_pvt *confp;
 	struct gsmVoice_t audio_all_but_one;
 	struct gsmVoice_t audio_all;
@@ -268,6 +272,7 @@
 	struct ast_module_user *u;
 	struct ast_trans_pvt *xpath;
 	unsigned int nodenum;
+	char *linkstr;
 };
 
 struct rtcp_sdes_request_item {
@@ -367,6 +372,7 @@
 static void send_audio_all_but_one(const void *nodep, const VISIT which, const int depth);
 static void send_audio_all(const void *nodep, const VISIT which, const int depth);
 static void send_heartbeat(const void *nodep, const VISIT which, const int depth);
+static void send_info(const void *nodep, const VISIT which, const int depth);
 static void print_users(const void *nodep, const VISIT which, const int depth);
 static void free_node(void *nodep);
 static void process_cmd(char *buf,char *fromip,struct el_instance *instp);
@@ -415,6 +421,54 @@
 	pthread_exit(NULL);
 }
 
+/*
+* Break up a delimited string into a table of substrings
+*
+* str - delimited string ( will be modified )
+* strp- list of pointers to substrings (this is built by this function), NULL will be placed at end of list
+* limit- maximum number of substrings to process
+*/
+	
+
+
+static int finddelim(char *str, char *strp[], int limit)
+{
+int     i,l,inquo;
+
+        inquo = 0;
+        i = 0;
+        strp[i++] = str;
+        if (!*str)
+           {
+                strp[0] = 0;
+                return(0);
+           }
+        for(l = 0; *str && (l < limit) ; str++)
+           {
+                if (*str == QUOTECHR)
+                   {
+                        if (inquo)
+                           {
+                                *str = 0;
+                                inquo = 0;
+                           }
+                        else
+                           {
+                                strp[i - 1] = str + 1;
+                                inquo = 1;
+                           }
+		}
+                if ((*str == DELIMCHR) && (!inquo))
+                {
+                        *str = 0;
+			l++;
+                        strp[i++] = str + 1;
+                }
+           }
+        strp[i] = 0;
+        return(i);
+
+}
 static int rtcp_make_sdes(unsigned char *pkt, int pktLen, char *call, char *name)
 {
     unsigned char zp[1500];
@@ -636,11 +690,11 @@
 	{
 		char *str,*cp;
 
-		str = strdup(dest);
+		str = ast_strdup(dest);
 		cp = strchr(str,'/');
 		if (cp) *cp++ = 0; else cp = str;
 		snprintf(buf,sizeof(buf) - 1,"o.conip %s",cp);
-		free(str);
+		ast_free(str);
 		ast_mutex_lock(&instp->lock);
 		strcpy(instp->el_node_test.ip,cp);
 		do_new_call(instp,p,"OUTBOUND","OUTBOUND");
@@ -655,6 +709,9 @@
 {
 	if (p->dsp) ast_dsp_free(p->dsp);
 	if (p->xpath) ast_translator_free_path(p->xpath);
+	if (p->linkstr) ast_free(p->linkstr);
+	p->linkstr = NULL;
+        twalk(el_node_list, send_info); 
 #ifdef	OLD_ASTERISK
 	ast_mutex_lock(&usecnt_lock);
 	usecnt--;
@@ -804,18 +861,134 @@
 	return -1;
 }
 
+static int mycompar(const void *a, const void *b)
+{
+char	**x = (char **) a;
+char	**y = (char **) b;
+int	xoff,yoff;
+
+	if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0;
+	if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0;
+	return(strcmp((*x) + xoff,(*y) + yoff));
+}
+
 static int el_text(struct ast_channel *ast, const char *text)
 {
+#define	MAXLINKSTRS 200
+
 	struct el_pvt *p = ast->tech_pvt;
 	char *cmd = NULL,*arg1 = NULL,*arg2 = NULL;
-	char *arg3 = NULL,delim = ' ',*saveptr;
-	char buf[200],*ptr,str[200],*arg4 = NULL;
+	char *arg3 = NULL,delim = ' ',*saveptr,*cp,*pkt;
+	char buf[200],*ptr,str[200],*arg4 = NULL,*strs[MAXLINKSTRS];
+	int i,j,k,x;
 
 	strncpy(buf,text,sizeof(buf) - 1);
 	ptr = strchr(buf, (int)'\r'); 
 	if (ptr) *ptr = '\0';
 	ptr = strchr(buf, (int)'\n');    
 	if (ptr) *ptr = '\0';
+
+	if (p->instp && (!p->instp->confmode) && (text[0] == 'L'))
+	{
+		if (strlen(text) < 3)
+		{
+			if (p->linkstr)
+			{
+				ast_free(p->linkstr);
+				p->linkstr = NULL;
+			        twalk(el_node_list, send_info); 
+			}
+			return 0;
+		}
+		if (p->linkstr)
+		{
+			ast_free(p->linkstr);
+			p->linkstr = NULL;
+		}
+		cp = ast_strdup(text + 2);
+		if (!cp)
+		{
+			ast_log(LOG_ERROR,"Couldnt alloc");
+			return -1;
+		}
+		i = finddelim(cp,strs,MAXLINKSTRS);
+		if (i) 
+		{
+			qsort((void *)strs,i,sizeof(char *),mycompar);
+			pkt = ast_malloc((i * 10) + 50);
+			if (!pkt)
+			{
+				ast_log(LOG_ERROR,"Couldnt alloc");
+				return -1;
+			}
+			memset(pkt,0,(i * 10) + 50);
+			j = 0;
+			k = 0;
+			for(x = 0; x < i; x++)
+			{
+			    if ((*(strs[x] + 1) < '3') ||
+			        (*(strs[x] + 1) > '4'))
+
+			    {
+				    if (strlen(pkt + k) >= 32)
+				    {
+					k = strlen(pkt);
+					strcat(pkt,"\r    ");
+				    }
+				    if (!j++) strcat(pkt,"Allstar:");
+				    if (*strs[x] == 'T')
+					    sprintf(pkt + strlen(pkt)," %s",strs[x] + 1);
+				    else
+					    sprintf(pkt + strlen(pkt)," %s(M)",strs[x] + 1);
+			    }
+			}
+			strcat(pkt,"\r");
+			j = 0;
+			k = strlen(pkt);
+			for(x = 0; x < i; x++)
+			{
+			    if (*(strs[x] + 1) == '3')
+			    {
+				    if (strlen(pkt + k) >= 32)
+				    {
+					k = strlen(pkt);
+					strcat(pkt,"\r    ");
+				    }
+				    if (!j++) strcat(pkt,"Echolink: ");
+				    if (*strs[x] == 'T')
+					    sprintf(pkt + strlen(pkt)," %d",atoi(strs[x] + 2));
+				    else
+					    sprintf(pkt + strlen(pkt)," %d(M)",atoi(strs[x] + 2));
+			    }
+			}
+			strcat(pkt,"\r");
+			j = 0;
+			k = strlen(pkt);
+			for(x = 0; x < i; x++)
+			{
+			    if (*(strs[x] + 1) == '4')
+			    {
+				    if (strlen(pkt + k) >= 32)
+				    {
+					k = strlen(pkt);
+					strcat(pkt,"\r    ");
+				    }
+				    if (!j++) strcat(pkt,"IRLP: ");
+				    if (*strs[x] == 'T')
+					    sprintf(pkt + strlen(pkt)," %s",strs[x] + 2);
+				    else
+					    sprintf(pkt + strlen(pkt)," %s(M)",strs[x] + 2);
+			    }
+			}
+			strcat(pkt,"\r");
+			if (p->linkstr && pkt && (!strcmp(p->linkstr,pkt))) ast_free(pkt);
+			else p->linkstr = pkt;
+		}
+		ast_free(cp);
+	        twalk(el_node_list, send_info); 
+		return 0;
+	}
+
 	cmd = strtok_r(buf, &delim, &saveptr);
 	if (!cmd)
 	{
@@ -863,7 +1036,7 @@
          instp->audio_all_but_one.payt = 3;
          instp->audio_all_but_one.seqnum = htons((*(struct el_node **)nodep)->seqnum++); 
          instp->audio_all_but_one.time = htonl(0);
-         instp->audio_all_but_one.ssrc = instp->mynode;
+         instp->audio_all_but_one.ssrc = htonl(instp->mynode);
 
          /*
          ast_log(LOG_NOTICE, "sending to %s(%s)\n", 
@@ -895,7 +1068,7 @@
       instp->audio_all.payt = 3;
       instp->audio_all.seqnum = htons((*(struct el_node **)nodep)->seqnum++);
       instp->audio_all.time = htonl(0);
-      instp->audio_all.ssrc = instp->mynode;
+      instp->audio_all.ssrc = htonl(instp->mynode);
 
       /*
       ast_log(LOG_NOTICE, "sending to %s(%s)\n", 
@@ -926,7 +1099,7 @@
       instp->audio_all.payt = 3;
       instp->audio_all.seqnum = htons((*(struct el_node **)nodep)->seqnum++);
       instp->audio_all.time = htonl(0);
-      instp->audio_all.ssrc = instp->mynode;
+      instp->audio_all.ssrc = htonl(instp->mynode);
 
       /*
       ast_log(LOG_NOTICE, "sending to %s(%s)\n", 
@@ -945,6 +1118,47 @@
              (*(struct el_node **)nodep)->ip,
              (*(struct el_node **)nodep)->name);
    }
+}
+
+static void send_info(const void *nodep, const VISIT which, const int depth)
+{
+	struct sockaddr_in sin;
+	char pkt[2500],*cp;
+	struct el_instance *instp = (*(struct el_node **)nodep)->instp;
+	int i;
+
+	if ((which == leaf) || (which == postorder)) {
+
+		sin.sin_family = AF_INET;
+		sin.sin_port = htons(instp->audio_port);
+		sin.sin_addr.s_addr = inet_addr((*(struct el_node **)nodep)->ip);
+		snprintf(pkt,sizeof(pkt) - 1,
+			"oNDATA\rWelcome to Allstar Node %s\r",instp->astnode);
+		if (instp->irlpnode)
+		{
+			i = strlen(pkt);
+			snprintf(pkt + i,sizeof(pkt) - (i + 1),
+				"IRLP Node %04d\r",instp->irlpnode);
+		}
+		i = strlen(pkt);
+		snprintf(pkt + i,sizeof(pkt) - (i + 1),
+			"Echolink Node %s\rNumber %u\r \r",
+				instp->mycall,instp->mynode);
+		if ((*(struct el_node **)nodep)->p &&
+		    (*(struct el_node **)nodep)->p->linkstr)
+		{
+			i = strlen(pkt);
+			strncat(pkt + i,"Systems Linked:\r",
+				sizeof(pkt) - (i + 1));
+			cp = ast_strdup((*(struct el_node **)nodep)->p->linkstr);
+			i = strlen(pkt);
+			strncat(pkt + i,cp,sizeof(pkt) - (i + 1));
+			ast_free(cp);
+		}
+		sendto(instp->audio_sock, pkt, strlen(pkt),
+			0,(struct sockaddr *)&sin,sizeof(sin));
+	}
+	return;
 }
 
 static void send_heartbeat(const void *nodep, const VISIT which, const int depth)
@@ -1389,13 +1603,13 @@
 		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
 		return NULL;
 	}
-	str = strdup((char *)data);
+	str = ast_strdup((char *)data);
 	cp = strchr(str,'/');
 	if (cp) *cp++ = 0;
 	nodenum = 0;
 	if (*cp && *++cp) nodenum = atoi(cp);
 	p = el_alloc(str);
-	free(str);
+	ast_free(str);
 	if (p) {
 		tmp = el_new(p, AST_STATE_DOWN,nodenum);
 		if (!tmp)
@@ -1936,7 +2150,7 @@
         struct el_node *el_node_key = NULL;
 	char dbstr[40],nodestr[30];
 
-	el_node_key = (struct el_node *)malloc(sizeof(struct el_node));
+	el_node_key = (struct el_node *)ast_malloc(sizeof(struct el_node));
 	if (el_node_key)
 	{
 		strncpy(el_node_key->call,call,EL_CALL_SIZE);
@@ -1946,7 +2160,7 @@
 		if (ast_db_get(EL_DB_ROOT,dbstr,nodestr,sizeof(nodestr) - 1))
 		{
 			ast_log(LOG_ERROR, "Cannot find DB entry for %s\n",dbstr);
-			free(el_node_key); 
+			ast_free(el_node_key); 
 			return 1;
 		}
 		el_node_key->nodenum = atoi(nodestr);
@@ -1971,7 +2185,7 @@
 					{
 						ast_log(LOG_NOTICE,"Cannot alloc el channel\n");
 						return -1;
-					}											
+					}	
 					el_node_key->p = p;
 					strncpy(el_node_key->p->ip, instp->el_node_test.ip,EL_IP_SIZE);
 					el_node_key->chan = el_new(el_node_key->p,
@@ -1994,7 +2208,7 @@
 		{
 			ast_log(LOG_ERROR, "tsearch() failed to add CALL=%s,ip=%s,name=%s\n",
 				el_node_key->call,el_node_key->ip,el_node_key->name);
-			free(el_node_key); 
+			ast_free(el_node_key); 
 			return -1;
 		}
 	}
@@ -2143,6 +2357,7 @@
 										0,(struct sockaddr *)&sin1,sizeof(sin1));
 								}
 							}
+						        twalk(el_node_list, send_info); 
 						}
 					}
 				}
@@ -2390,6 +2605,12 @@
         else
            strncpy(instp->elservers[2],val,EL_SERVERNAME_SIZE);
 
+        val = (char *) ast_variable_retrieve(cfg,ctg,"irlpnode"); 
+        if (val)
+	{
+	   instp->irlpnode = atoi(val);
+	}
+
 	instp->audio_sock = -1;
 	instp->ctrl_sock = -1;
 
@@ -2455,7 +2676,6 @@
         ast_log(LOG_NOTICE, "Echolink/%s node capacity set to %d node(s)\n", instp->name, instp->maxstns);
         ast_log(LOG_NOTICE, "Echolink/%s heartbeat timeout set to %d heartbeats\n", instp->name,instp->rtcptimeout);
         ast_log(LOG_NOTICE, "Echolink/%s node set to %u\n", instp->name,instp->mynode);
-        instp->mynode = htonl(instp->mynode);
         ast_log(LOG_NOTICE, "Echolink/%s call set to %s\n",instp->name,instp->mycall);
         ast_log(LOG_NOTICE, "Echolink/%s name set to %s\n",instp->name,instp->myname);
         ast_log(LOG_NOTICE, "Echolink/%s file for recording set to %s\n",instp->name, instp->fdr_file);




More information about the asterisk-commits mailing list