[asterisk-commits] jdixon: branch jdixon/chan_usbradio-1.4 r139445 - /team/jdixon/chan_usbradio-...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Aug 22 03:25:49 CDT 2008
Author: jdixon
Date: Fri Aug 22 03:25:49 2008
New Revision: 139445
URL: http://svn.digium.com/view/asterisk?view=rev&rev=139445
Log:
More good stuff
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=139445&r1=139444&r2=139445
==============================================================================
--- 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 Fri Aug 22 03:25:49 2008
@@ -31,9 +31,8 @@
/*** MODULEINFO
***/
-/* Version 0.5, 08/21/2008
+/* Version 0.6, 08/22/2008
Echolink channel driver for Asterisk/app_rpt.
-This is a second attempt.
A lot more has to be added,
Here is what comes to mind first:
@@ -184,6 +183,7 @@
struct el_instance
{
+ ast_mutex_t lock;
char name[EL_NAME_SIZE + 1];
char mycall[EL_CALL_SIZE + 1];
char myname[EL_NAME_SIZE + 1];
@@ -241,6 +241,7 @@
struct el_rxqast rxqast;
struct el_rxqel rxqel;
char firstsent;
+ char firstheard;
struct ast_dsp *dsp;
struct ast_module_user *u;
struct ast_trans_pvt *xpath;
@@ -325,17 +326,17 @@
static void copy_sdes_item(char *source, char *dest, int destlen);
static int is_rtcp_bye(unsigned char *p, int len);
static int is_rtcp_sdes(unsigned char *p, int len);
-/* remove binary tree functions if Asterisk has similar functionality */
+ /* remove binary tree functions if Asterisk has similar functionality */
static int compare_ip(const void *pa, const void *pb);
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 print_users(const void *nodep, const VISIT which, const int depth);
static void free_node(void *nodep);
-static void process_cmd(char *buf, ssize_t recvlen, struct el_node *from,
- struct el_instance *instp);
+static void process_cmd(char *buf,char *fromip,struct el_instance *instp);
static int find_delete(struct el_node *key);
static int sendcmd(char *server,struct el_instance *instp);
+static int do_new_call(struct el_instance *instp, struct el_pvt *p, char *call, char *name);
/* remove writen if Asterisk has similar functionality */
static int writen(int fd, char *ptr, int nbytes);
@@ -559,9 +560,10 @@
static int el_call(struct ast_channel *ast, char *dest, int timeout)
{
- struct el_pvt *p;
-
- p = ast->tech_pvt;
+ struct el_pvt *p = ast->tech_pvt;
+ struct el_instance *instp = p->instp;
+ char buf[100];
+
if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
ast_log(LOG_WARNING, "el_call called on %s, neither down nor reserved\n", ast->name);
@@ -571,8 +573,22 @@
ring the phone and wait for someone to answer */
if (option_debug)
ast_log(LOG_DEBUG, "Calling %s on %s\n", dest, ast->name);
-
- ast_setstate(ast,AST_STATE_UP);
+ if (*dest) /* if number specified */
+ {
+ char *str,*cp;
+
+ str = strdup(dest);
+ cp = strchr(str,'/');
+ if (cp) *cp++ = 0; else cp = str;
+ snprintf(buf,sizeof(buf) - 1,"o.conip %s",cp);
+ free(str);
+ ast_mutex_lock(&instp->lock);
+ strcpy(instp->el_node_test.ip,cp);
+ do_new_call(instp,p,"OUTBOUND","OUTBOUND");
+// process_cmd(buf,"127.0.0.1",instp);
+ ast_mutex_unlock(&instp->lock);
+ }
+ ast_setstate(ast,AST_STATE_RINGING);
return 0;
}
@@ -603,7 +619,11 @@
{
if (!strcmp(instances[n]->name,args.idstr)) break;
}
- if (n >= ninstances) return NULL;
+ if (n >= ninstances)
+ {
+ ast_log(LOG_NOTICE,"Cannot find echolink channel %s\n",args.idstr);
+ return NULL;
+ }
p = ast_malloc(sizeof(struct el_pvt));
if (p) {
@@ -656,6 +676,7 @@
if (!instp->confmode)
{
+ ast_log(LOG_NOTICE,"Sent bye to IP address %s\n",p->ip);
n = rtcp_make_bye(bye,"disconnected");
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(p->ip);
@@ -665,7 +686,6 @@
sendto(instp->ctrl_sock, bye, n,
0,(struct sockaddr *)&sin,sizeof(sin));
}
- ast_log(LOG_NOTICE,"Sent bye to IP address %s\n",p->ip);
}
if (option_debug)
ast_log(LOG_DEBUG, "el_hangup(%s)\n", ast->name);
@@ -872,8 +892,7 @@
return found;
}
-static void process_cmd(char *buf, ssize_t recvlen, struct el_node *from,
- struct el_instance *instp)
+static void process_cmd(char *buf, char *fromip,struct el_instance *instp)
{
char *cmd = NULL;
char *arg1 = NULL;
@@ -889,7 +908,7 @@
unsigned short i;
struct el_node key;
- if (strncmp(from->ip,"127.0.0.1",EL_IP_SIZE) != 0)
+ if (strncmp(fromip,"127.0.0.1",EL_IP_SIZE) != 0)
return;
ptr = strchr(buf, (int)'\r');
if (ptr)
@@ -922,7 +941,9 @@
cmd = strtok_r(buf, &delim, &saveptr);
if (!cmd)
+ {
return;
+ }
/* This version: up to 3 parameters */
arg1 = strtok_r(NULL, &delim, &saveptr);
@@ -932,7 +953,9 @@
if ((strcmp(cmd, "o.conip") == 0) ||
(strcmp(cmd, "o.dconip") == 0)) {
if (!arg1)
+ {
return;
+ }
if (strcmp(cmd, "o.conip") == 0)
pack_length = rtcp_make_sdes(pack,sizeof(pack),instp->mycall,instp->myname);
@@ -955,13 +978,14 @@
}
else {
for (i = 0; i < 20; i++)
+ {
sendto(instp->ctrl_sock, pack, pack_length,
0,(struct sockaddr *)&sin,sizeof(sin));
+ }
ast_log(LOG_NOTICE,"connect request sent to %s\n", arg1);
}
return;
}
-
return;
}
@@ -996,11 +1020,9 @@
struct el_rxqel *qpel;
char buf[GSM_FRAME_SIZE + AST_FRIENDLY_OFFSET];
- if (ast->_state != AST_STATE_UP) {
- return 0;
- }
-
if (frame->frametype != AST_FRAME_VOICE) return 0;
+
+ ast_mutex_lock(&instp->lock);
if ((!p->firstsent) && (!instp->confmode))
{
@@ -1122,6 +1144,7 @@
/* Asterisk to Echolink */
if (!(frame->subclass & (AST_FORMAT_GSM))) {
ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
+ ast_mutex_unlock(&instp->lock);
return 0;
}
if (p->txkey || p->txindex) {
@@ -1141,7 +1164,11 @@
}
}
- if (p->keepalive--) return 0;
+ if (p->keepalive--)
+ {
+ ast_mutex_unlock(&instp->lock);
+ return 0;
+ }
p->keepalive = KEEPALIVE_TIME;
/* Echolink: send heartbeats and drop dead stations */
@@ -1160,6 +1187,7 @@
}
instp->el_node_test.ip[0] = '\0';
}
+ ast_mutex_unlock(&instp->lock);
return 0;
}
@@ -1207,6 +1235,7 @@
int oldformat;
struct el_pvt *p;
struct ast_channel *tmp = NULL;
+ char *str,*cp;
oldformat = format;
format &= (AST_FORMAT_GSM);
@@ -1214,7 +1243,11 @@
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
return NULL;
}
- p = el_alloc(data);
+ str = strdup((char *)data);
+ cp = strchr(str,'/');
+ if (cp) *cp = 0;
+ p = el_alloc(str);
+ free(str);
if (p) {
tmp = el_new(p, AST_STATE_DOWN,0);
if (!tmp)
@@ -1405,6 +1438,74 @@
pthread_exit(NULL);
}
+static int do_new_call(struct el_instance *instp, struct el_pvt *p, char *call, char *name)
+{
+ struct el_node *el_node_key = NULL;
+
+ el_node_key = (struct el_node *)malloc(sizeof(struct el_node));
+ if (el_node_key)
+ {
+ strncpy(el_node_key->call,call,EL_CALL_SIZE);
+ strncpy(el_node_key->ip, instp->el_node_test.ip, EL_IP_SIZE);
+ strncpy(el_node_key->name,name,EL_NAME_SIZE);
+ el_node_key->nodenum = 385239;
+ el_node_key->countdown = instp->rtcptimeout;
+ el_node_key->seqnum = 1;
+ el_node_key->instp = instp;
+ if (tsearch(el_node_key, &el_node_list, compare_ip))
+ {
+ ast_log(LOG_NOTICE, "new CALL=%s,ip=%s,name=%s\n",
+ el_node_key->call,el_node_key->ip,
+ el_node_key->name);
+ if (instp->confmode)
+ {
+ el_node_key->p = instp->confp;
+ }
+ else
+ {
+ if (p == NULL) /* if a new inbound call */
+ {
+ p = el_alloc((void *)instp->name);
+ if (!p)
+ {
+ 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,
+ AST_STATE_RINGING,el_node_key->nodenum);
+ if (!el_node_key->chan)
+ {
+ el_destroy(el_node_key->p);
+ return -1;
+ }
+ }
+ else
+ {
+ el_node_key->p = p;
+ strncpy(el_node_key->p->ip, instp->el_node_test.ip,EL_IP_SIZE);
+ el_node_key->chan = p->owner;
+ }
+ }
+ }
+ else
+ {
+ 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);
+ return -1;
+ }
+ }
+ else
+ {
+ ast_log(LOG_ERROR,"malloc() failed for new CALL=%s, ip=%s\n",
+ call,instp->el_node_test.ip);
+ return -1;
+ }
+ return 0;
+}
+
static void *el_reader(void *data)
{
struct el_instance *instp = (struct el_instance *)data;
@@ -1413,11 +1514,10 @@
int i,x;
struct el_rxqast *qpast;
struct el_rxqel *qpel;
-
+ struct ast_frame fr;
socklen_t fromlen;
ssize_t recvlen;
- struct el_node *el_node_key = NULL;
struct el_node **found_key = NULL;
struct rtcp_sdes_request items;
char call_name[128];
@@ -1428,8 +1528,11 @@
struct timeval tmout;
ast_log(LOG_NOTICE, "Echolink reader thread started on %s.\n",instp->name);
+ ast_mutex_lock(&instp->lock);
while(run_forever)
{
+
+ ast_mutex_unlock(&instp->lock);
FD_ZERO(fds);
FD_SET(instp->audio_sock,fds);
FD_SET(instp->ctrl_sock,fds);
@@ -1438,12 +1541,17 @@
tmout.tv_sec = 0;
tmout.tv_usec = 50000;
i = select(x + 1,fds,NULL,NULL,&tmout);
- if (i == 0) continue;
+ if (i == 0)
+ {
+ ast_mutex_lock(&instp->lock);
+ continue;
+ }
if (i < 0)
{
ast_log(LOG_ERROR,"Error in select()\n");
pthread_exit(NULL);
}
+ ast_mutex_lock(&instp->lock);
if (FD_ISSET(instp->ctrl_sock,fds)) /* if a ctrl packet */
{
fromlen = sizeof(struct sockaddr_in);
@@ -1479,6 +1587,23 @@
&el_node_list, compare_ip);
if (found_key)
{
+ if (!(*found_key)->p->firstheard)
+ {
+ (*found_key)->p->firstheard = 1;
+ fr.datalen = 0;
+ fr.samples = 0;
+ fr.frametype = AST_FRAME_CONTROL;
+ fr.subclass = AST_CONTROL_ANSWER;
+ fr.data = 0;
+ fr.src = type;
+ fr.offset = 0;
+ fr.mallocd=0;
+ 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",
+ (*found_key)->chan->name);
+ }
(*found_key)->countdown = instp->rtcptimeout;
/* different callsigns behind a NAT router, running -L, -R, ... */
if (strncmp((*found_key)->call,call,EL_CALL_SIZE) != 0)
@@ -1488,54 +1613,18 @@
strncpy((*found_key)->call,call,EL_CALL_SIZE);
}
if (strncmp((*found_key)->name, name, EL_NAME_SIZE) != 0)
+ {
+ ast_log(LOG_NOTICE,"Name changed from %s to %s\n",
+ (*found_key)->name,name);
strncpy((*found_key)->name,name,EL_NAME_SIZE);
+ }
}
else /* otherwise its a new request */
{
- el_node_key = (struct el_node *)malloc(sizeof(struct el_node));
- if (el_node_key)
+ if (do_new_call(instp,NULL,call,name) < 0)
{
- strncpy(el_node_key->call,call,EL_CALL_SIZE);
- strncpy(el_node_key->ip, instp->el_node_test.ip, EL_IP_SIZE);
- strncpy(el_node_key->name,name,EL_NAME_SIZE);
- el_node_key->nodenum = 385239;
- el_node_key->countdown = instp->rtcptimeout;
- el_node_key->seqnum = 1;
- el_node_key->instp = instp;
- if (tsearch(el_node_key, &el_node_list, compare_ip))
- {
- ast_log(LOG_NOTICE, "new CALL=%s,ip=%s,name=%s\n",
- el_node_key->call,el_node_key->ip,
- el_node_key->name);
- if (instp->confmode)
- {
- el_node_key->p = instp->confp;
- }
- else
- {
- el_node_key->p = el_alloc((void *)instp);
- strncpy(el_node_key->p->ip, instp->el_node_test.ip,
- EL_IP_SIZE);
- if (el_node_key->p)
- {
- el_node_key->chan = el_new(el_node_key->p,
- AST_STATE_UP,el_node_key->nodenum);
- if (!el_node_key->chan)
- el_destroy(el_node_key->p);
- }
- }
- }
- else
- {
- 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);
- }
- }
- else
- {
- ast_log(LOG_ERROR,"malloc() failed for new CALL=%s, ip=%s\n",
- call,instp->el_node_test.ip);
+ ast_mutex_unlock(&instp->lock);
+ pthread_exit(NULL);
}
}
}
@@ -1547,8 +1636,6 @@
{
if (find_delete(&instp->el_node_test))
ast_log(LOG_NOTICE,"disconnect from ip=%s\n",instp->el_node_test.ip);
- else
- ast_log(LOG_NOTICE, "ip=%s,busy, denied or multiple disconnects\n",instp->el_node_test.ip);
}
}
}
@@ -1568,7 +1655,7 @@
#endif
if (buf[0] == 0x6f)
{
- process_cmd(buf,recvlen,&instp->el_node_test,instp);
+ process_cmd(buf,instp->el_node_test.ip,instp);
}
else
{
@@ -1576,6 +1663,24 @@
if (found_key)
{
struct el_pvt *p = (*found_key)->p;
+
+ if (!(*found_key)->p->firstheard)
+ {
+ (*found_key)->p->firstheard = 1;
+ fr.datalen = 0;
+ fr.samples = 0;
+ fr.frametype = AST_FRAME_CONTROL;
+ fr.subclass = AST_CONTROL_ANSWER;
+ fr.data = 0;
+ fr.src = type;
+ fr.offset = 0;
+ fr.mallocd=0;
+ 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",
+ (*found_key)->chan->name);
+ }
(*found_key)->countdown = instp->rtcptimeout;
if (recvlen == sizeof(struct gsmVoice_t))
{
@@ -1589,6 +1694,7 @@
if (!qpast)
{
ast_log(LOG_NOTICE,"Cannot malloc for qpast\n");
+ ast_mutex_unlock(&instp->lock);
pthread_exit(NULL);
}
memcpy(qpast->buf,((struct gsmVoice_t *)buf)->data +
@@ -1618,6 +1724,7 @@
}
}
}
+ ast_mutex_unlock(&instp->lock);
ast_log(LOG_NOTICE, "Echolink read thread exited.\n");
pthread_exit(NULL);
}
@@ -1643,6 +1750,7 @@
}
memset(instp,0,sizeof(struct el_instance));
+ ast_mutex_init(&instp->lock);
instp->audio_sock = -1;
instp->ctrl_sock = -1;
instp->fdr = -1;
More information about the asterisk-commits
mailing list