[svn-commits] jdixon: branch 1.4 r82366 - in /branches/1.4: apps/ channels/ channels/xpmr/ ...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Thu Sep 13 19:34:13 CDT 2007
Author: jdixon
Date: Thu Sep 13 19:34:13 2007
New Revision: 82366
URL: http://svn.digium.com/view/asterisk?view=rev&rev=82366
Log:
Added channel driver for USB Radio device and
support thereof.
Added:
branches/1.4/channels/chan_usbradio.c (with props)
branches/1.4/channels/xpmr/
branches/1.4/channels/xpmr/LICENSE (with props)
branches/1.4/channels/xpmr/sinetabx.h (with props)
branches/1.4/channels/xpmr/xpmr.c (with props)
branches/1.4/channels/xpmr/xpmr.h (with props)
branches/1.4/channels/xpmr/xpmr_coef.h (with props)
branches/1.4/configs/usbradio.conf.sample (with props)
Modified:
branches/1.4/apps/app_rpt.c
branches/1.4/channels/Makefile
Modified: branches/1.4/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_rpt.c?view=diff&rev=82366&r1=82365&r2=82366
==============================================================================
--- branches/1.4/apps/app_rpt.c (original)
+++ branches/1.4/apps/app_rpt.c Thu Sep 13 19:34:13 2007
@@ -18,11 +18,10 @@
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
-
/*! \file
*
* \brief Radio Repeater / Remote Base program
- * version 0.70 07/22/07
+ * version 0.73 09/04/07
*
* \author Jim Dixon, WB6NIL <jim at lambdatel.com>
*
@@ -179,7 +178,7 @@
#define RETRY_TIMER_MS 5000
-#define START_DELAY 10
+#define START_DELAY 2
#define MAXPEERSTR 31
#define MAXREMSTR 15
@@ -226,6 +225,8 @@
#define DTMF_LOCAL_STARTTIME 500
#define IC706_PL_MEMORY_OFFSET 50
+
+#define ALLOW_LOCAL_CHANNELS
enum {REM_OFF,REM_MONITOR,REM_TX};
@@ -301,6 +302,7 @@
#include "asterisk/say.h"
#include "asterisk/localtime.h"
#include "asterisk/cdr.h"
+#include "asterisk/options.h"
#include <termios.h>
/* Start a tone-list going */
@@ -308,7 +310,7 @@
/*! Stop the tones from playing */
void ast_playtones_stop(struct ast_channel *chan);
-static char *tdesc = "Radio Repeater / Remote Base version 0.70 07/22/2007";
+static char *tdesc = "Radio Repeater / Remote Base version 0.73 09/04/2007";
static char *app = "Rpt";
@@ -591,7 +593,7 @@
char lastdtmfcommand[MAXDTMF];
char cmdnode[50];
struct ast_channel *rxchannel,*txchannel, *monchannel;
- struct ast_channel *pchannel,*txpchannel;
+ struct ast_channel *pchannel,*txpchannel, *zaprxchannel, *zaptxchannel;
struct ast_frame *lastf1,*lastf2;
struct rpt_tele tele;
struct timeval lasttv,curtv;
@@ -1186,6 +1188,57 @@
ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", fname, strerror(errno));
return(fd);
}
+
+static void mdc1200_notify(struct rpt *myrpt,char *fromnode, unsigned int unit)
+{
+ if (!fromnode)
+ {
+ ast_verbose("Got MDC-1200 ID %04X from local system (%s)\n",
+ unit,myrpt->name);
+ }
+ else
+ {
+ ast_verbose("Got MDC-1200 ID %04X from node %s (%s)\n",
+ unit,fromnode,myrpt->name);
+ }
+}
+
+#ifdef _MDC_DECODE_H_
+
+static void mdc1200_send(struct rpt *myrpt, unsigned int unit)
+{
+struct rpt_link *l;
+struct ast_frame wf;
+char str[200];
+
+
+ sprintf(str,"I %s %04X",myrpt->name,unit);
+
+ wf.frametype = AST_FRAME_TEXT;
+ wf.subclass = 0;
+ wf.offset = 0;
+ wf.mallocd = 0;
+ wf.datalen = strlen(str) + 1;
+ wf.samples = 0;
+
+
+ l = myrpt->links.next;
+ /* otherwise, send it to all of em */
+ while(l != &myrpt->links)
+ {
+ if (l->name[0] == '0')
+ {
+ l = l->next;
+ continue;
+ }
+ wf.data = str;
+ if (l->chan) ast_write(l->chan,&wf);
+ l = l->next;
+ }
+ return;
+}
+
+#endif
static char func_xlat(struct rpt *myrpt,char c,struct rpt_xlat *xlat)
{
@@ -3113,7 +3166,7 @@
ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);
}
}
-#ifdef _MDC_DECODE_H_
+#if defined(_MDC_DECODE_H_) && defined(MDC_SAY_WHEN_DOING_CT)
if (myrpt->lastunit)
{
char mystr[10];
@@ -3334,14 +3387,14 @@
break;
}
i = ZT_FLUSH_EVENT;
- if (ioctl(myrpt->txchannel->fds[0],ZT_FLUSH,&i) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_FLUSH,&i) == -1)
{
ast_mutex_unlock(&myrpt->remlock);
ast_log(LOG_ERROR,"Cant flush events");
res = -1;
break;
}
- if (ioctl(myrpt->rxchannel->fds[0],ZT_GET_PARAMS,&par) == -1)
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_GET_PARAMS,&par) == -1)
{
ast_mutex_unlock(&myrpt->remlock);
ast_log(LOG_ERROR,"Cant get params");
@@ -4490,7 +4543,14 @@
l->isremote = (s && ast_true(s));
if (modechange) l->connected = 1;
l->hasconnected = l->perma = perma;
+#ifdef ALLOW_LOCAL_CHANNELS
+ if ((strncasecmp(s1,"iax2/", 5) == 0) || (strncasecmp(s1, "local/", 6) == 0))
+ strncpy(deststr, s1, sizeof(deststr));
+ else
+ snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
+#else
snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
+#endif
tele = strchr(deststr, '/');
if (!tele){
ast_log(LOG_WARNING,"link3:Dial number (%s) must be in format tech/number\n",deststr);
@@ -4771,6 +4831,14 @@
break;
+#ifdef _MDC_DECODE_H_
+ case 8:
+ myrpt->lastunit = 0xd00d;
+ mdc1200_notify(myrpt,NULL,myrpt->lastunit);
+ mdc1200_send(myrpt,myrpt->lastunit);
+ break;
+#endif
+
case 16: /* Restore links disconnected with "disconnect all links" command */
strcpy(tmp, myrpt->savednodes); /* Make a copy */
finddelim(tmp, strs, MAXLINKLIST); /* convert into substrings */
@@ -5253,15 +5321,28 @@
myrpt->name,tmp,mylink->name);
return;
}
- if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
- {
- ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
- return;
- }
- if (strcmp(cmd,"D"))
- {
- ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
- return;
+ if (tmp[0] == 'I')
+ {
+ if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3)
+ {
+ ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
+ return;
+ }
+ mdc1200_notify(myrpt,src,seq);
+ strcpy(dest,"*");
+ }
+ else
+ {
+ if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
+ {
+ ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
+ return;
+ }
+ if (strcmp(cmd,"D"))
+ {
+ ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
+ return;
+ }
}
if (dest[0] == '0')
{
@@ -5727,6 +5808,7 @@
static void rbi_out_parallel(struct rpt *myrpt,unsigned char *data)
{
+#ifdef __i386__
int i,j;
unsigned char od,d;
static volatile long long delayvar;
@@ -5749,6 +5831,7 @@
}
/* >= 50 us */
for(delayvar = 1; delayvar < 50000; delayvar++);
+#endif
}
static void rbi_out(struct rpt *myrpt,unsigned char *data)
@@ -5759,16 +5842,16 @@
r.radpar = ZT_RADPAR_REMMODE;
r.data = ZT_RADPAR_REM_RBI1;
/* if setparam ioctl fails, its probably not a pciradio card */
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
{
rbi_out_parallel(myrpt,data);
return;
}
r.radpar = ZT_RADPAR_REMCOMMAND;
memcpy(&r.data,data,5);
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
- {
- ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->rxchannel->name);
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
+ {
+ ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->zaprxchannel->name);
return;
}
}
@@ -5803,36 +5886,39 @@
if (c == '\r') break;
}
}
- if(debug){
- printf("String returned was: ");
- for(j = 0; j < i; j++)
- printf("%02X ", (unsigned char ) rxbuf[j]);
- printf("\n");
- }
+ if(debug){
+ printf("String returned was: ");
+ for(j = 0; j < i; j++)
+ printf("%02X ", (unsigned char ) rxbuf[j]);
+ printf("\n");
+ }
return(i);
}
-
+
+ /* if not a zap channel, cant use pciradio stuff */
+ if (myrpt->rxchannel != myrpt->zaprxchannel) return -1;
+
prm.radpar = ZT_RADPAR_UIOMODE;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
oldmode = prm.data;
prm.radpar = ZT_RADPAR_UIODATA;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
olddata = prm.data;
prm.radpar = ZT_RADPAR_REMMODE;
if (asciiflag & 1) prm.data = ZT_RADPAR_REM_SERIAL_ASCII;
else prm.data = ZT_RADPAR_REM_SERIAL;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
if (asciiflag & 2)
{
i = ZT_ONHOOK;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
usleep(100000);
}
prm.radpar = ZT_RADPAR_REMCOMMAND;
prm.data = rxmaxbytes;
memcpy(prm.buf,txbuf,txbytes);
prm.index = txbytes;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
if (rxbuf)
{
*rxbuf = 0;
@@ -5841,18 +5927,18 @@
index = prm.index;
prm.radpar = ZT_RADPAR_REMMODE;
prm.data = ZT_RADPAR_REM_NONE;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
if (asciiflag & 2)
{
i = ZT_OFFHOOK;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
}
prm.radpar = ZT_RADPAR_UIOMODE;
prm.data = oldmode;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
prm.radpar = ZT_RADPAR_UIODATA;
prm.data = olddata;
- if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
return(index);
}
@@ -8238,6 +8324,19 @@
/* put string in our buffer */
strncpy(tmp,str,sizeof(tmp) - 1);
if (!strcmp(tmp,discstr)) return 0;
+
+#ifndef DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES
+ if (tmp[0] == 'I')
+ {
+ if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3)
+ {
+ ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
+ return 0;
+ }
+ mdc1200_notify(myrpt,src,seq);
+ return 0;
+ }
+#endif
if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
{
ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
@@ -8645,7 +8744,6 @@
}
-
/* single thread with one file (request) to dial */
static void *rpt(void *this)
{
@@ -8694,6 +8792,9 @@
}
*tele++ = 0;
myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL);
+ myrpt->zaprxchannel = NULL;
+ if (!strcasecmp(tmpstr,"Zap"))
+ myrpt->zaprxchannel = myrpt->rxchannel;
if (myrpt->rxchannel)
{
if (myrpt->rxchannel->_state == AST_STATE_BUSY)
@@ -8728,6 +8829,7 @@
myrpt->rpt_thread = AST_PTHREADT_STOP;
pthread_exit(NULL);
}
+ myrpt->zaptxchannel = NULL;
if (myrpt->txchanname)
{
strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1);
@@ -8742,6 +8844,8 @@
}
*tele++ = 0;
myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL);
+ if (!strcasecmp(tmpstr,"Zap"))
+ myrpt->zaptxchannel = myrpt->txchannel;
if (myrpt->txchannel)
{
if (myrpt->txchannel->_state == AST_STATE_BUSY)
@@ -8798,6 +8902,24 @@
myrpt->rpt_thread = AST_PTHREADT_STOP;
pthread_exit(NULL);
}
+ if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel;
+ if (!myrpt->zaptxchannel)
+ {
+ /* allocate a pseudo-channel thru asterisk */
+ myrpt->zaptxchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
+ if (!myrpt->zaptxchannel)
+ {
+ fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
+ rpt_mutex_unlock(&myrpt->lock);
+ if (myrpt->txchannel != myrpt->rxchannel)
+ ast_hangup(myrpt->txchannel);
+ ast_hangup(myrpt->rxchannel);
+ myrpt->rpt_thread = AST_PTHREADT_STOP;
+ pthread_exit(NULL);
+ }
+ ast_set_read_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR);
+ ast_set_write_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR);
+ }
/* allocate a pseudo-channel thru asterisk */
myrpt->monchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
if (!myrpt->monchannel)
@@ -8817,7 +8939,7 @@
ci.confno = -1; /* make a new conf */
ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER;
/* first put the channel on the conference in proper mode */
- if (ioctl(myrpt->txchannel->fds[0],ZT_SETCONF,&ci) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_SETCONF,&ci) == -1)
{
ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
rpt_mutex_unlock(&myrpt->lock);
@@ -8853,7 +8975,8 @@
myrpt->conf = ci.confno;
/* make a conference for the pseudo */
ci.chan = 0;
- if (strstr(myrpt->txchannel->name,"pseudo") == NULL)
+ if ((strstr(myrpt->txchannel->name,"pseudo") == NULL) &&
+ (myrpt->zaptxchannel == myrpt->txchannel))
{
/* get tx channel's port number */
if (ioctl(myrpt->txchannel->fds[0],ZT_CHANNO,&ci.confno) == -1)
@@ -9059,6 +9182,7 @@
if (ast_check_hangup(myrpt->pchannel)) break;
if (ast_check_hangup(myrpt->monchannel)) break;
if (ast_check_hangup(myrpt->txpchannel)) break;
+ if (myrpt->zaptxchannel && ast_check_hangup(myrpt->zaptxchannel)) break;
/* Set local tx with keyed */
myrpt->localtx = myrpt->keyed;
@@ -9316,6 +9440,8 @@
cs[n++] = myrpt->monchannel;
cs[n++] = myrpt->txpchannel;
if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel;
+ if (myrpt->zaptxchannel != myrpt->txchannel)
+ cs[n++] = myrpt->zaptxchannel;
l = myrpt->links.next;
while(l != &myrpt->links)
{
@@ -9609,6 +9735,8 @@
if ((op == 1) && (arg == 0))
{
myrpt->lastunit = unitID;
+ mdc1200_notify(myrpt,NULL,myrpt->lastunit);
+ mdc1200_send(myrpt,myrpt->lastunit);
}
}
if ((debug > 2) && (i == 2))
@@ -9629,7 +9757,7 @@
/* apply inbound filters, if any */
rpt_filter(myrpt,f->data,f->datalen / 2);
#endif
- if (ioctl(myrpt->rxchannel->fds[0], ZT_GETCONFMUTE, &ismuted) == -1)
+ if (ioctl(myrpt->zaprxchannel->fds[0], ZT_GETCONFMUTE, &ismuted) == -1)
{
ismuted = 0;
}
@@ -9757,6 +9885,30 @@
{
if (debug) printf("@@@@ rpt:Hung Up\n");
break;
+ }
+ if (f->frametype == AST_FRAME_CONTROL)
+ {
+ if (f->subclass == AST_CONTROL_HANGUP)
+ {
+ if (debug) printf("@@@@ rpt:Hung Up\n");
+ ast_frfree(f);
+ break;
+ }
+ }
+ ast_frfree(f);
+ continue;
+ }
+ if (who == myrpt->zaptxchannel) /* if it was a read from pseudo-tx */
+ {
+ f = ast_read(myrpt->zaptxchannel);
+ if (!f)
+ {
+ if (debug) printf("@@@@ rpt:Hung Up\n");
+ break;
+ }
+ if (f->frametype == AST_FRAME_VOICE)
+ {
+ ast_write(myrpt->txchannel,f);
}
if (f->frametype == AST_FRAME_CONTROL)
{
@@ -10178,6 +10330,7 @@
ast_hangup(myrpt->monchannel);
ast_hangup(myrpt->txpchannel);
if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel);
+ if (myrpt->zaptxchannel != myrpt->txchannel) ast_hangup(myrpt->zaptxchannel);
if (myrpt->lastf1) ast_frfree(myrpt->lastf1);
myrpt->lastf1 = NULL;
if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
@@ -10216,6 +10369,9 @@
/* go thru all the specified repeaters */
this = NULL;
n = 0;
+ /* wait until asterisk starts */
+ while(!ast_test_flag(&ast_options,AST_OPT_FLAG_FULLY_BOOTED))
+ usleep(250000);
rpt_vars[n].cfg = ast_config_load("rpt.conf");
cfg = rpt_vars[n].cfg;
if (!cfg) {
@@ -10395,6 +10551,7 @@
ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n");
return -1;
}
+
strncpy(tmp, (char *)data, sizeof(tmp)-1);
time(&t);
/* if time has externally shifted negative, screw it */
@@ -10443,11 +10600,19 @@
}
else
{
+#ifdef ALLOW_LOCAL_CHANNELS
+ /* Check to insure the connection is IAX2 or Local*/
+ if ( (strncmp(chan->name,"IAX2",4)) && (strncmp(chan->name,"Local",5)) ) {
+ ast_log(LOG_WARNING, "We only accept links via IAX2 or Local!!\n");
+ return -1;
+ }
+#else
if (strncmp(chan->name,"IAX2",4))
{
ast_log(LOG_WARNING, "We only accept links via IAX2!!\n");
return -1;
}
+#endif
}
if (options && (*options == 'R'))
{
@@ -10581,7 +10746,17 @@
/* get his IP from IAX2 module */
memset(hisip,0,sizeof(hisip));
+#ifdef ALLOW_LOCAL_CHANNELS
+ /* set IP address if this is a local connection*/
+ if (strncmp(chan->name,"Local",5)==0) {
+ strcpy(hisip,"127.0.0.1");
+ } else {
+ pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
+ }
+#else
pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
+#endif
+
if (!hisip[0])
{
ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n");
@@ -10815,6 +10990,9 @@
}
*tele++ = 0;
myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL);
+ myrpt->zaprxchannel = NULL;
+ if (!strcasecmp(myrpt->rxchanname,"Zap"))
+ myrpt->zaprxchannel = myrpt->rxchannel;
if (myrpt->rxchannel)
{
ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
@@ -10836,6 +11014,7 @@
pthread_exit(NULL);
}
*--tele = '/';
+ myrpt->zaptxchannel = NULL;
if (myrpt->txchanname)
{
tele = strchr(myrpt->txchanname,'/');
@@ -10848,6 +11027,8 @@
}
*tele++ = 0;
myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL);
+ if (!strcasecmp(myrpt->txchanname,"Zap"))
+ myrpt->zaptxchannel = myrpt->txchannel;
if (myrpt->txchannel)
{
ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
@@ -10888,6 +11069,8 @@
}
ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
+ if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel;
+ if (!myrpt->zaptxchannel) myrpt->zaptxchannel = myrpt->pchannel;
/* make a conference for the pseudo */
ci.chan = 0;
ci.confno = -1; /* make a new conf */
@@ -10903,6 +11086,8 @@
ast_hangup(myrpt->rxchannel);
pthread_exit(NULL);
}
+ /* save pseudo channel conference number */
+ myrpt->conf = myrpt->txconf = ci.confno;
/* if serial io port, open it */
myrpt->iofd = -1;
if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt->p.ioport)) == -1))
@@ -10916,30 +11101,30 @@
}
iskenwood_pci4 = 0;
memset(&z,0,sizeof(z));
- if (myrpt->iofd < 1)
+ if ((myrpt->iofd < 1) && (myrpt->txchannel == myrpt->zaptxchannel))
{
z.radpar = ZT_RADPAR_REMMODE;
z.data = ZT_RADPAR_REM_NONE;
- res = ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z);
+ res = ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z);
/* if PCIRADIO and kenwood selected */
if ((!res) && (!strcmp(myrpt->remote,remote_rig_kenwood)))
{
z.radpar = ZT_RADPAR_UIOMODE;
z.data = 1;
- if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
{
ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
return -1;
}
z.radpar = ZT_RADPAR_UIODATA;
z.data = 3;
- if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
{
ast_log(LOG_ERROR,"Cannot set UIODATA\n");
return -1;
}
i = ZT_OFFHOOK;
- if (ioctl(myrpt->txchannel->fds[0],ZT_HOOK,&i) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i) == -1)
{
ast_log(LOG_ERROR,"Cannot set hook\n");
return -1;
@@ -10947,30 +11132,31 @@
iskenwood_pci4 = 1;
}
}
- i = ZT_ONHOOK;
- ioctl(myrpt->txchannel->fds[0],ZT_HOOK,&i);
- /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */
- if ((myrpt->iofd < 1) && (!res) &&
- (!strcmp(myrpt->remote,remote_rig_ft897) ||
- (!strcmp(myrpt->remote,remote_rig_ic706))))
- {
- z.radpar = ZT_RADPAR_UIOMODE;
- z.data = 1;
- if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
- return -1;
- }
- z.radpar = ZT_RADPAR_UIODATA;
- z.data = 3;
- if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
- {
- ast_log(LOG_ERROR,"Cannot set UIODATA\n");
- return -1;
- }
- }
- /* save pseudo channel conference number */
- myrpt->conf = myrpt->txconf = ci.confno;
+ if (myrpt->txchannel == myrpt->zaptxchannel)
+ {
+ i = ZT_ONHOOK;
+ ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i);
+ /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */
+ if ((myrpt->iofd < 1) && (!res) &&
+ (!strcmp(myrpt->remote,remote_rig_ft897) ||
+ (!strcmp(myrpt->remote,remote_rig_ic706))))
+ {
+ z.radpar = ZT_RADPAR_UIOMODE;
+ z.data = 1;
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
+ {
+ ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
+ return -1;
+ }
+ z.radpar = ZT_RADPAR_UIODATA;
+ z.data = 3;
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
+ {
+ ast_log(LOG_ERROR,"Cannot set UIODATA\n");
+ return -1;
+ }
+ }
+ }
myrpt->remoterx = 0;
myrpt->remotetx = 0;
myrpt->retxtimer = 0;
@@ -11000,19 +11186,22 @@
if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel))
{
i = 128;
- ioctl(myrpt->rxchannel->fds[0],ZT_ECHOCANCEL,&i);
+ ioctl(myrpt->zaprxchannel->fds[0],ZT_ECHOCANCEL,&i);
}
if (chan->_state != AST_STATE_UP) {
ast_answer(chan);
}
- if (ioctl(myrpt->rxchannel->fds[0],ZT_GET_PARAMS,&par) != -1)
- {
- if (par.rxisoffhook)
- {
- ast_indicate(chan,AST_CONTROL_RADIO_KEY);
- myrpt->remoterx = 1;
- remkeyed = 1;
+ if (myrpt->rxchannel == myrpt->zaprxchannel)
+ {
+ if (ioctl(myrpt->zaprxchannel->fds[0],ZT_GET_PARAMS,&par) != -1)
+ {
+ if (par.rxisoffhook)
+ {
+ ast_indicate(chan,AST_CONTROL_RADIO_KEY);
+ myrpt->remoterx = 1;
+ remkeyed = 1;
+ }
}
}
if (myrpt->p.archivedir)
@@ -11268,11 +11457,11 @@
if((myrpt->remtxfreqok = check_tx_freq(myrpt)))
{
time(&myrpt->last_activity_time);
- if (iskenwood_pci4)
+ if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
{
z.radpar = ZT_RADPAR_UIODATA;
z.data = 1;
- if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
{
ast_log(LOG_ERROR,"Cannot set UIODATA\n");
return -1;
@@ -11292,11 +11481,11 @@
if(!myrpt->remtxfreqok){
rpt_telemetry(myrpt,UNAUTHTX,NULL);
}
- if (iskenwood_pci4)
+ if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
{
z.radpar = ZT_RADPAR_UIODATA;
z.data = 3;
- if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
{
ast_log(LOG_ERROR,"Cannot set UIODATA\n");
return -1;
@@ -11569,24 +11758,24 @@
myrpt->lastf1 = NULL;
if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
myrpt->lastf2 = NULL;
- if (iskenwood_pci4)
+ if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
{
z.radpar = ZT_RADPAR_UIOMODE;
z.data = 3;
- if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
{
ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
return -1;
}
z.radpar = ZT_RADPAR_UIODATA;
z.data = 3;
- if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
{
ast_log(LOG_ERROR,"Cannot set UIODATA\n");
return -1;
}
i = ZT_OFFHOOK;
- if (ioctl(myrpt->txchannel->fds[0],ZT_HOOK,&i) == -1)
+ if (ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i) == -1)
{
ast_log(LOG_ERROR,"Cannot set hook\n");
return -1;
Modified: branches/1.4/channels/Makefile
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/Makefile?view=diff&rev=82366&r1=82365&r2=82366
==============================================================================
--- branches/1.4/channels/Makefile (original)
+++ branches/1.4/channels/Makefile Thu Sep 13 19:34:13 2007
@@ -116,3 +116,9 @@
$(if $(filter chan_misdn,$(EMBEDDED_MODS)),modules.link,chan_misdn.so): chan_misdn.o misdn_config.o misdn/isdn_lib.o misdn/isdn_msg_parser.o
chan_vpb.oo: ASTCFLAGS:=$(filter-out -Wdeclaration-after-statement,$(ASTCFLAGS))
+
+chan_usbradio.o: chan_usbradio.c xpmr/xpmr.c xpmr/xpmr.h xpmr/xpmr_coef.h xpmr/sinetabx.h busy.h ringtone.h
+
+chan_usbradio.so: LIBS+=-lusb -lasound
+
+
Added: branches/1.4/channels/chan_usbradio.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/chan_usbradio.c?view=auto&rev=82366
==============================================================================
--- branches/1.4/channels/chan_usbradio.c (added)
+++ branches/1.4/channels/chan_usbradio.c Thu Sep 13 19:34:13 2007
@@ -1,0 +1,2811 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 2007, Jim Dixon
+ *
+ * Jim Dixon, WB6NIL <jim at lambdatel.com>
+ * Steve Henke, W9SH <w9sh at arrl.net>
+ * Based upon work by Mark Spencer <markster at digium.com> and Luigi Rizzo
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Channel driver for CM108 USB Cards with Radio Interface
+ *
+ * \author Jim Dixon <jim at lambdatel.com>
+ * \author Steve Henke <w9sh at arrl.net>
+ *
+ * \par See also
+ * \arg \ref Config_usbradio
+ *
+ * \ingroup channel_drivers
+ */
+
+/*** MODULEINFO
+ <depend>ossaudio</depend>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <usb.h>
+#include <alsa/asoundlib.h>
+
+#define CHAN_USBRADIO 1
+
+#define DEBUG_USBRADIO 0
+#define DEBUG_CAPTURES 1
+
+#define DEBUG_CAP_RX_OUT 0
+#define DEBUG_CAP_TX_OUT 0
+
+#define DEBUG_FILETEST 0
+
+#define RX_CAP_RAW_FILE "/tmp/rx_cap_in.pcm"
+#define RX_CAP_TRACE_FILE "/tmp/rx_trace.pcm"
+#define RX_CAP_OUT_FILE "/tmp/rx_cap_out.pcm"
+
+#define TX_CAP_RAW_FILE "/tmp/tx_cap_in.pcm"
+#define TX_CAP_TRACE_FILE "/tmp/tx_trace.pcm"
+#define TX_CAP_OUT_FILE "/tmp/tx_cap_out.pcm"
+
+#define MIXER_PARAM_MIC_PLAYBACK_SW "Mic Playback Switch"
+#define MIXER_PARAM_MIC_PLAYBACK_VOL "Mic Playback Volume"
+#define MIXER_PARAM_MIC_CAPTURE_SW "Mic Capture Switch"
+#define MIXER_PARAM_MIC_CAPTURE_VOL "Mic Capture Volume"
+#define MIXER_PARAM_MIC_BOOST "Auto Gain Control"
+#define MIXER_PARAM_SPKR_PLAYBACK_SW "Speaker Playback Switch"
+#define MIXER_PARAM_SPKR_PLAYBACK_VOL "Speaker Playback Volume"
+
+#include "./xpmr/xpmr.h"
+
+#if 0
+#define traceusb1(a) {printf a;}
+#else
+#define traceusb1(a)
+#endif
+
+#if 0
+#define traceusb2(a) {printf a;}
+#else
+#define traceusb2(a)
+#endif
+
+#ifdef __linux
+#include <linux/soundcard.h>
+#elif defined(__FreeBSD__)
+#include <sys/soundcard.h>
+#else
+#include <soundcard.h>
+#endif
+
+#include "asterisk/lock.h"
+#include "asterisk/frame.h"
+#include "asterisk/logger.h"
+#include "asterisk/callerid.h"
+#include "asterisk/channel.h"
+#include "asterisk/module.h"
+#include "asterisk/options.h"
+#include "asterisk/pbx.h"
+#include "asterisk/config.h"
+#include "asterisk/cli.h"
+#include "asterisk/utils.h"
+#include "asterisk/causes.h"
+#include "asterisk/endian.h"
+#include "asterisk/stringfields.h"
+#include "asterisk/abstract_jb.h"
+#include "asterisk/musiconhold.h"
+#include "asterisk/dsp.h"
+
+/* ringtones we use */
+#include "busy.h"
+#include "ringtone.h"
+#include "ring10.h"
+#include "answer.h"
+
+#define C108_VENDOR_ID 0x0d8c
+#define C108_PRODUCT_ID 0x000c
+#define C108_HID_INTERFACE 3
+
+#define HID_REPORT_GET 0x01
+#define HID_REPORT_SET 0x09
+
+#define HID_RT_INPUT 0x01
+#define HID_RT_OUTPUT 0x02
+
+/*! Global jitterbuffer configuration - by default, jb is disabled */
+static struct ast_jb_conf default_jbconf =
+{
+ .flags = 0,
+ .max_size = -1,
+ .resync_threshold = -1,
+ .impl = "",
+};
+static struct ast_jb_conf global_jbconf;
+
+/*
+ * usbradio.conf parameters are
+START_CONFIG
+
+[general]
+ ; General config options, with default values shown.
+ ; You should use one section per device, with [general] being used
+ ; for the device.
+ ;
+ ;
+ ; debug = 0x0 ; misc debug flags, default is 0
+
+ ; Set the device to use for I/O
+ ; devicenum = 0
+ ; Set hardware type here
+ ; hdwtype=0 ; 0=limey, 1=sph
+
+ ; rxboostset=0 ; no rx gain boost
+ ; rxctcssrelax=1 ; reduce talkoff from radios w/o CTCSS Tx HPF
+ ; rxctcssfreq=100.0 ; rx ctcss freq in floating point. must be in table
+ ; txctcssfreq=100.0 ; tx ctcss freq, any frequency permitted
+
+ ; carrierfrom=dsp ;no,usb,usbinvert,dsp,vox
+ ; ctcssfrom=dsp ;no,usb,dsp
+
+ ; rxdemod=flat ; input type from radio: no,speaker,flat
+ ; txprelim=yes ; output is pre-emphasised and limited
+ ; txtoctype=no ; no,phase,notone
+
+ ; txmixa=composite ;no,voice,tone,composite,auxvoice
+ ; txmixb=no ;no,voice,tone,composite,auxvoice
+
+ ; invertptt=0
+
+ ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+ ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
+ ; USBRADIO channel. Defaults to "no". An enabled jitterbuffer will
+ ; be used only if the sending side can create and the receiving
+ ; side can not accept jitter. The USBRADIO channel can't accept jitter,
+ ; thus an enabled jitterbuffer on the receive USBRADIO side will always
+ ; be used if the sending side can create jitter.
+
+ ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
+
+ ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
+ ; resynchronized. Useful to improve the quality of the voice, with
+ ; big jumps in/broken timestamps, usualy sent from exotic devices
+ ; and programs. Defaults to 1000.
+
+ ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of an USBRADIO
+ ; channel. Two implementations are currenlty available - "fixed"
+ ; (with size always equals to jbmax-size) and "adaptive" (with
+ ; variable size, actually the new jb of IAX2). Defaults to fixed.
+
+ ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
+ ;-----------------------------------------------------------------------------------
+
+
+END_CONFIG
+
+ */
+
+/*
+ * Helper macros to parse config arguments. They will go in a common
+ * header file if their usage is globally accepted. In the meantime,
+ * we define them here. Typical usage is as below.
+ * Remember to open a block right before M_START (as it declares
+ * some variables) and use the M_* macros WITHOUT A SEMICOLON:
+ *
+ * {
+ * M_START(v->name, v->value)
+ *
+ * M_BOOL("dothis", x->flag1)
+ * M_STR("name", x->somestring)
+ * M_F("bar", some_c_code)
+ * M_END(some_final_statement)
+ * ... other code in the block
+ * }
+ *
+ * XXX NOTE these macros should NOT be replicated in other parts of asterisk.
+ * Likely we will come up with a better way of doing config file parsing.
+ */
+#define M_START(var, val) \
+ char *__s = var; char *__val = val;
+#define M_END(x) x;
+#define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
+#define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
+#define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
+#define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
+
+/*
+ * The following parameters are used in the driver:
+ *
+ * FRAME_SIZE the size of an audio frame, in samples.
+ * 160 is used almost universally, so you should not change it.
+ *
+ * FRAGS the argument for the SETFRAGMENT ioctl.
+ * Overridden by the 'frags' parameter in usbradio.conf
+ *
+ * Bits 0-7 are the base-2 log of the device's block size,
+ * bits 16-31 are the number of blocks in the driver's queue.
+ * There are a lot of differences in the way this parameter
+ * is supported by different drivers, so you may need to
+ * experiment a bit with the value.
+ * A good default for linux is 30 blocks of 64 bytes, which
+ * results in 6 frames of 320 bytes (160 samples).
+ * FreeBSD works decently with blocks of 256 or 512 bytes,
+ * leaving the number unspecified.
+ * Note that this only refers to the device buffer size,
+ * this module will then try to keep the lenght of audio
+ * buffered within small constraints.
+ *
+ * QUEUE_SIZE The max number of blocks actually allowed in the device
+ * driver's buffer, irrespective of the available number.
+ * Overridden by the 'queuesize' parameter in usbradio.conf
+ *
+ * Should be >=2, and at most as large as the hw queue above
+ * (otherwise it will never be full).
+ */
+
+#define FRAME_SIZE 160
+#define QUEUE_SIZE 20
+
+#if defined(__FreeBSD__)
+#define FRAGS 0x8
+#else
+#define FRAGS ( ( (6 * 5) << 16 ) | 0xc )
+#endif
+
+/*
+ * XXX text message sizes are probably 256 chars, but i am
+ * not sure if there is a suitable definition anywhere.
+ */
+#define TEXT_SIZE 256
+
+#if 0
+#define TRYOPEN 1 /* try to open on startup */
+#endif
+#define O_CLOSE 0x444 /* special 'close' mode for device */
+/* Which device to use */
+#if defined( __OpenBSD__ ) || defined( __NetBSD__ )
+#define DEV_DSP "/dev/audio"
+#else
+#define DEV_DSP "/dev/dsp"
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+static char *config = "usbradio.conf"; /* default config file */
+static char *config1 = "usbradio_tune.conf"; /* tune config file */
+
+static FILE *frxcapraw = NULL, *frxcaptrace = NULL, *frxoutraw = NULL;
+static FILE *ftxcapraw = NULL, *ftxcaptrace = NULL, *ftxoutraw = NULL;
+
+static int usbradio_debug;
+#if 0 //maw asdf sph
+static int usbradio_debug_level = 0;
+#endif
+
+enum {RX_AUDIO_NONE,RX_AUDIO_SPEAKER,RX_AUDIO_FLAT};
+enum {CD_IGNORE,CD_XPMR_NOISE,CD_XPMR_VOX,CD_HID,CD_HID_INVERT};
+enum {SD_IGNORE,SD_HID,SD_HID_INVERT,SD_XPMR}; // no,external,externalinvert,software
+enum {RX_KEY_CARRIER,RX_KEY_CARRIER_CODE};
+enum {TX_OUT_OFF,TX_OUT_VOICE,TX_OUT_LSD,TX_OUT_COMPOSITE,TX_OUT_AUX};
+enum {TOC_NONE,TOC_PHASE,TOC_NOTONE};
+
+/* DECLARE STRUCTURES */
+
+/*
+ * Each sound is made of 'datalen' samples of sound, repeated as needed to
+ * generate 'samplen' samples of data, then followed by 'silencelen' samples
+ * of silence. The loop is repeated if 'repeat' is set.
+ */
+struct sound {
+ int ind;
+ char *desc;
+ short *data;
+ int datalen;
+ int samplen;
+ int silencelen;
+ int repeat;
+};
+
+static struct sound sounds[] = {
+ { AST_CONTROL_RINGING, "RINGING", ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
+ { AST_CONTROL_BUSY, "BUSY", busy, sizeof(busy)/2, 4000, 4000, 1 },
+ { AST_CONTROL_CONGESTION, "CONGESTION", busy, sizeof(busy)/2, 2000, 2000, 1 },
+ { AST_CONTROL_RING, "RING10", ring10, sizeof(ring10)/2, 16000, 32000, 1 },
+ { AST_CONTROL_ANSWER, "ANSWER", answer, sizeof(answer)/2, 2200, 0, 0 },
+ { -1, NULL, 0, 0, 0, 0 }, /* end marker */
+};
+
+
+/*
+ * descriptor for one of our channels.
+ * There is one used for 'default' values (from the [general] entry in
+ * the configuration file), and then one instance for each device
+ * (the default is cloned from [general], others are only created
+ * if the relevant section exists).
+ */
+struct chan_usbradio_pvt {
+ struct chan_usbradio_pvt *next;
+
+ char *name;
+ /*
+ * cursound indicates which in struct sound we play. -1 means nothing,
+ * any other value is a valid sound, in which case sampsent indicates
+ * the next sample to send in [0..samplen + silencelen]
+ * nosound is set to disable the audio data from the channel
+ * (so we can play the tones etc.).
+ */
+ int sndcmd[2]; /* Sound command pipe */
+ int cursound; /* index of sound to send */
+ int sampsent; /* # of sound samples sent */
+ int nosound; /* set to block audio from the PBX */
+
+ int total_blocks; /* total blocks in the output device */
+ int sounddev;
+ enum { M_UNSET, M_FULL, M_READ, M_WRITE } duplex;
+ i16 cdMethod;
+ int autoanswer;
+ int autohangup;
+ int hookstate;
+ unsigned int queuesize; /* max fragments in queue */
+ unsigned int frags; /* parameter for SETFRAGMENT */
+
+ int warned; /* various flags used for warnings */
+#define WARN_used_blocks 1
+#define WARN_speed 2
+#define WARN_frag 4
+ int w_errors; /* overfull in the write path */
+ struct timeval lastopen;
+
+ int overridecontext;
+ int mute;
+
+ /* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
+ * be representable in 16 bits to avoid overflows.
+ */
+#define BOOST_SCALE (1<<9)
+#define BOOST_MAX 40 /* slightly less than 7 bits */
+ int boost; /* input boost, scaled by BOOST_SCALE */
+ char devicenum;
+ int spkrmax;
+ int micmax;
+
+ pthread_t sthread;
+ pthread_t hidthread;
+
+ int stophid;
+ struct ast_channel *owner;
+ char ext[AST_MAX_EXTENSION];
+ char ctx[AST_MAX_CONTEXT];
+ char language[MAX_LANGUAGE];
+ char cid_name[256]; /*XXX */
+ char cid_num[256]; /*XXX */
+ char mohinterpret[MAX_MUSICCLASS];
+
+ /* buffers used in usbradio_write, 2 per int by 2 channels by 6 times oversampling (48KS/s) */
+ char usbradio_write_buf[FRAME_SIZE * 2 * 2 * 6];
+ char usbradio_write_buf_1[FRAME_SIZE * 2 * 2* 6];
+
+ int usbradio_write_dst;
+ /* buffers used in usbradio_read - AST_FRIENDLY_OFFSET space for headers
+ * plus enough room for a full frame
+ */
+ char usbradio_read_buf[FRAME_SIZE * (2 * 12) + AST_FRIENDLY_OFFSET];
+ char usbradio_read_buf_8k[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
+ int readpos; /* read position above */
+ struct ast_frame read_f; /* returned by usbradio_read */
+
+
+ char debuglevel;
+ char radioduplex; //
+
+ char lastrx;
+ char rxhidsq;
+ char rxcarrierdetect; // status from pmr channel
+ char rxctcssdecode; // status from pmr channel
+
+ char rxkeytype;
+ char rxkeyed; // indicates rx signal present
+
+ char lasttx;
+ char txkeyed; // tx key request from upper layers
+ char txchankey;
+ char txtestkey;
+
+ time_t lasthidtime;
+ struct ast_dsp *dsp;
+
+ t_pmr_chan *pmrChan;
+
+ char rxcpusaver;
+ char txcpusaver;
+
+ char rxdemod;
+ float rxgain;
+ char rxcdtype;
+ char rxsdtype;
+ int rxsquelchadj; /* this copy needs to be here for initialization */
+ char txtoctype;
+
+ char txprelim;
+ float txctcssgain;
+ char txmixa;
+ char txmixb;
+
+ char invertptt;
+
+ char rxctcssrelax;
+ float rxctcssgain;
+ float rxctcssfreq;
+ float txctcssfreq;
+
+ int rxmixerset;
+ int rxboostset;
+ float rxvoiceadj;
+ float rxctcssadj;
+ int txmixaset;
[... 6991 lines stripped ...]
More information about the svn-commits
mailing list