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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Nov 16 18:55:54 CST 2008


Author: jdixon
Date: Sun Nov 16 18:55:53 2008
New Revision: 157234

URL: http://svn.digium.com/view/asterisk?view=rev&rev=157234
Log:
Added support for UNCOMP

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/view/asterisk/team/jdixon/chan_usbradio-1.4/channels/chan_irlp.c?view=diff&rev=157234&r1=157233&r2=157234
==============================================================================
--- team/jdixon/chan_usbradio-1.4/channels/chan_irlp.c (original)
+++ team/jdixon/chan_usbradio-1.4/channels/chan_irlp.c Sun Nov 16 18:55:53 2008
@@ -31,7 +31,10 @@
 /*** MODULEINFO
  ***/
 
-/* Version 0.13, 9/17/2008
+#define	rpt_free(p) __ast_free(p,__FILE__,__LINE__,__PRETTY_FUNCTION__)
+
+
+/* Version 0.15, 11/16/2008
 irlp channel driver for Asterisk/app_rpt.
 
 I wish to thank the following people for the immeasurable amount of
@@ -88,6 +91,9 @@
 
 #define GSM_BLOCKING_FACTOR 10
 #define GSM_FRAME_SIZE 33
+
+#define ULAW_BLOCKING_FACTOR 1
+#define ULAW_FRAME_SIZE 256
 
 #define IRLP_IP_SIZE 15
 #define IRLP_CALL_SIZE 15
@@ -112,7 +118,7 @@
 	"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\""
 
-enum {IRLP_NOPROTO,IRLP_ISADPCM,IRLP_ISGSM} ;
+enum {IRLP_NOPROTO,IRLP_ISADPCM,IRLP_ISGSM,IRLP_ISULAW} ;
 
 struct irlp_audio
 {
@@ -211,6 +217,7 @@
 static int nodenum = 0;
 static int audio_sock = -1;
 static int ctrl_sock = -1;
+static int tx_buf_n = 0;
 static int tx_audio_port = 0;
 static int alt_audio_sock = -1;
 static int alt_ctrl_sock = -1;
@@ -226,7 +233,6 @@
 static int run_forever = 1;
 static int proto = IRLP_NOPROTO;
 static int in_node = 0;
-static int txindex;
 static struct irlp_rxqast rxqast;
 static char *outbuf_old;
 static int rxlen;
@@ -289,7 +295,7 @@
 	keepalive = 0;
 	in_node = 0;
 	nodenum = 0;
-	txindex = 0;
+	tx_buf_n = 0;
 	ready = 0;
 	rxqast.qe_forw = &rxqast;
 	rxqast.qe_back = &rxqast;
@@ -514,7 +520,7 @@
 		if (cp[strlen(cp) - 1] == '\n')
 			cp[strlen(cp) - 1] = 0;
 		strncpy(ipbuf,cp,sizeof(ipbuf) - 1);
-		free(cp);
+		ast_free(cp);
 	}
 	else
 	{
@@ -545,7 +551,7 @@
 		if (cp[strlen(cp) - 1] == '\n')
 			cp[strlen(cp) - 1] = 0;
 		strncpy(buf,cp,sizeof(buf) - 1);
-		free(cp);
+		ast_free(cp);
 	}
 	else
 	{
@@ -597,7 +603,7 @@
 		ast_safe_system(IRLP_END);
 		usleep(10000);
 	}
-	if (cp) free(cp);
+	if (cp) ast_free(cp);
 	if ((!radmode) && nodenum)
 	{
 		if (nodenum >= 9000)
@@ -637,6 +643,15 @@
 			  proto = IRLP_ISGSM;
 		          ast->nativeformats = AST_FORMAT_GSM;
 		  }
+		  else if (!strncasecmp(cp,"UNCOMP",6))
+		  {
+			  if (proto == IRLP_NOPROTO)
+				  ast_log(LOG_NOTICE,"irlp channel format set to ULAW (UNCOMP)\n");
+			  else if (proto != IRLP_ISULAW)
+				  ast_log(LOG_NOTICE,"irlp channel format changed to ULAW (UNCOMP)\n");
+			  proto = IRLP_ISULAW;
+		          ast->nativeformats = AST_FORMAT_ULAW;
+		  }
 		  else 
 		  {
 			  if (proto == IRLP_NOPROTO)
@@ -648,7 +663,7 @@
 		  }
 		  ast_set_read_format(ast,ast->readformat);
 		  ast_set_write_format(ast,ast->writeformat);
-		  free(cp);
+		  ast_free(cp);
 	  }
 	  return;
 }
@@ -705,7 +720,7 @@
 		{
 			cp = irlp_read_file(IRLP_ROOT,"codec");
 			i = ((cp && *cp));
-			if (cp) free(cp);
+			if (cp) ast_free(cp);
 			if (i) send_keepalive();
 			keepalive = now;
 		}
@@ -781,7 +796,7 @@
 					ready = 1;
 					if (curcall && (proto == IRLP_NOPROTO)) process_codec_file(curcall);
 				  } else ast_log(LOG_NOTICE,"irlp node attempted connect from %s with no node info\n", ip);
-				  if (cp) free(cp);
+				  if (cp) ast_free(cp);
 	                       }
 	                    }
 	                 } 
@@ -825,7 +840,7 @@
 			      if (proto == IRLP_NOPROTO)
 				  ast_log(LOG_NOTICE,"irlp channel format set to ADPCM\n");
 			      else if (proto != IRLP_ISADPCM)
-				  ast_log(LOG_NOTICE,"irlp channel format changed to GSM\n");
+				  ast_log(LOG_NOTICE,"irlp channel format changed to ADPCM\n");
 			      proto = IRLP_ISADPCM;
 			      if (curcall)
 			      {
@@ -835,7 +850,7 @@
 				      ast_set_write_format(curcall,curcall->writeformat);
 			      }
 		          }
-	                  if (((struct irlp_audio *)buf)->compression == htonl(0x20 | 0x40000000))
+	                  else if (((struct irlp_audio *)buf)->compression == htonl(0x20 | 0x40000000))
 		          {
 			      if (proto == IRLP_NOPROTO)
 				  ast_log(LOG_NOTICE,"irlp channel format set to GSM\n");
@@ -849,13 +864,27 @@
 				      ast_set_write_format(curcall,curcall->writeformat);
 			      }
 		          }
+	                  else if (((struct irlp_audio *)buf)->compression == htonl(0x40000000))
+		          {
+			      if (proto == IRLP_NOPROTO)
+				  ast_log(LOG_NOTICE,"irlp channel format set to ULAW (UNCOMP)\n");
+			      else if (proto != IRLP_ISULAW)
+				  ast_log(LOG_NOTICE,"irlp channel format changed to ULAW (UNCOMP)\n");
+			      proto = IRLP_ISULAW;
+			      if (curcall)
+			      {
+		                      curcall->nativeformats = AST_FORMAT_ULAW;
+				      ast_set_read_format(curcall,curcall->readformat);
+				      ast_set_write_format(curcall,curcall->writeformat);
+			      }
+		          }
 	                 qpast = ast_malloc(sizeof(struct irlp_rxqast) + len);
 	                 if (!qpast) 
 			 {
 	                    ast_log(LOG_NOTICE,"Cannot malloc for qpast\n");
 			    break;
 	                 }
-			 if (proto == IRLP_ISADPCM)
+			 if (proto != IRLP_ISGSM)
 			 {
 		                 qpast->len = len;
 		                 memcpy(qpast->buf,((struct irlp_audio *)buf)->buffer.buffer_val,len);
@@ -1100,8 +1129,8 @@
 	struct irlp_pvt *p = ast->tech_pvt;
 	struct ast_frame fr;
 	struct irlp_rxqast *qpast;
-	int n,i,len,gotone,dosync,blocking_factor,frame_size,frame_samples,recvlen;
-        char outbuf[ADPCM_FRAME_SIZE + AST_FRIENDLY_OFFSET + 3]; /* turns out that ADPCM is larger */
+	int n,i,len,gotone,dosync,blocking_factor,frame_size,frame_samples,recvlen,flen;
+        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];
@@ -1154,18 +1183,20 @@
 			}
 		}
 	}
+        /* IRLP to Asterisk */
 	frame_samples = 160;
 	if (proto == IRLP_ISGSM)
 	{
-		blocking_factor = GSM_BLOCKING_FACTOR;
 		frame_size = GSM_FRAME_SIZE;
 	}
+	else if (proto == IRLP_ISULAW)
+	{
+		frame_size = frame_samples;
+	}
 	else
 	{
-		blocking_factor = ADPCM_BLOCKING_FACTOR;
 		frame_size = ADPCM_FRAME_SIZE;
 	}
-        /* IRLP to Asterisk */
 	if (rxqast.qe_forw != &rxqast) {
 		for(n = 0,qpast = rxqast.qe_forw; qpast != &rxqast; qpast = qpast->qe_forw) {
 			n++;
@@ -1246,7 +1277,7 @@
 			memcpy(cp + i,outbuf_new,len);
 			rxlen = len + i;
 			rxidx = 0;
-			free(outbuf_new);
+			ast_free(outbuf_new);
 			outbuf_new = NULL;
 			free(outbuf_old);
 			outbuf_old = cp;
@@ -1274,6 +1305,10 @@
 		if (proto == IRLP_ISADPCM)
 		{
 			fr.subclass = AST_FORMAT_ADPCM;
+		}
+		else if (proto == IRLP_ISULAW)
+		{
+			fr.subclass = AST_FORMAT_ULAW;
 		}
 		else
 		{
@@ -1285,7 +1320,6 @@
 		fr.mallocd=0;
 		fr.delivery.tv_sec = 0;
 		fr.delivery.tv_usec = 0;
-
 		ast_queue_frame(ast,&fr);
 	}
 	if (p->rxkey == 1) {
@@ -1329,36 +1363,61 @@
 		irlp_dtmf_special = 0;
 	}
 
-	if (!p->txkey) return(0);
-
-	i = AST_FORMAT_ADPCM;
-	if (proto == IRLP_ISGSM) i = AST_FORMAT_GSM;
-
-        /* Asterisk to IRLP */
+	if (!p->txkey) 
+	{
+		tx_buf_n = 0;
+		return(0);
+	}
+
+	flen = frame->datalen;
+	/* Asterisk to IRLP */
+	if (proto == IRLP_ISGSM)
+	{
+		blocking_factor = GSM_BLOCKING_FACTOR;
+		frame_size = GSM_FRAME_SIZE;
+		i = AST_FORMAT_GSM;	
+	}
+	else if (proto == IRLP_ISULAW)
+	{
+		blocking_factor = ULAW_BLOCKING_FACTOR;
+		frame_size = ULAW_FRAME_SIZE;
+		i = AST_FORMAT_ULAW;
+	}
+	else
+	{
+		blocking_factor = ADPCM_BLOCKING_FACTOR;
+		frame_size = ADPCM_FRAME_SIZE;
+		i = AST_FORMAT_ADPCM;
+		flen = frame->datalen - 3;
+	}
+	
         if (!(frame->subclass & i)) {
              ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
              return 0;
         }
 	cp = frame->data;
-        if (p->txkey || txindex)  {
-	     if ((proto == IRLP_ISADPCM) && (!txindex))
-		 memcpy(tx_buf + (frame_size * 
+	if ((proto == IRLP_ISADPCM) && (!tx_buf_n)) {
+	    memcpy(tx_buf + (frame_size * 
 		    blocking_factor),cp + frame_size,3);
-             memcpy(tx_buf + (frame_size * txindex++), 
-                    frame->data,frame_size);
-        }     
-
-        if (txindex >= blocking_factor) { 
+	}
+        memcpy(tx_buf + tx_buf_n,frame->data,flen);
+	tx_buf_n += flen;
+        if (tx_buf_n >= (blocking_factor * frame_size)) { 
 
            dp = (unsigned char *)irlp_audio_packet.buffer.buffer_val;
 	   if (proto == IRLP_ISADPCM)
 	   {
 	           irlp_audio_packet.compression = htonl(0x200 | 0x40000000);
 	   }
+	   else if (proto == IRLP_ISULAW)
+	   {
+	           irlp_audio_packet.compression = htonl(0x40000000);
+	   }
 	   else
 	   {
 	           irlp_audio_packet.compression = htonl(0x20 | 0x40000000);
 	   }
+
            snprintf(irlp_audio_packet.sendinghost,IRLP_IP_SIZE,
                      "stn%s-%s",mynode,mycall);
 
@@ -1367,6 +1426,12 @@
 		memcpy((char *)dp,tx_buf,(blocking_factor * frame_size) + 3);
 	        irlp_audio_packet.buffer.buffer_len = htonl((blocking_factor * 
 			frame_size) + 3);
+	   }
+	   else if (proto == IRLP_ISULAW)
+	   {
+		memcpy((char *)dp,tx_buf,blocking_factor * frame_size);
+	        irlp_audio_packet.buffer.buffer_len = htonl(blocking_factor * 
+			frame_size);
 	   }
 	   else
 	   {
@@ -1384,6 +1449,11 @@
 	      if (proto == IRLP_ISADPCM)
 	      {
                   sendto((alt_audio_sock != -1) ? alt_audio_sock : audio_sock,(char *)&irlp_audio_packet,507,
+                      0,(struct sockaddr *)&sin,sizeof(struct sockaddr));
+	      }
+	      else if (proto == IRLP_ISULAW)
+	      {
+                  sendto((alt_audio_sock != -1) ? alt_audio_sock : audio_sock,(char *)&irlp_audio_packet,280,
                       0,(struct sockaddr *)&sin,sizeof(struct sockaddr));
 	      }
 	      else
@@ -1401,12 +1471,22 @@
                sendto(audio_sock,(char *)&irlp_audio_packet,507,
                   0,(struct sockaddr *)&sin,sizeof(struct sockaddr));
 	   }
+	   else if (proto == IRLP_ISULAW)
+	   {
+               sendto(audio_sock,(char *)&irlp_audio_packet,280,
+                  0,(struct sockaddr *)&sin,sizeof(struct sockaddr));
+	   }
 	   else
 	   {
                sendto(audio_sock,(char *)&irlp_audio_packet,356,
                   0,(struct sockaddr *)&sin,sizeof(struct sockaddr));
 	   }
-           txindex = 0;
+           tx_buf_n -= (blocking_factor * frame_size);
+	   if (tx_buf_n)
+	   {
+		i = (blocking_factor * frame_size);
+		memmove(tx_buf,tx_buf + i,tx_buf_n);
+	   }
         }
 	return 0;
 }




More information about the asterisk-commits mailing list