[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