[asterisk-commits] jdixon: branch jdixon/chan_usbradio-1.4 r139864 - /team/jdixon/chan_usbradio-...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Aug 25 13:45:44 CDT 2008
Author: jdixon
Date: Mon Aug 25 13:45:44 2008
New Revision: 139864
URL: http://svn.digium.com/view/asterisk?view=rev&rev=139864
Log:
Fixed directory download and segfault on re-connect bug
Modified:
team/jdixon/chan_usbradio-1.4/dev-1.0/channels/chan_echolink.c
Modified: team/jdixon/chan_usbradio-1.4/dev-1.0/channels/chan_echolink.c
URL: http://svn.digium.com/view/asterisk/team/jdixon/chan_usbradio-1.4/dev-1.0/channels/chan_echolink.c?view=diff&rev=139864&r1=139863&r2=139864
==============================================================================
--- team/jdixon/chan_usbradio-1.4/dev-1.0/channels/chan_echolink.c (original)
+++ team/jdixon/chan_usbradio-1.4/dev-1.0/channels/chan_echolink.c Mon Aug 25 13:45:44 2008
@@ -31,7 +31,7 @@
/*** MODULEINFO
***/
-/* Version 0.9, 08/23/2008
+/* Version 0.10, 08/25/2008
Echolink channel driver for Asterisk/app_rpt.
A lot more has to be added,
Here is what comes to mind first:
@@ -98,6 +98,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
+#include <zlib.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
@@ -142,8 +143,12 @@
static const char tdesc[] = "Echolink channel driver by KI4LKF";
static int prefformat = AST_FORMAT_GSM;
static char type[] = "echolink";
-char db_active = 'a';
-char db_loading = 0;
+static char db_active = 'a';
+static char db_loading = 0;
+static char snapshot_id[50] = {'0',0};
+static int el_net_get_index = 0;
+static int el_net_get_nread = 0;
+
/* Echolink audio packet heafer */
struct gsmVoice_t {
@@ -244,6 +249,7 @@
int txindex;
struct el_rxqast rxqast;
struct el_rxqel rxqel;
+ char firstsent;
char firstheard;
struct ast_dsp *dsp;
struct ast_module_user *u;
@@ -296,6 +302,7 @@
} r;
};
+int debug = 0;
struct el_instance *instances[EL_MAX_INSTANCES];
int ninstances = 0;
@@ -576,8 +583,8 @@
}
/* When we call, it just works, really, there's no destination... Just
ring the phone and wait for someone to answer */
- if (option_debug)
- ast_log(LOG_DEBUG, "Calling %s on %s\n", dest, ast->name);
+// if (option_debug)
+ ast_log(LOG_NOTICE, "Calling %s on %s\n", dest, ast->name);
if (*dest) /* if number specified */
{
char *str,*cp;
@@ -681,7 +688,11 @@
if (!instp->confmode)
{
- ast_log(LOG_NOTICE,"Sent bye to IP address %s\n",p->ip);
+ if (debug) ast_log(LOG_DEBUG,"Sent bye to IP address %s\n",p->ip);
+ ast_mutex_lock(&instp->lock);
+ strcpy(instp->el_node_test.ip,p->ip);
+ find_delete(&instp->el_node_test);
+ ast_mutex_unlock(&instp->lock);
n = rtcp_make_bye(bye,"disconnected");
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(p->ip);
@@ -917,7 +928,7 @@
found_key = (struct el_node **)tfind(key, &el_node_list, compare_ip);
if (found_key) {
- ast_log(LOG_NOTICE,"...removing %s(%s)\n", (*found_key)->call, (*found_key)->ip);
+ if (debug) ast_log(LOG_DEBUG,"...removing %s(%s)\n", (*found_key)->call, (*found_key)->ip);
found = 1;
if (!(*found_key)->instp->confmode)
ast_softhangup((*found_key)->chan,AST_SOFTHANGUP_DEV);
@@ -1055,6 +1066,24 @@
char buf[GSM_FRAME_SIZE + AST_FRIENDLY_OFFSET];
if (frame->frametype != AST_FRAME_VOICE) return 0;
+
+ if (!p->firstsent)
+ {
+ struct sockaddr_in sin;
+ unsigned char sdes_packet[256];
+ int sdes_length;
+
+ p->firstsent = 1;
+ memset(sdes_packet,0,sizeof(sdes_packet));
+ sdes_length = rtcp_make_sdes(sdes_packet,sizeof(sdes_packet),
+ instp->mycall,instp->myname);
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(instp->ctrl_port);
+ sin.sin_addr.s_addr = inet_addr(p->ip);
+ sendto(instp->ctrl_sock, sdes_packet, sdes_length,
+ 0,(struct sockaddr *)&sin,sizeof(sin));
+ }
/* Echolink to Asterisk */
if (p->rxqast.qe_forw != &p->rxqast) {
@@ -1436,25 +1465,86 @@
return 0;
}
-static int net_get_line(int s,char *str, int max)
-{
-static int index = 0;
-static int nread = 0;
+#define EL_DIRECTORY_PORT 5200
+#define EL_DB_ROOT "echolink"
+
+
+static void el_zapem(char loading)
+{
+char str[10];
+
+ str[0] = loading;
+ str[1] = 0;
+ ast_db_deltree(EL_DB_ROOT,str);
+}
+
+static void el_zapcall(char loading,char *call)
+{
+char node[50],ipaddr[50],str[150],dbstr[50];
+
+ sprintf(dbstr,"%c/call/%s",loading,call);
+ if (ast_db_get(EL_DB_ROOT,dbstr,str,sizeof(str) - 1)) return;
+ if (sscanf(str,"%s:%s",node,ipaddr) != 2) return;
+ ast_log(LOG_NOTICE,"Zapped %s\n",dbstr);
+ sprintf(dbstr,"%c/node/%s",loading,node);
+ ast_db_del(EL_DB_ROOT,dbstr);
+ sprintf(dbstr,"%c/ipaddr/%s",loading,ipaddr);
+ ast_db_del(EL_DB_ROOT,dbstr);
+ return;
+}
+
+static int el_net_read(int sock,unsigned char *buf1,int buf1len,
+ int compressed,struct z_stream_s *z)
+{
+unsigned char buf[512];
+int n,i,r;
+
+ if (!compressed)
+ {
+ n = recv(sock,buf1,buf1len - 1,0);
+ if (n < 1) return(-1);
+ return(n);
+ }
+ memset(buf1,0,buf1len);
+ memset(buf,0,sizeof(buf));
+ n = recv(sock,buf,sizeof(buf) - 1,0);
+ if (n < 1) return(-1);
+ z->next_in = buf;
+ z->avail_in = n;
+ z->next_out = buf1;
+ z->avail_out = buf1len;
+ i = Z_NO_FLUSH;
+ if (n < (sizeof(buf) - 1)) i = Z_FINISH;
+ r = inflate(z,i);
+ if ((r != Z_OK) && (r != Z_STREAM_END))
+ {
+ if (z->msg)
+ fprintf(stderr,"Unable to inflate (Zlib): %s\n",z->msg);
+ else
+ fprintf(stderr,"Unable to inflate (Zlib)\n");
+ return -1;
+ }
+ return(buf1len - z->avail_out);
+}
+
+static int el_net_get_line(int s,char *str, int max, int compressed,
+ struct z_stream_s *z)
+{
int nstr;
-static unsigned char buf[1024];
+static unsigned char buf[2048];
unsigned char c;
nstr = 0;
for(;;)
{
- if (index >= nread)
- {
- index = 0;
- nread = recv(s,buf,sizeof(buf) - 1,0);
- if ((nread) < 1) return(nread);
- }
- if (buf[index] > 126) buf[index] = ' ';
- c = buf[index++];
+ if (el_net_get_index >= el_net_get_nread)
+ {
+ el_net_get_index = 0;
+ el_net_get_nread = el_net_read(s,buf,sizeof(buf),compressed,z);
+ if ((el_net_get_nread) < 1) return(el_net_get_nread);
+ }
+ if (buf[el_net_get_index] > 126) buf[el_net_get_index] = ' ';
+ c = buf[el_net_get_index++];
str[nstr++] = c & 0x7f;
str[nstr] = 0;
if (c < ' ') break;
@@ -1463,26 +1553,17 @@
return(nstr);
}
-#define EL_DIRECTORY_PORT 5200
-#define EL_DB_ROOT "echolink"
-
-
-static void el_zapem(char loading)
-{
-char str[10];
-
- str[0] = loading;
- str[1] = 0;
- ast_db_deltree(EL_DB_ROOT,str);
-}
-
static int do_el_directory(char *hostname)
{
struct ast_hostent ah;
struct hostent *host;
struct sockaddr_in dirserver;
char str[200],dbstr[100],ipaddr[50],nodenum[50];
-int sock,n = 0;
+char dbstr1[100],call[50];
+int n = 0,rep_lines,delmode;
+int dir_compressed,dir_partial;
+struct z_stream_s z;
+int sock;
db_active = 'a';
db_loading = 'a';
@@ -1493,7 +1574,18 @@
db_active = *str;
if (db_active == 'a') db_loading = 'b';
}
- if (sendcmd(hostname,instances[0])) return -1;
+ sendcmd(hostname,instances[0]);
+ el_net_get_index = 0;
+ el_net_get_nread = 0;
+ memset(&z,0,sizeof(z));
+ if (inflateInit(&z) != Z_OK)
+ {
+ if (z.msg)
+ fprintf(stderr,"Unable to init Zlib: %s\n",z.msg);
+ else
+ fprintf(stderr,"Unable to init Zlib\n");
+ return -1;
+ }
host = ast_gethostbyname(hostname,&ah);
if (!host)
{
@@ -1518,30 +1610,104 @@
ast_log(LOG_NOTICE,"Unable to connect to directory server %s\n",hostname);
return -1;
}
- strcpy(str,"s\n");
+ sprintf(str,"F%s\r",snapshot_id);
if (send(sock,str,strlen(str),0) < 0)
{
ast_log(LOG_NOTICE,"Unable to send to directory server %s\n",hostname);
return -1;
}
- if ((net_get_line(sock,str,sizeof(str) - 1) < 1) ||
- (net_get_line(sock,str,sizeof(str) - 1) < 1))
+ str[strlen(str) - 1] = 0;
+printf("Sending: %s to %s\n",str,hostname);
+ if (recv(sock,str,4,0) != 4)
{
ast_log(LOG_NOTICE,"Error in directory download (header) on %s\n",hostname);
return -1;
- }
- el_zapem(db_loading);
+ }
+ dir_compressed = 1;
+ dir_partial = 0;
+ if (!strncmp(str,"@@@",3))
+ {
+ dir_partial = 0;
+ dir_compressed = 0;
+ }
+ else if (!strncmp(str,"DDD",3))
+ {
+ dir_partial = 1;
+ dir_compressed = 0;
+ }
+ if (dir_compressed)
+ {
+ if (el_net_get_line(sock,str,sizeof(str) - 1,dir_compressed,&z) < 1)
+ {
+ ast_log(LOG_NOTICE,"Error in directory download (header) on %s\n",hostname);
+ return -1;
+ }
+printf("Line is: %s len %d\n",str,strlen(str));
+ if (!strncmp(str,"@@@",3))
+ {
+ dir_partial = 0;
+ }
+ else if (!strncmp(str,"DDD",3))
+ {
+ dir_partial = 1;
+ }
+ else
+ {
+ ast_log(LOG_NOTICE,"Error in header on %s\n",hostname);
+ return -1;
+ }
+ }
+ if (el_net_get_line(sock,str,sizeof(str) - 1,dir_compressed,&z) < 1)
+ {
+ ast_log(LOG_NOTICE,"Error in directory download (header) on %s\n",hostname);
+ return -1;
+ }
+ if (dir_compressed)
+ {
+ if(sscanf(str,"%d:%s",&rep_lines,snapshot_id) < 2)
+ {
+ ast_log(LOG_NOTICE,"Error in parsing header on %s\n",hostname);
+ return -1;
+ }
+ }
+ else
+ {
+ if(sscanf(str,"%d",&rep_lines) < 1)
+ {
+ ast_log(LOG_NOTICE,"Error in parsing header on %s\n",hostname);
+ return -1;
+ }
+ }
+ if (dir_partial) db_loading = db_active;
+ else el_zapem(db_loading);
+ delmode = 0;
for(;;)
{
- if (net_get_line(sock,str,sizeof(str) - 1) < 1) break;
+ if (el_net_get_line(sock,str,sizeof(str) - 1,dir_compressed,&z) < 1) break;
if (*str <= ' ') break;
- if (net_get_line(sock,str,sizeof(str) - 1) < 1)
+
+ if (!strncmp(str,"+++",3))
+ {
+ if (delmode) break;
+ if (!dir_partial) break;
+ delmode = 1;
+ continue;
+ }
+ if (str[strlen(str) - 1] == '\n')
+ str[strlen(str) - 1] = 0;
+ strncpy(call,str,sizeof(call) - 1);
+ if (dir_partial)
+ {
+ el_zapcall(db_loading,call);
+ if (delmode) continue;
+ }
+ if (el_net_get_line(sock,str,sizeof(str) - 1,dir_compressed,&z) < 1)
{
ast_log(LOG_NOTICE,"Error in directory download on %s\n",hostname);
el_zapem(db_loading);
return -1;
}
- if (net_get_line(sock,str,sizeof(str) - 1) < 1)
+ if (el_net_get_line(sock,str,sizeof(str) - 1,dir_compressed,&z) < 1)
{
ast_log(LOG_NOTICE,"Error in directory download on %s\n",hostname);
el_zapem(db_loading);
@@ -1550,7 +1716,7 @@
if (str[strlen(str) - 1] == '\n')
str[strlen(str) - 1] = 0;
strncpy(nodenum,str,sizeof(nodenum) - 1);
- if (net_get_line(sock,str,sizeof(str) - 1) < 1)
+ if (el_net_get_line(sock,str,sizeof(str) - 1,dir_compressed,&z) < 1)
{
ast_log(LOG_NOTICE,"Error in directory download on %s\n",hostname);
el_zapem(db_loading);
@@ -1571,6 +1737,13 @@
ast_log(LOG_NOTICE,"Error in putting nodenum record %s (ipaddr %s)",nodenum,ipaddr);
return -1;
}
+ sprintf(dbstr,"%c/call/%s",db_loading,call);
+ sprintf(dbstr1,"%s:%s",nodenum,ipaddr);
+ if (ast_db_put(EL_DB_ROOT,dbstr,dbstr1))
+ {
+ ast_log(LOG_NOTICE,"Error in putting call record %s (ipaddr %s)",nodenum,ipaddr);
+ return -1;
+ }
n++;
}
db_active = db_loading;
@@ -1582,44 +1755,39 @@
ast_log(LOG_NOTICE,"Error in finalizing DB process on %s\n",hostname);
return -1;
}
-
+ close(sock);
ast_log(LOG_NOTICE,"Diretory pgm done downloading, %d records\n",n);
- return 0;
+ printf("Compressed: %d, Partial: %d\n",dir_compressed,dir_partial);
+ if (dir_compressed) printf("Got snapshot_id: %s\n",snapshot_id);
+ return(dir_compressed);
}
static void *el_directory(void *data)
{
- short i = 0;
- int rc = 0;
-
- while (run_forever)
- {
- if (i >= EL_MAX_SERVERS)
- i = 0;
-
- do {
- if (instances[0]->elservers[i][0] != '\0')
- break;
- i++;
- } while (i < EL_MAX_SERVERS);
-
- if (i < EL_MAX_SERVERS) {
- ast_log(LOG_NOTICE, "Trying to register with Echolink server %s\n", instances[0]->elservers[i]);
- rc = do_el_directory(instances[0]->elservers[i++]);
- }
- if (rc == 0)
- sleep(1800);
- else
- sleep(20);
- }
- /*
- Send a de-register message, but what is the point,
- Echolink deactivates this node within 6 minutes
- */
- ast_log(LOG_NOTICE, "Echolink directory thread exited.\n");
- pthread_exit(NULL);
-}
-
+ int rc = 0,curdir;
+
+ curdir = 0;
+ while (run_forever)
+ {
+ if (!instances[0]->elservers[curdir][0])
+ {
+ if (++curdir >= EL_MAX_SERVERS) curdir = 0;
+ continue;
+ }
+ ast_log(LOG_NOTICE, "Trying to do directory downloa Echolink server %s\n", instances[0]->elservers[curdir]);
+ rc = do_el_directory(instances[0]->elservers[curdir]);
+ if (rc < 0)
+ {
+ if (++curdir >= EL_MAX_SERVERS) curdir = 0;
+ sleep(20);
+ continue;
+ }
+ if (rc == 1) sleep(240);
+ else if (rc == 0) sleep(1800);
+ }
+ ast_log(LOG_NOTICE, "Echolink directory thread exited.\n");
+ pthread_exit(NULL);
+}
static void *el_register(void *data)
{
@@ -1827,7 +1995,7 @@
fr.delivery.tv_sec = 0;
fr.delivery.tv_usec = 0;
ast_queue_frame((*found_key)->chan,&fr);
- ast_log(LOG_NOTICE,"Channel %s answering\n",
+ if (debug) ast_log(LOG_DEBUG,"Channel %s answering\n",
(*found_key)->chan->name);
}
(*found_key)->countdown = instp->rtcptimeout;
More information about the asterisk-commits
mailing list