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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Feb 10 14:00:57 CST 2009


Author: jdixon
Date: Tue Feb 10 14:00:57 2009
New Revision: 174707

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=174707
Log:
More stuff added to chan_irlp.. completely un-tangled from Cameron distribution now

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

Modified: team/jdixon/chan_usbradio-1.4/channels/chan_irlp.c
URL: http://svn.digium.com/svn-view/asterisk/team/jdixon/chan_usbradio-1.4/channels/chan_irlp.c?view=diff&rev=174707&r1=174706&r2=174707
==============================================================================
--- team/jdixon/chan_usbradio-1.4/channels/chan_irlp.c (original)
+++ team/jdixon/chan_usbradio-1.4/channels/chan_irlp.c Tue Feb 10 14:00:57 2009
@@ -31,10 +31,7 @@
 /*** MODULEINFO
  ***/
 
-#define	rpt_free(p) __ast_free(p,__FILE__,__LINE__,__PRETTY_FUNCTION__)
-
-
-/* Version 0.19, 2/8/2009
+/* Version 0.20, 2/10/2009
 irlp channel driver for Asterisk/app_rpt.
 
 I wish to thank the following people for the immeasurable amount of
@@ -80,6 +77,7 @@
 #include "asterisk/app.h"
 #include "asterisk/translate.h"
 #include "asterisk/cli.h"
+#include "asterisk/astdb.h"
 
 #define	MAX_RXKEY_TIME 4
 
@@ -103,6 +101,9 @@
 
 #define	LARGEST_PACKET_SIZE 1024
 #define	DISC_LINGER_TIME 2
+#define IRLP_DB_ROOT "irlp"
+
+#ifdef	STNTYPE
 #define	IRLP_ROOT "/home/irlp/local"
 #define	IRLP_RESET "su - repeater /tmp/irlpwrap /home/irlp/custom/irlp_fullreset"
 #define	IRLP_END "su - repeater /tmp/irlpwrap /home/irlp/scripts/end &"
@@ -118,6 +119,10 @@
 	"/bin/mknod /home/irlp/astrun/dtmf_fifo p;" \
 	"chown repeater /home/irlp/astrun/dtmf_fifo) > /dev/null 2>&1"
 #define	IRLP_SEND_DTMF "su - repeater /tmp/irlpwrap \"/home/irlp/scripts/fifoecho stn%04d dtmfregen %s\""
+#endif
+
+#define	DELIMCHR ':'
+#define	QUOTECHR 34
 
 enum {IRLP_NOPROTO,IRLP_ISADPCM,IRLP_ISGSM,IRLP_ISULAW} ;
 
@@ -227,13 +232,14 @@
 static uint16_t audio_port;
 static uint16_t ctrl_port;
 static char *config = "irlp.conf";
-static const char tdesc[] = "irlp channel driver by KI4LKF";
+static const char tdesc[] = "irlp channel driver";
 static int prefformat = AST_FORMAT_ADPCM;
 static char context[AST_MAX_EXTENSION] = "default";
 static char type[] = "irlp";
 static pthread_t irlp_reader_thread;
 static int run_forever = 1;
 static int proto = IRLP_NOPROTO;
+static int default_proto = IRLP_ISULAW;
 static int in_node = 0;
 static struct irlp_rxqast rxqast;
 static char *outbuf_old;
@@ -245,12 +251,16 @@
 static char stream[256];
 static int nullfd = -1;
 static int dfd = -1;
+#ifdef	STNTYPE
 static int playing = 0;
+#endif
 static unsigned int xcount = 0;
 static char havedtmf = 0;
 static char irlp_dtmf_string[64];
 static char irlp_dtmf_special = 0;
 time_t keepalive = 0;
+static char db_active = 'a';
+static char db_loading = 0;
 
 #ifdef OLD_ASTERISK
 #define ast_free free
@@ -293,7 +303,11 @@
 	alt_audio_sock = -1;
 	if (alt_ctrl_sock != -1) close(alt_ctrl_sock);
 	alt_ctrl_sock = -1;
+#ifdef	STNTYPE
 	proto = IRLP_NOPROTO;
+#else
+	proto = default_proto;
+#endif
 	time(&lingertime);
 	keepalive = 0;
 	in_node = 0;
@@ -319,6 +333,7 @@
 }
 
 
+#ifdef	STNTYPE
 static char *irlp_read_file(char *basename,char *fname)
 {
 char s[200],*str;
@@ -326,9 +341,6 @@
 int  len;
 struct stat mystat;
 
-#ifndef	STNTYPE
-	return(NULL);
-#endif
 	snprintf(s,sizeof(s) - 1,"%s/%s",basename,fname);
 	fp = fopen(s,"r");
 	if (!fp) return(NULL);
@@ -354,34 +366,221 @@
 	str[len] = 0;
 	return(str);
 }
+#endif
 
 #ifndef	STNTYPE
 
 static char *irlp_get_node(char *ip)
 {
-	FILE *fp = NULL;
-	char myip[100],mystn[100];
-
-	fp = fopen("/home/irlp/local/hosts","r");
-	if (!fp)
-	{
-		ast_log(LOG_ERROR,"Cannot open hosts file\n");
-		reset_stuff();
-		if ((!radmode) && curcall) ast_softhangup(curcall,AST_SOFTHANGUP_DEV);
-		return(NULL);
-	}
-	while(fscanf(fp,"%s %s",mystn,myip) == 2)
-	{
-		if (strcasecmp(myip,ip)) continue;
+
+char active = 'a',str[200],dbstr[200];
+
+	if (!ast_db_get(IRLP_DB_ROOT,"active",str,sizeof(str) - 1))
+	{
+		active = *str;
+	}
+
+	sprintf(dbstr,"%c/ipaddr/%s",active,ip);
+	if (!ast_db_get(IRLP_DB_ROOT,dbstr,str,sizeof(str) - 1))
+	{
+		return(strdup(str));
+	}
+	return(NULL);
+}
+
+static char *irlp_get_ip(char *nodenum)
+{
+
+char active = 'a',str[200],dbstr[200];
+
+	if (!ast_db_get(IRLP_DB_ROOT,"active",str,sizeof(str) - 1))
+	{
+		active = *str;
+	}
+
+	sprintf(dbstr,"%c/nodenum/%s",active,nodenum);
+	if (!ast_db_get(IRLP_DB_ROOT,dbstr,str,sizeof(str) - 1))
+	{
+		return(strdup(str));
+	}
+	return(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);
+
+}
+
+/* IRLP db load stuff */
+static void irlp_zapem(char loading)
+{
+char str[10];
+
+	str[0] = loading;
+	str[1] = 0;
+	ast_db_deltree(IRLP_DB_ROOT,str);
+}
+
+static int do_irlp_dbload(void)
+{
+char	str[200],mystn[200],myip[200],dbstr[300];
+char	*strs[100];
+int	n = 0;
+FILE	*fp;
+struct ast_hostent ahp;
+struct hostent *hp;
+struct in_addr ia;
+
+	db_active = 'a';
+	db_loading = 'a';
+	if (!ast_db_get(IRLP_DB_ROOT,"active",str,sizeof(str) - 1))
+	{
+		db_active = *str;
+		if (db_active == 'a') db_loading = 'b';
+	}
+	irlp_zapem(db_loading);
+	fp = fopen("/var/lib/asterisk/irlphosts","r");
+	if (fp)
+	{
+		while(fgets(str,sizeof(str) - 1,fp))
+		{
+			if (!str[0]) continue;
+			if (str[strlen(str) - 1] == '\n')
+				str[strlen(str) - 1] = 0;
+			if (!str[0]) continue;
+			if (str[0] < '0') continue;
+			if (str[0] > '9') continue;
+			if (sscanf(str,"%s %s",myip,mystn) != 2) continue;
+			sprintf(dbstr,"%c/ipaddr/%s",db_loading,myip);
+			usleep(2000); /* To get to dry land */
+			if (ast_db_put(IRLP_DB_ROOT,dbstr,mystn) != 0)
+			{
+				ast_log(LOG_ERROR,"Error in putting ipaddr record %s (nodenum %s)",myip,mystn);
+				fclose(fp);
+				return -1;
+			}
+			sprintf(dbstr,"%c/nodenum/%s",db_loading,mystn);
+			usleep(2000); /* To get to dry land */
+			if (ast_db_put(IRLP_DB_ROOT,dbstr,myip))
+			{
+	 			ast_log(LOG_ERROR,"Error in putting nodenum record %s (ipaddr %s)",mystn,myip);
+				fclose(fp);
+				return -1;
+			}
+			n++;
+		}
 		fclose(fp);
-		return(strdup(mystn));
-	}
-	fclose(fp);
-	return(NULL);
-}
-
-#endif
-
+	}
+	fp = fopen("/var/lib/asterisk/exp-x-reference","r");
+	if (fp)
+	{
+		while(fgets(str,sizeof(str) - 1,fp))
+		{
+			if (!str[0]) continue;
+			if (str[strlen(str) - 1] == '\n')
+				str[strlen(str) - 1] = 0;
+			if (!str[0]) continue;
+			if (strncasecmp(str,"exp",3)) continue;
+			if(finddelim(str,strs,100) != 5) continue;
+			hp = ast_gethostbyname(strs[1], &ahp);
+			if (!hp)
+			{
+				ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",strs[1]);
+				continue;
+			}
+			memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
+#ifdef	OLD_ASTERISK
+			ast_inet_ntoa(myip,sizeof(myip) - 1,ia);
+#else
+			strncpy(myip,ast_inet_ntoa(ia),sizeof(myip) - 1);
+#endif
+			sprintf(dbstr,"%c/ipaddr/%s",db_loading,myip);
+			usleep(2000); /* To get to dry land */
+			if (ast_db_put(IRLP_DB_ROOT,dbstr,strs[0]) != 0)
+			{
+				ast_log(LOG_ERROR,"Error in putting ipaddr record %s (nodenum %s)",strs[1],strs[0]);
+				fclose(fp);
+				return -1;
+			}
+			sprintf(dbstr,"%c/nodenum/%s",db_loading,strs[0]);
+			usleep(2000); /* To get to dry land */
+			if (ast_db_put(IRLP_DB_ROOT,dbstr,myip))
+			{
+	 			ast_log(LOG_ERROR,"Error in putting nodenum record %s (ipaddr %s)",strs[0],strs[1]);
+				fclose(fp);
+				return -1;
+			}
+			snprintf(myip,sizeof(myip) - 1,"%s:%s:%s",strs[2],strs[3],strs[4]);
+			snprintf(dbstr,sizeof(dbstr) - 1,"%c/params/%s",db_loading,strs[0]);
+			usleep(2000); /* To get to dry land */
+			if (ast_db_put(IRLP_DB_ROOT,dbstr,myip) != 0)
+			{
+				ast_log(LOG_ERROR,"Error in putting params record %s (nodenum %s)",myip,strs[0]);
+				fclose(fp);
+				return -1;
+			}
+			n++;
+		}
+		fclose(fp);
+	}
+	db_active = db_loading;
+	db_loading = 0;
+	dbstr[0] = db_active;
+	dbstr[1] = 0;
+	if (ast_db_put(IRLP_DB_ROOT,"active",dbstr) != 0)
+	{
+		ast_log(LOG_ERROR,"Error in finalizing DB process\n");
+		return -1;
+	}
+	ast_log(LOG_NOTICE,"IRLP databasse load done %d records\n",n);
+	return(0);
+}
+
+#endif
 
 static int is_rtcp_bye(unsigned char *p, int len)
 {
@@ -543,18 +742,22 @@
 
 static void send_bye(char *reason)
 {
-char	buf[200],*cp,ipbuf[100];
+char	buf[200],ipbuf[100];
 int	len,x;
 struct sockaddr_in sin;
 
 	if (!*remote_irlp_node_ip)
 	{
+#ifdef	STNTYPE
+		char *cp;
+
 		cp = irlp_read_file(IRLP_ROOT,"calledip");
 		if (!cp) return;
 		if (cp[strlen(cp) - 1] == '\n')
 			cp[strlen(cp) - 1] = 0;
 		strncpy(ipbuf,cp,sizeof(ipbuf) - 1);
 		ast_free(cp);
+#endif
 	}
 	else
 	{
@@ -584,6 +787,7 @@
 	len = rtcp_make_bye((unsigned char *)buf,reason);
 	for(x = 0; x < 1; x++)
 	{	
+printf("foop: sending bye to %s\n",ipbuf);
 	        sendto((alt_ctrl_sock != -1) ? alt_ctrl_sock : ctrl_sock,buf,len,
         	        0,(struct sockaddr *)&sin,sizeof(struct sockaddr));
 	}
@@ -592,18 +796,22 @@
 
 static void send_keepalive(void)
 {
-char	buf[200],*cp;
+char	buf[200];
 int	len;
 struct sockaddr_in sin;
 
 	if (!*remote_irlp_node_ip)
 	{
+#ifdef	STNTYPE
+		char *cp;
+
 		cp = irlp_read_file(IRLP_ROOT,"calledip");
 		if (!cp) return;
 		if (cp[strlen(cp) - 1] == '\n')
 			cp[strlen(cp) - 1] = 0;
 		strncpy(buf,cp,sizeof(buf) - 1);
 		ast_free(cp);
+#endif
 	}
 	else
 	{
@@ -641,7 +849,9 @@
 static int irlp_call(struct ast_channel *ast, char *dest, int timeout)
 {
 	struct irlp_pvt *p;
-	char *cp,str[100];
+	char *cp,str[300];
+	int len;	
+	struct sockaddr_in sin;
 
 	p = ast->tech_pvt;
 
@@ -649,6 +859,7 @@
 		ast_log(LOG_WARNING, "irlp_call called on %s, neither down nor reserved\n", ast->name);
 		return -1;
 	}
+#ifdef	STNTYPE
 	cp = irlp_read_file(IRLP_ROOT,"active");
 	if (cp && *cp) 
 	{
@@ -665,7 +876,28 @@
 		ast_safe_system(str);
 		usleep(10000);
 	}		
-
+#else
+	if (nodenum > 999)
+	{
+		ast_log(LOG_WARNING, "irlp_call called invalid node %04d on %s\n", nodenum,ast->name);
+		return -1;
+	}
+	sprintf(str,"exp%04d",nodenum);
+	cp = irlp_get_ip(str);
+	if (!cp)
+	{
+		ast_log(LOG_WARNING, "irlp_call called unknown node %04d on %s\n", nodenum,ast->name);
+		return -1;
+	}
+printf("foop: calling node %s on %s\n",str,cp);
+        sin.sin_family = AF_INET;
+        sin.sin_addr.s_addr = inet_addr(cp);
+        sin.sin_port = htons(tx_audio_port + 1);
+	len = rtcp_make_sdes((unsigned char *)str,sizeof(str) - 1);
+        sendto((alt_ctrl_sock != -1) ? alt_ctrl_sock : ctrl_sock,str,len,
+                0,(struct sockaddr *)&sin,sizeof(struct sockaddr));
+
+#endif
 	ast_setstate(ast,(radmode) ? AST_STATE_UP : AST_STATE_RINGING);
 	return 0;
 }
@@ -680,7 +912,11 @@
 
 static void process_codec_file(struct ast_channel *ast)
 {
-	char *cp;
+#ifndef	STNTYPE
+	return;
+#else
+
+	  char *cp;
 
 	  if (!ready) return;
 	  cp = irlp_read_file(IRLP_ROOT,"codec");
@@ -719,6 +955,7 @@
 		  ast_free(cp);
 	  }
 	  return;
+#endif
 }
 
 
@@ -727,7 +964,7 @@
 
 	fd_set fds[3];
 	struct timeval tmout;
-	int i,myaud,myctl,x,was_outbound,seen_curcall;
+	int i,myaud,myctl,x,seen_curcall;
 
 	char buf[LARGEST_PACKET_SIZE + 1];
 	struct sockaddr_in sin;
@@ -736,14 +973,17 @@
         socklen_t fromlen;
 	ssize_t recvlen;
         size_t len;
-	struct stat statbuf;
-	static int play_outbound = 0;
 	time_t now;
 
 	ast_log(LOG_NOTICE, "IRLP reader thread started.\n");
 	seen_curcall = 0;
 	while(run_forever)
 	{
+#ifdef	STNTYPE
+		int was_outbound;
+		struct stat statbuf;
+		static int play_outbound = 0;
+
 		if ((proto == IRLP_NOPROTO) && curcall) process_codec_file(curcall);
 		i = ((stat(IRLP_PLAY_FILE,&statbuf) != -1));
 		if (i != playing)
@@ -765,6 +1005,7 @@
 			}
 			playing = i;
 		}
+#endif
 		myaud = (alt_audio_sock != -1) ? alt_audio_sock : audio_sock;
 		myctl = (alt_ctrl_sock != -1) ? alt_ctrl_sock : ctrl_sock;
 
@@ -868,7 +1109,7 @@
 				   else 
 				  {
 					ast_log(LOG_NOTICE,"irlp node attempted connect from %s with no node info\n", ip);
-					send_bye("un-authorized");
+					send_bye_ip("un-authorized",ip);
 				  }
 				  if (cp) ast_free(cp);
 	                       }
@@ -1033,7 +1274,7 @@
 		if ((!radmode) && args.nodenum && *args.nodenum)
 		{
 			nodenum = atoi(args.nodenum);
-			if ((nodenum < 1000) || (nodenum > 9999))
+			if ((nodenum < 10) || (nodenum > 9999))
 			{
 				ast_log(LOG_ERROR,"Requested node number %s invalid\n",args.nodenum);
 				ast_free(p);
@@ -1106,7 +1347,9 @@
 		ast->tech_pvt = NULL;
 		ast_setstate(ast, AST_STATE_DOWN);
 	}
+#ifdef	STNTYPE
 	ast_safe_system(IRLP_END);
+#endif
 	send_bye("disconnected");
 	return 0;
 }
@@ -1207,9 +1450,12 @@
         char outbuf[ULAW_FRAME_SIZE + AST_FRIENDLY_OFFSET + 3]; /* turns out that ADPCM is larger */
         struct irlp_audio irlp_audio_packet;
         static char tx_buf[(ADPCM_BLOCKING_FACTOR * ADPCM_FRAME_SIZE) + 3]; /* turns out the ADPCM is larger */
-	char *outbuf_new,*cp,c,str[200];
+	char *outbuf_new,*cp,c;
         unsigned char *dp;
 	static int lasttx = 0;
+#ifdef	STNTYPE
+	char str[200];
+#endif
 
 	if (ast->_state != AST_STATE_UP) 
            return 0;
@@ -1429,8 +1675,10 @@
 					irlp_dtmf_string[i] = 'P';
 				}
 			}
+#ifdef	STNTYPE
 			sprintf(str,IRLP_SEND_DTMF,in_node,irlp_dtmf_string);
 			ast_safe_system(str);
+#endif
 			ast_log(LOG_NOTICE,"Sent DTMF %s to IRLP\n",irlp_dtmf_string);
 		}
 		irlp_dtmf_string[0] = 0;
@@ -1617,9 +1865,11 @@
 		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
 		return NULL;
 	}
+#ifdef	STNTYPE
 	unlink(IRLP_PLAY_FILE);
 	ast_safe_system(IRLP_RESET);
 	usleep(10000);
+#endif
 	reset_stuff();
 	p = irlp_alloc(data);
 	if (p) {
@@ -1630,6 +1880,21 @@
 	curcall = tmp;
 	return tmp;
 }
+
+static int irlp_cli_do_dbload(int fd, int argc, char *argv[])
+{
+	if (argc != 2) return RESULT_SHOWUSAGE;
+	do_irlp_dbload();
+	return RESULT_SUCCESS;
+}
+
+static char dbload_usage[] =
+"Usage: irlp dbload.\n"
+"       load irlp db.\n";
+
+static struct ast_cli_entry  cli_dbload =
+        { { "irlp", "dbload" }, irlp_cli_do_dbload,
+		"Load IRLP DB", dbload_usage };
 
 static int unload_module(void)
 {
@@ -1645,6 +1910,7 @@
 	alt_ctrl_sock = -1;
 	if (nullfd != -1) close(nullfd);
 	if (dfd != -1) close(dfd);
+	ast_cli_unregister(&cli_dbload);
 	/* First, take us out of the channel loop */
 	ast_channel_unregister(&irlp_tech);
 	return 0;
@@ -1671,7 +1937,9 @@
                 return AST_MODULE_LOAD_DECLINE;
         }
 
+#ifdef	STNTYPE
 	ast_safe_system(IRLP_WRAPPER);
+#endif
 
         /* some of these values can be copied from /home/irlp/custom/environment */
         val = (char *)ast_variable_retrieve(cfg,"general","rtcptimeout");
@@ -1719,14 +1987,24 @@
         else
            strncpy(context,val,sizeof(context) - 1);
 
+        val = (char *)ast_variable_retrieve(cfg,"general","codec");
+	if (val)
+	{
+		if (!strcasecmp(val,"GSM")) default_proto = IRLP_ISGSM;
+		else if (!strcasecmp(val,"ADPCM")) default_proto = IRLP_ISADPCM;
+		else if (!strcasecmp(val,"UNCOMP")) default_proto = IRLP_ISULAW;
+	}
+
         /* initialize local and remote IRLP node */
 	reset_stuff();
 	curcall = 0;
 
         ast_config_destroy(cfg);
 
+#ifdef	STNTYPE
 	ast_safe_system(IRLP_RESET);
 	usleep(10000);
+#endif
 
 	audio_port = audio_port_cfg;
 	if ((audio_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) 
@@ -1766,6 +2044,7 @@
         fcntl(ctrl_sock,F_SETFL,O_NONBLOCK);
 	nullfd = open("/dev/null",O_RDWR);
 
+#ifdef	STNTYPE
 	ast_safe_system(IRLP_MAKE_FIFO);
 	dfd = open(IRLP_DTMF_FIFO,O_RDONLY | O_NONBLOCK);
 	if (dfd == -1)
@@ -1777,8 +2056,10 @@
 	unlink(IRLP_PLAY_FILE);
 
 	usleep(100000);
+#endif
         cfg = NULL; 
 
+	ast_cli_register(&cli_dbload);
         pthread_attr_init(&attr);
         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
         ast_pthread_create(&irlp_reader_thread,&attr,irlp_reader,NULL);




More information about the asterisk-commits mailing list