[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