182c98e8b05d2be7a2c8cde8262c37bb84c58d04
[asterisk/asterisk.git] / channels / chan_usbradio.c
1 #define NEW_ASTERISK
2 /*
3  * Asterisk -- An open source telephony toolkit.
4  *
5  * Copyright (C) 1999 - 2005, Digium, Inc.
6  * Copyright (C) 2007 - 2008, Jim Dixon
7  *
8  * Jim Dixon, WB6NIL <jim@lambdatel.com>
9  * Steve Henke, W9SH  <w9sh@arrl.net>
10  * Based upon work by Mark Spencer <markster@digium.com> and Luigi Rizzo
11  *
12  * See http://www.asterisk.org for more information about
13  * the Asterisk project. Please do not directly contact
14  * any of the maintainers of this project for assistance;
15  * the project provides a web site, mailing lists and IRC
16  * channels for your use.
17  *
18  * This program is free software, distributed under the terms of
19  * the GNU General Public License Version 2. See the LICENSE file
20   * at the top of the source tree.
21  */
22
23 /*! \file
24  *
25  * \brief Channel driver for CM108 USB Cards with Radio Interface
26  *
27  * \author Jim Dixon  <jim@lambdatel.com>
28  * \author Steve Henke  <w9sh@arrl.net>
29  *
30  * \par See also
31  * \arg \ref Config_usbradio
32  *
33  * \ingroup channel_drivers
34  */
35
36 /*** MODULEINFO
37         <depend>ossaudio</depend>
38         <depend>usb</depend>     
39         <defaultenabled>no</defaultenabled>
40         <member name="RADIO_RTX" displayname="Build RTX/DTX Radio Programming">          
41         <defaultenabled>no</defaultenabled>      
42         </member>        
43         <member name="RADIO_XPMRX" displayname="Build Experimental Radio Protocols">     
44         <defaultenabled>no</defaultenabled>      
45         </member>
46  ***/
47
48 // 20070918 1600 EDT sph@xelatec.com changing to rx driven streams
49
50 #include "asterisk.h"
51
52 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
53
54 #include <stdio.h>
55 #include <ctype.h>
56 #include <math.h>
57 #include <string.h>
58 #include <unistd.h>
59 #include <sys/io.h>
60 #include <sys/ioctl.h>
61 #include <fcntl.h>
62 #include <sys/time.h>
63 #include <stdlib.h>
64 #include <errno.h>
65 #include <usb.h>
66 #include <alsa/asoundlib.h>
67
68 //#define HAVE_XPMRX                            1
69 #ifdef RADIO_XPMRX
70 #define HAVE_XPMRX                              1
71 #endif
72
73 #define CHAN_USBRADIO           1
74 #define DEBUG_USBRADIO          0       
75 #define DEBUG_CAPTURES                  1
76 #define DEBUG_CAP_RX_OUT                0               
77 #define DEBUG_CAP_TX_OUT            0                   
78 #define DEBUG_FILETEST                  0                        
79
80 #define RX_CAP_RAW_FILE                 "/tmp/rx_cap_in.pcm"
81 #define RX_CAP_TRACE_FILE               "/tmp/rx_trace.pcm"
82 #define RX_CAP_OUT_FILE                 "/tmp/rx_cap_out.pcm"
83
84 #define TX_CAP_RAW_FILE                 "/tmp/tx_cap_in.pcm"
85 #define TX_CAP_TRACE_FILE               "/tmp/tx_trace.pcm"
86 #define TX_CAP_OUT_FILE                 "/tmp/tx_cap_out.pcm"
87
88 #define MIXER_PARAM_MIC_PLAYBACK_SW "Mic Playback Switch"
89 #define MIXER_PARAM_MIC_PLAYBACK_VOL "Mic Playback Volume"
90 #define MIXER_PARAM_MIC_CAPTURE_SW "Mic Capture Switch"
91 #define MIXER_PARAM_MIC_CAPTURE_VOL "Mic Capture Volume"
92 #define MIXER_PARAM_MIC_BOOST "Auto Gain Control"
93 #define MIXER_PARAM_SPKR_PLAYBACK_SW "Speaker Playback Switch"
94 #define MIXER_PARAM_SPKR_PLAYBACK_VOL "Speaker Playback Volume"
95
96 #define DELIMCHR ','
97 #define QUOTECHR 34
98
99 #define READERR_THRESHOLD 50
100
101 #include "./xpmr/xpmr.h"
102 #ifdef HAVE_XPMRX
103 #include "./xpmrx/xpmrx.h"
104 #include "./xpmrx/bitweight.h"
105 #endif
106
107 #if 0
108 #define traceusb1(a) {printf a;}
109 #else
110 #define traceusb1(a)
111 #endif
112
113 #if 0
114 #define traceusb2(a) {printf a;}
115 #else
116 #define traceusb2(a)
117 #endif
118
119 #ifdef __linux
120 #include <linux/soundcard.h>
121 #elif defined(__FreeBSD__)
122 #include <sys/soundcard.h>
123 #else
124 #include <soundcard.h>
125 #endif
126
127 #include "asterisk/lock.h"
128 #include "asterisk/frame.h"
129 #include "asterisk/logger.h"
130 #include "asterisk/callerid.h"
131 #include "asterisk/channel.h"
132 #include "asterisk/module.h"
133 #include "asterisk/options.h"
134 #include "asterisk/pbx.h"
135 #include "asterisk/config.h"
136 #include "asterisk/cli.h"
137 #include "asterisk/utils.h"
138 #include "asterisk/causes.h"
139 #include "asterisk/endian.h"
140 #include "asterisk/stringfields.h"
141 #include "asterisk/abstract_jb.h"
142 #include "asterisk/musiconhold.h"
143 #include "asterisk/dsp.h"
144
145 #ifndef NEW_ASTERISK
146
147 /* ringtones we use */
148 #include "busy.h"
149 #include "ringtone.h"
150 #include "ring10.h"
151 #include "answer.h"
152
153 #endif
154
155 #define C108_VENDOR_ID          0x0d8c
156 #define C108_PRODUCT_ID         0x000c
157 #define C108_HID_INTERFACE      3
158
159 #define HID_REPORT_GET          0x01
160 #define HID_REPORT_SET          0x09
161
162 #define HID_RT_INPUT            0x01
163 #define HID_RT_OUTPUT           0x02
164
165 #define EEPROM_START_ADDR       6
166 #define EEPROM_END_ADDR         63
167 #define EEPROM_PHYSICAL_LEN     64
168 #define EEPROM_TEST_ADDR        EEPROM_END_ADDR
169 #define EEPROM_MAGIC_ADDR       6
170 #define EEPROM_MAGIC            34329
171 #define EEPROM_CS_ADDR          62
172 #define EEPROM_RXMIXERSET       8
173 #define EEPROM_TXMIXASET        9
174 #define EEPROM_TXMIXBSET        10
175 #define EEPROM_RXVOICEADJ       11
176 #define EEPROM_RXCTCSSADJ       13
177 #define EEPROM_TXCTCSSADJ       15
178 #define EEPROM_RXSQUELCHADJ     16
179
180 /*! Global jitterbuffer configuration - by default, jb is disabled */
181 static struct ast_jb_conf default_jbconf =
182 {
183         .flags = 0,
184         .max_size = -1,
185         .resync_threshold = -1,
186         .impl = "",
187 };
188 static struct ast_jb_conf global_jbconf;
189
190 /*
191  * usbradio.conf parameters are
192 START_CONFIG
193
194 [general]
195     ; General config options which propigate to all devices, with
196     ; default values shown. You may have as many devices as the
197     ; system will allow. You must use one section per device, with
198     ; [usb] generally (although its up to you) being the first device.
199     ;
200     ;
201     ; debug = 0x0               ; misc debug flags, default is 0
202
203         ; Set the device to use for I/O
204         ; devicenum = 0
205         ; Set hardware type here
206         ; hdwtype=0               ; 0=limey, 1=sph
207
208         ; rxboost=0          ; no rx gain boost
209         ; rxctcssrelax=1        ; reduce talkoff from radios w/o CTCSS Tx HPF
210         ; rxctcssfreqs=100.0,123.0      ; list of rx ctcss freq in floating point. must be in table
211         ; txctcssfreqs=100.0,123.0      ; list tx ctcss freq, any frequency permitted
212         ; txctcssdefault=100.0      ; default tx ctcss freq, any frequency permitted
213
214         ; carrierfrom=dsp     ;no,usb,usbinvert,dsp,vox
215         ; ctcssfrom=dsp       ;no,usb,dsp
216
217         ; rxdemod=flat            ; input type from radio: no,speaker,flat
218         ; txprelim=yes            ; output is pre-emphasised and limited
219         ; txtoctype=no            ; no,phase,notone
220
221         ; txmixa=composite        ;no,voice,tone,composite,auxvoice
222         ; txmixb=no               ;no,voice,tone,composite,auxvoice
223
224         ; invertptt=0
225
226     ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
227     ; jbenable = yes              ; Enables the use of a jitterbuffer on the receiving side of an
228                                   ; USBRADIO channel. Defaults to "no". An enabled jitterbuffer will
229                                   ; be used only if the sending side can create and the receiving
230                                   ; side can not accept jitter. The USBRADIO channel can't accept jitter,
231                                   ; thus an enabled jitterbuffer on the receive USBRADIO side will always
232                                   ; be used if the sending side can create jitter.
233
234     ; jbmaxsize = 200             ; Max length of the jitterbuffer in milliseconds.
235
236     ; jbresyncthreshold = 1000    ; Jump in the frame timestamps over which the jitterbuffer is
237                                   ; resynchronized. Useful to improve the quality of the voice, with
238                                   ; big jumps in/broken timestamps, usualy sent from exotic devices
239                                   ; and programs. Defaults to 1000.
240
241     ; jbimpl = fixed              ; Jitterbuffer implementation, used on the receiving side of an USBRADIO
242                                   ; channel. Two implementations are currenlty available - "fixed"
243                                   ; (with size always equals to jbmax-size) and "adaptive" (with
244                                   ; variable size, actually the new jb of IAX2). Defaults to fixed.
245
246     ; jblog = no                  ; Enables jitterbuffer frame logging. Defaults to "no".
247     ;-----------------------------------------------------------------------------------
248
249 [usb]
250
251 ; First channel unique config
252
253 [usb1]
254
255 ; Second channel config
256
257 END_CONFIG
258
259  */
260
261 /*
262  * Helper macros to parse config arguments. They will go in a common
263  * header file if their usage is globally accepted. In the meantime,
264  * we define them here. Typical usage is as below.
265  * Remember to open a block right before M_START (as it declares
266  * some variables) and use the M_* macros WITHOUT A SEMICOLON:
267  *
268  *      {
269  *              M_START(v->name, v->value) 
270  *
271  *              M_BOOL("dothis", x->flag1)
272  *              M_STR("name", x->somestring)
273  *              M_F("bar", some_c_code)
274  *              M_END(some_final_statement)
275  *              ... other code in the block
276  *      }
277  *
278  * XXX NOTE these macros should NOT be replicated in other parts of asterisk. 
279  * Likely we will come up with a better way of doing config file parsing.
280  */
281 #define M_START(var, val) \
282         char *__s = var; char *__val = val;
283 #define M_END(x)   x;
284 #define M_F(tag, f)                     if (!strcasecmp((__s), tag)) { f; } else
285 #define M_BOOL(tag, dst)        M_F(tag, (dst) = ast_true(__val) )
286 #define M_UINT(tag, dst)        M_F(tag, (dst) = strtoul(__val, NULL, 0) )
287 #define M_STR(tag, dst)         M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
288
289 /*
290  * The following parameters are used in the driver:
291  *
292  *  FRAME_SIZE  the size of an audio frame, in samples.
293  *              160 is used almost universally, so you should not change it.
294  *
295  *  FRAGS       the argument for the SETFRAGMENT ioctl.
296  *              Overridden by the 'frags' parameter in usbradio.conf
297  *
298  *              Bits 0-7 are the base-2 log of the device's block size,
299  *              bits 16-31 are the number of blocks in the driver's queue.
300  *              There are a lot of differences in the way this parameter
301  *              is supported by different drivers, so you may need to
302  *              experiment a bit with the value.
303  *              A good default for linux is 30 blocks of 64 bytes, which
304  *              results in 6 frames of 320 bytes (160 samples).
305  *              FreeBSD works decently with blocks of 256 or 512 bytes,
306  *              leaving the number unspecified.
307  *              Note that this only refers to the device buffer size,
308  *              this module will then try to keep the lenght of audio
309  *              buffered within small constraints.
310  *
311  *  QUEUE_SIZE  The max number of blocks actually allowed in the device
312  *              driver's buffer, irrespective of the available number.
313  *              Overridden by the 'queuesize' parameter in usbradio.conf
314  *
315  *              Should be >=2, and at most as large as the hw queue above
316  *              (otherwise it will never be full).
317  */
318
319 #define FRAME_SIZE      160
320 #define QUEUE_SIZE      2                               
321
322 #if defined(__FreeBSD__)
323 #define FRAGS   0x8
324 #else
325 #define FRAGS   ( ( (6 * 5) << 16 ) | 0xc )
326 #endif
327
328 /*
329  * XXX text message sizes are probably 256 chars, but i am
330  * not sure if there is a suitable definition anywhere.
331  */
332 #define TEXT_SIZE       256
333
334 #if 0
335 #define TRYOPEN 1                               /* try to open on startup */
336 #endif
337 #define O_CLOSE 0x444                   /* special 'close' mode for device */
338 /* Which device to use */
339 #if defined( __OpenBSD__ ) || defined( __NetBSD__ )
340 #define DEV_DSP "/dev/audio"
341 #else
342 #define DEV_DSP "/dev/dsp"
343 #endif
344
345 #ifndef MIN
346 #define MIN(a,b) ((a) < (b) ? (a) : (b))
347 #endif
348 #ifndef MAX
349 #define MAX(a,b) ((a) > (b) ? (a) : (b))
350 #endif
351
352 static char *config = "usbradio.conf";  /* default config file */
353 static char *config1 = "usbradio_tune_%s.conf";    /* tune config file */
354
355 static FILE *frxcapraw = NULL, *frxcaptrace = NULL, *frxoutraw = NULL;
356 static FILE *ftxcapraw = NULL, *ftxcaptrace = NULL, *ftxoutraw = NULL;
357
358 static char *usb_device_list = NULL;
359 static int usb_device_list_size = 0;
360
361 static int usbradio_debug;
362 #if 0 //maw asdf sph
363 static int usbradio_debug_level = 0;
364 #endif
365
366 enum {RX_AUDIO_NONE,RX_AUDIO_SPEAKER,RX_AUDIO_FLAT};
367 enum {CD_IGNORE,CD_XPMR_NOISE,CD_XPMR_VOX,CD_HID,CD_HID_INVERT};
368 enum {SD_IGNORE,SD_HID,SD_HID_INVERT,SD_XPMR};                                   // no,external,externalinvert,software
369 enum {RX_KEY_CARRIER,RX_KEY_CARRIER_CODE};
370 enum {TX_OUT_OFF,TX_OUT_VOICE,TX_OUT_LSD,TX_OUT_COMPOSITE,TX_OUT_AUX};
371 enum {TOC_NONE,TOC_PHASE,TOC_NOTONE};
372
373 /*      DECLARE STRUCTURES */
374
375 /*
376  * Each sound is made of 'datalen' samples of sound, repeated as needed to
377  * generate 'samplen' samples of data, then followed by 'silencelen' samples
378  * of silence. The loop is repeated if 'repeat' is set.
379  */
380 struct sound {
381         int ind;
382         char *desc;
383         short *data;
384         int datalen;
385         int samplen;
386         int silencelen;
387         int repeat;
388 };
389
390 #ifndef NEW_ASTERISK
391
392 static struct sound sounds[] = {
393         { AST_CONTROL_RINGING, "RINGING", ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
394         { AST_CONTROL_BUSY, "BUSY", busy, sizeof(busy)/2, 4000, 4000, 1 },
395         { AST_CONTROL_CONGESTION, "CONGESTION", busy, sizeof(busy)/2, 2000, 2000, 1 },
396         { AST_CONTROL_RING, "RING10", ring10, sizeof(ring10)/2, 16000, 32000, 1 },
397         { AST_CONTROL_ANSWER, "ANSWER", answer, sizeof(answer)/2, 2200, 0, 0 },
398         { -1, NULL, 0, 0, 0, 0 },       /* end marker */
399 };
400
401 #endif
402
403 /*
404  * descriptor for one of our channels.
405  * There is one used for 'default' values (from the [general] entry in
406  * the configuration file), and then one instance for each device
407  * (the default is cloned from [general], others are only created
408  * if the relevant section exists).
409  */
410 struct chan_usbradio_pvt {
411         struct chan_usbradio_pvt *next;
412
413         char *name;
414 #ifndef NEW_ASTERISK
415         /*
416          * cursound indicates which in struct sound we play. -1 means nothing,
417          * any other value is a valid sound, in which case sampsent indicates
418          * the next sample to send in [0..samplen + silencelen]
419          * nosound is set to disable the audio data from the channel
420          * (so we can play the tones etc.).
421          */
422         int sndcmd[2];                          /* Sound command pipe */
423         int cursound;                           /* index of sound to send */
424         int sampsent;                           /* # of sound samples sent  */
425         int nosound;                            /* set to block audio from the PBX */
426 #endif
427
428         int pttkick[2];
429         int total_blocks;                       /* total blocks in the output device */
430         int sounddev;
431         enum { M_UNSET, M_FULL, M_READ, M_WRITE } duplex;
432         i16 cdMethod;
433         int autoanswer;
434         int autohangup;
435         int hookstate;
436         unsigned int queuesize;         /* max fragments in queue */
437         unsigned int frags;                     /* parameter for SETFRAGMENT */
438
439         int warned;                                     /* various flags used for warnings */
440 #define WARN_used_blocks        1
441 #define WARN_speed              2
442 #define WARN_frag               4
443         int w_errors;                           /* overfull in the write path */
444         struct timeval lastopen;
445
446         int overridecontext;
447         int mute;
448
449         /* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
450          * be representable in 16 bits to avoid overflows.
451          */
452 #define BOOST_SCALE     (1<<9)
453 #define BOOST_MAX       40                      /* slightly less than 7 bits */
454         int boost;                                      /* input boost, scaled by BOOST_SCALE */
455         char devicenum;
456         char devstr[128];
457         int spkrmax;
458         int micmax;
459
460 #ifndef NEW_ASTERISK
461         pthread_t sthread;
462 #endif
463         pthread_t hidthread;
464
465         int stophid;
466         FILE *hkickhid;
467
468         struct ast_channel *owner;
469         char ext[AST_MAX_EXTENSION];
470         char ctx[AST_MAX_CONTEXT];
471         char language[MAX_LANGUAGE];
472         char cid_name[256];                     /*XXX */
473         char cid_num[256];                      /*XXX */
474         char mohinterpret[MAX_MUSICCLASS];
475
476         /* buffers used in usbradio_write, 2 per int by 2 channels by 6 times oversampling (48KS/s) */
477         char usbradio_write_buf[FRAME_SIZE * 2 * 2 * 6];    
478         char usbradio_write_buf_1[FRAME_SIZE * 2 * 2* 6];
479
480         int usbradio_write_dst;
481         /* buffers used in usbradio_read - AST_FRIENDLY_OFFSET space for headers
482          * plus enough room for a full frame
483          */
484         char usbradio_read_buf[FRAME_SIZE * (2 * 12) + AST_FRIENDLY_OFFSET];
485         char usbradio_read_buf_8k[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
486         int readpos;                            /* read position above */
487         struct ast_frame read_f;        /* returned by usbradio_read */
488
489         char    debuglevel;
490         char    radioduplex;                    // 
491         char    wanteeprom;
492
493         int     tracetype;
494         int     tracelevel;
495         char    area;
496         char    rptnum;
497         int     idleinterval;
498         int             turnoffs;
499         int     txsettletime;
500         char    ukey[48];
501
502         char lastrx;
503         char rxhidsq;
504         char rxcarrierdetect;           // status from pmr channel
505         char rxctcssdecode;                     // status from pmr channel
506
507         int  rxdcsdecode;
508         int  rxlsddecode;
509
510         char rxkeytype;
511         char rxkeyed;                           // indicates rx signal present
512
513         char lasttx;
514         char txkeyed;                           // tx key request from upper layers 
515         char txchankey;
516         char txtestkey;
517
518         time_t lasthidtime;
519     struct ast_dsp *dsp;
520
521         t_pmr_chan      *pmrChan;
522
523         char    rxcpusaver;
524         char    txcpusaver;
525
526         char    rxdemod;
527         float   rxgain;
528         char    rxcdtype;
529         char    rxsdtype;
530         int             rxsquelchadj;   /* this copy needs to be here for initialization */
531         int     rxsqvoxadj;
532         char    txtoctype;
533
534         char    txprelim;
535         float   txctcssgain;
536         char    txmixa;
537         char    txmixb;
538
539         char    invertptt;
540
541         char    rxctcssrelax;
542         float   rxctcssgain;
543
544         char    txctcssdefault[16];                             // for repeater operation
545         char    rxctcssfreqs[512];                              // a string
546         char    txctcssfreqs[512];
547
548         char    txctcssfreq[32];                                // encode now
549         char    rxctcssfreq[32];                                // decode now
550
551         char    numrxctcssfreqs;                                // how many
552         char    numtxctcssfreqs;
553
554         char    *rxctcss[CTCSS_NUM_CODES];              // pointers to strings
555         char    *txctcss[CTCSS_NUM_CODES];
556
557         int     txfreq;                                                 // in Hz
558         int     rxfreq;
559
560         //              start remote operation info
561         char    set_txctcssdefault[16];                         // for remote operation
562         char    set_txctcssfreq[16];                            // encode now
563         char    set_rxctcssfreq[16];                            // decode now
564
565         char    set_numrxctcssfreqs;                            // how many
566         char    set_numtxctcssfreqs;
567
568         char    set_rxctcssfreqs[16];                           // a string
569         char    set_txctcssfreqs[16];
570
571         char    *set_rxctcss;                                       // pointers to strings
572         char    *set_txctcss;
573
574         int     set_txfreq;                                                     // in Hz
575         int     set_rxfreq;
576         //              end remote operation info
577
578         int             rxmixerset;             
579         int     rxboostset;
580         float   rxvoiceadj;
581         float   rxctcssadj;
582         int     txmixaset;
583         int     txmixbset;
584         int     txctcssadj;
585
586         int     hdwtype;
587         int             hid_gpio_ctl;           
588         int             hid_gpio_ctl_loc;       
589         int             hid_io_cor;             
590         int             hid_io_cor_loc;         
591         int             hid_io_ctcss;           
592         int             hid_io_ctcss_loc;       
593         int             hid_io_ptt;             
594         int             hid_gpio_loc;           
595
596         struct {
597             unsigned rxcapraw:1;
598                 unsigned txcapraw:1;
599                 unsigned txcap2:1;
600                 unsigned rxcap2:1;
601                 unsigned rxplmon:1;
602                 unsigned remoted:1;
603                 unsigned txpolarity:1;
604                 unsigned rxpolarity:1;
605                 unsigned dcstxpolarity:1;
606                 unsigned dcsrxpolarity:1;
607                 unsigned lsdtxpolarity:1;
608                 unsigned lsdrxpolarity:1;
609                 unsigned loopback:1;
610                 unsigned radioactive:1;
611         }b;
612         unsigned short eeprom[EEPROM_PHYSICAL_LEN];
613         char eepromctl;
614         ast_mutex_t eepromlock;
615
616         struct usb_dev_handle *usb_handle;
617         int readerrs;
618 };
619
620 // maw add additional defaults !!!
621 static struct chan_usbradio_pvt usbradio_default = {
622 #ifndef NEW_ASTERISK
623         .cursound = -1,
624 #endif
625         .sounddev = -1,
626         .duplex = M_UNSET,                      /* XXX check this */
627         .autoanswer = 1,
628         .autohangup = 1,
629         .queuesize = QUEUE_SIZE,
630         .frags = FRAGS,
631         .ext = "s",
632         .ctx = "default",
633         .readpos = AST_FRIENDLY_OFFSET, /* start here on reads */
634         .lastopen = { 0, 0 },
635         .boost = BOOST_SCALE,
636         .wanteeprom = 1,
637         .area = 0,
638         .rptnum = 0,
639 };
640
641 /*      DECLARE FUNCTION PROTOTYPES     */
642
643 static void store_txtoctype(struct chan_usbradio_pvt *o, char *s);
644 static int      hidhdwconfig(struct chan_usbradio_pvt *o);
645 static int set_txctcss_level(struct chan_usbradio_pvt *o);
646 static void pmrdump(struct chan_usbradio_pvt *o);
647 static void mult_set(struct chan_usbradio_pvt *o);
648 static int  mult_calc(int value);
649 static void mixer_write(struct chan_usbradio_pvt *o);
650 static void tune_rxinput(int fd, struct chan_usbradio_pvt *o);
651 static void tune_rxvoice(int fd, struct chan_usbradio_pvt *o);
652 static void tune_rxctcss(int fd, struct chan_usbradio_pvt *o);
653 static void tune_txoutput(struct chan_usbradio_pvt *o, int value, int fd);
654 static void tune_write(struct chan_usbradio_pvt *o);
655
656 static char *usbradio_active;    /* the active device */
657
658 static int setformat(struct chan_usbradio_pvt *o, int mode);
659
660 static struct ast_channel *usbradio_request(const char *type, int format, void *data
661 , int *cause);
662 static int usbradio_digit_begin(struct ast_channel *c, char digit);
663 static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration);
664 static int usbradio_text(struct ast_channel *c, const char *text);
665 static int usbradio_hangup(struct ast_channel *c);
666 static int usbradio_answer(struct ast_channel *c);
667 static struct ast_frame *usbradio_read(struct ast_channel *chan);
668 static int usbradio_call(struct ast_channel *c, char *dest, int timeout);
669 static int usbradio_write(struct ast_channel *chan, struct ast_frame *f);
670 static int usbradio_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
671 static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
672 static int xpmr_config(struct chan_usbradio_pvt *o);
673
674 #if     DEBUG_FILETEST == 1
675 static int RxTestIt(struct chan_usbradio_pvt *o);
676 #endif
677
678 static char tdesc[] = "USB (CM108) Radio Channel Driver";
679
680 static const struct ast_channel_tech usbradio_tech = {
681         .type = "Radio",
682         .description = tdesc,
683         .capabilities = AST_FORMAT_SLINEAR,
684         .requester = usbradio_request,
685         .send_digit_begin = usbradio_digit_begin,
686         .send_digit_end = usbradio_digit_end,
687         .send_text = usbradio_text,
688         .hangup = usbradio_hangup,
689         .answer = usbradio_answer,
690         .read = usbradio_read,
691         .call = usbradio_call,
692         .write = usbradio_write,
693         .indicate = usbradio_indicate,
694         .fixup = usbradio_fixup,
695 };
696
697 /* Call with:  devnum: alsa major device number, param: ascii Formal
698 Parameter Name, val1, first or only value, val2 second value, or 0 
699 if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
700
701 Note: must add -lasound to end of linkage */
702
703 static int amixer_max(int devnum,char *param)
704 {
705 int     rv,type;
706 char    str[100];
707 snd_hctl_t *hctl;
708 snd_ctl_elem_id_t *id;
709 snd_hctl_elem_t *elem;
710 snd_ctl_elem_info_t *info;
711
712         sprintf(str,"hw:%d",devnum);
713         if (snd_hctl_open(&hctl, str, 0)) return(-1);
714         snd_hctl_load(hctl);
715         snd_ctl_elem_id_alloca(&id);
716         snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
717         snd_ctl_elem_id_set_name(id, param);  
718         elem = snd_hctl_find_elem(hctl, id);
719         if (!elem)
720         {
721                 snd_hctl_close(hctl);
722                 return(-1);
723         }
724         snd_ctl_elem_info_alloca(&info);
725         snd_hctl_elem_info(elem,info);
726         type = snd_ctl_elem_info_get_type(info);
727         rv = 0;
728         switch(type)
729         {
730             case SND_CTL_ELEM_TYPE_INTEGER:
731                 rv = snd_ctl_elem_info_get_max(info);
732                 break;
733             case SND_CTL_ELEM_TYPE_BOOLEAN:
734                 rv = 1;
735                 break;
736         }
737         snd_hctl_close(hctl);
738         return(rv);
739 }
740
741 /* Call with:  devnum: alsa major device number, param: ascii Formal
742 Parameter Name, val1, first or only value, val2 second value, or 0 
743 if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
744
745 Note: must add -lasound to end of linkage */
746
747 static int setamixer(int devnum,char *param, int v1, int v2)
748 {
749 int     type;
750 char    str[100];
751 snd_hctl_t *hctl;
752 snd_ctl_elem_id_t *id;
753 snd_ctl_elem_value_t *control;
754 snd_hctl_elem_t *elem;
755 snd_ctl_elem_info_t *info;
756
757         sprintf(str,"hw:%d",devnum);
758         if (snd_hctl_open(&hctl, str, 0)) return(-1);
759         snd_hctl_load(hctl);
760         snd_ctl_elem_id_alloca(&id);
761         snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
762         snd_ctl_elem_id_set_name(id, param);  
763         elem = snd_hctl_find_elem(hctl, id);
764         if (!elem)
765         {
766                 snd_hctl_close(hctl);
767                 return(-1);
768         }
769         snd_ctl_elem_info_alloca(&info);
770         snd_hctl_elem_info(elem,info);
771         type = snd_ctl_elem_info_get_type(info);
772         snd_ctl_elem_value_alloca(&control);
773         snd_ctl_elem_value_set_id(control, id);    
774         switch(type)
775         {
776             case SND_CTL_ELEM_TYPE_INTEGER:
777                 snd_ctl_elem_value_set_integer(control, 0, v1);
778                 if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2);
779                 break;
780             case SND_CTL_ELEM_TYPE_BOOLEAN:
781                 snd_ctl_elem_value_set_integer(control, 0, (v1 != 0));
782                 break;
783         }
784         if (snd_hctl_elem_write(elem, control))
785         {
786                 snd_hctl_close(hctl);
787                 return(-1);
788         }
789         snd_hctl_close(hctl);
790         return(0);
791 }
792
793 static void hid_set_outputs(struct usb_dev_handle *handle,
794          unsigned char *outputs)
795 {
796         usleep(1500);
797         usb_control_msg(handle,
798               USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
799               HID_REPORT_SET,
800               0 + (HID_RT_OUTPUT << 8),
801               C108_HID_INTERFACE,
802               (char*)outputs, 4, 5000);
803 }
804
805 static void hid_get_inputs(struct usb_dev_handle *handle,
806          unsigned char *inputs)
807 {
808         usleep(1500);
809         usb_control_msg(handle,
810               USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
811               HID_REPORT_GET,
812               0 + (HID_RT_INPUT << 8),
813               C108_HID_INTERFACE,
814               (char*)inputs, 4, 5000);
815 }
816
817 static unsigned short read_eeprom(struct usb_dev_handle *handle, int addr)
818 {
819         unsigned char buf[4];
820
821         buf[0] = 0x80;
822         buf[1] = 0;
823         buf[2] = 0;
824         buf[3] = 0x80 | (addr & 0x3f);
825         hid_set_outputs(handle,buf);
826         memset(buf,0,sizeof(buf));
827         hid_get_inputs(handle,buf);
828         return(buf[1] + (buf[2] << 8));
829 }
830
831 static void write_eeprom(struct usb_dev_handle *handle, int addr, 
832    unsigned short data)
833 {
834
835         unsigned char buf[4];
836
837         buf[0] = 0x80;
838         buf[1] = data & 0xff;
839         buf[2] = data >> 8;
840         buf[3] = 0xc0 | (addr & 0x3f);
841         hid_set_outputs(handle,buf);
842 }
843
844 static unsigned short get_eeprom(struct usb_dev_handle *handle,
845         unsigned short *buf)
846 {
847 int     i;
848 unsigned short cs;
849
850         cs = 0xffff;
851         for(i = EEPROM_START_ADDR; i < EEPROM_END_ADDR; i++)
852         {
853                 cs += buf[i] = read_eeprom(handle,i);
854         }
855         return(cs);
856 }
857
858 static void put_eeprom(struct usb_dev_handle *handle,unsigned short *buf)
859 {
860 int     i;
861 unsigned short cs;
862
863         cs = 0xffff;
864         buf[EEPROM_MAGIC_ADDR] = EEPROM_MAGIC;
865         for(i = EEPROM_START_ADDR; i < EEPROM_CS_ADDR; i++)
866         {
867                 write_eeprom(handle,i,buf[i]);
868                 cs += buf[i];
869         }
870         buf[EEPROM_CS_ADDR] = (65535 - cs) + 1;
871         write_eeprom(handle,i,buf[EEPROM_CS_ADDR]);
872 }
873
874 static struct usb_device *hid_device_init(char *desired_device)
875 {
876     struct usb_bus *usb_bus;
877     struct usb_device *dev;
878     char devstr[200],str[200],desdev[200],*cp;
879     int i;
880     FILE *fp;
881
882     usb_init();
883     usb_find_busses();
884     usb_find_devices();
885     for (usb_bus = usb_busses;
886          usb_bus;
887          usb_bus = usb_bus->next) {
888         for (dev = usb_bus->devices;
889              dev;
890              dev = dev->next) {
891             if ((dev->descriptor.idVendor
892                   == C108_VENDOR_ID) &&
893                 (dev->descriptor.idProduct
894                   == C108_PRODUCT_ID))
895                 {
896                         sprintf(devstr,"%s/%s", usb_bus->dirname,dev->filename);
897                         for(i = 0; i < 32; i++)
898                         {
899                                 sprintf(str,"/proc/asound/card%d/usbbus",i);
900                                 fp = fopen(str,"r");
901                                 if (!fp) continue;
902                                 if ((!fgets(desdev,sizeof(desdev) - 1,fp)) || (!desdev[0]))
903                                 {
904                                         fclose(fp);
905                                         continue;
906                                 }
907                                 fclose(fp);
908                                 if (desdev[strlen(desdev) - 1] == '\n')
909                                         desdev[strlen(desdev) -1 ] = 0;
910                                 if (strcasecmp(desdev,devstr)) continue;
911                                 if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
912                                 else strcpy(str,"/sys/class/sound/dsp/device");
913                                 memset(desdev,0,sizeof(desdev));
914                                 if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
915                                 {
916                                         sprintf(str,"/sys/class/sound/controlC%d/device",i);
917                                         memset(desdev,0,sizeof(desdev));
918                                         if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
919                                 }
920                                 cp = strrchr(desdev,'/');
921                                 if (cp) *cp = 0; else continue;
922                                 cp = strrchr(desdev,'/');
923                                 if (!cp) continue;
924                                 cp++;
925                                 break;
926                         }
927                         if (i >= 32) continue;
928                         if (!strcmp(cp,desired_device)) return dev;
929                 }
930
931         }
932     }
933     return NULL;
934 }
935
936 static int hid_device_mklist(void)
937 {
938     struct usb_bus *usb_bus;
939     struct usb_device *dev;
940     char devstr[200],str[200],desdev[200],*cp;
941     int i;
942     FILE *fp;
943
944     usb_device_list = ast_malloc(2);
945     if (!usb_device_list) return -1;
946     memset(usb_device_list,0,2);
947
948     usb_init();
949     usb_find_busses();
950     usb_find_devices();
951     for (usb_bus = usb_busses;
952          usb_bus;
953          usb_bus = usb_bus->next) {
954         for (dev = usb_bus->devices;
955              dev;
956              dev = dev->next) {
957             if ((dev->descriptor.idVendor
958                   == C108_VENDOR_ID) &&
959                 (dev->descriptor.idProduct
960                   == C108_PRODUCT_ID))
961                 {
962                         sprintf(devstr,"%s/%s", usb_bus->dirname,dev->filename);
963                         for(i = 0;i < 32; i++)
964                         {
965                                 sprintf(str,"/proc/asound/card%d/usbbus",i);
966                                 fp = fopen(str,"r");
967                                 if (!fp) continue;
968                                 if ((!fgets(desdev,sizeof(desdev) - 1,fp)) || (!desdev[0]))
969                                 {
970                                         fclose(fp);
971                                         continue;
972                                 }
973                                 fclose(fp);
974                                 if (desdev[strlen(desdev) - 1] == '\n')
975                                         desdev[strlen(desdev) -1 ] = 0;
976                                 if (strcasecmp(desdev,devstr)) continue;
977                                 if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
978                                 else strcpy(str,"/sys/class/sound/dsp/device");
979                                 memset(desdev,0,sizeof(desdev));
980                                 if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
981                                 {
982                                         sprintf(str,"/sys/class/sound/controlC%d/device",i);
983                                         memset(desdev,0,sizeof(desdev));
984                                         if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
985                                 }
986                                 cp = strrchr(desdev,'/');
987                                 if (cp) *cp = 0; else continue;
988                                 cp = strrchr(desdev,'/');
989                                 if (!cp) continue;
990                                 cp++;
991                                 break;
992                         }
993                         if (i >= 32) return -1;
994                         usb_device_list = ast_realloc(usb_device_list,
995                                 usb_device_list_size + 2 +
996                                         strlen(cp));
997                         if (!usb_device_list) return -1;
998                         usb_device_list_size += strlen(cp) + 2;
999                         i = 0;
1000                         while(usb_device_list[i])
1001                         {
1002                                 i += strlen(usb_device_list + i) + 1;
1003                         }
1004                         strcat(usb_device_list + i,cp);
1005                         usb_device_list[strlen(cp) + i + 1] = 0;
1006                 }
1007
1008         }
1009     }
1010     return 0;
1011 }
1012
1013 /* returns internal formatted string from external one */
1014 static int usb_get_usbdev(char *devstr)
1015 {
1016 int     i;
1017 char    str[200],desdev[200],*cp;
1018
1019         for(i = 0;i < 32; i++)
1020         {
1021                 if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
1022                 else strcpy(str,"/sys/class/sound/dsp/device");
1023                 memset(desdev,0,sizeof(desdev));
1024                 if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
1025                 {
1026                         sprintf(str,"/sys/class/sound/controlC%d/device",i);
1027                         memset(desdev,0,sizeof(desdev));
1028                         if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
1029                 }
1030                 cp = strrchr(desdev,'/');
1031                 if (cp) *cp = 0; else continue;
1032                 cp = strrchr(desdev,'/');
1033                 if (!cp) continue;
1034                 cp++;
1035                 if (!strcasecmp(cp,devstr)) break;
1036         }
1037         if (i >= 32) return -1;
1038         return i;
1039
1040 }
1041
1042 static int usb_list_check(char *devstr)
1043 {
1044
1045 char *s = usb_device_list;
1046
1047         if (!s) return(0);
1048         while(*s)
1049         {
1050                 if (!strcasecmp(s,devstr)) return(1);
1051                 s += strlen(s) + 1;
1052         }
1053         return(0);
1054 }
1055
1056
1057 static int      hidhdwconfig(struct chan_usbradio_pvt *o)
1058 {
1059         if(o->hdwtype==1)         //sphusb
1060         {
1061                 o->hid_gpio_ctl         =  0x08;        /* set GPIO4 to output mode */
1062                 o->hid_gpio_ctl_loc     =  2;   /* For CTL of GPIO */
1063                 o->hid_io_cor           =  4;   /* GPIO3 is COR */
1064                 o->hid_io_cor_loc       =  1;   /* GPIO3 is COR */
1065                 o->hid_io_ctcss         =  2;   /* GPIO 2 is External CTCSS */
1066                 o->hid_io_ctcss_loc =  1;       /* is GPIO 2 */
1067                 o->hid_io_ptt           =  8;   /* GPIO 4 is PTT */
1068                 o->hid_gpio_loc         =  1;   /* For ALL GPIO */
1069         }
1070         else if(o->hdwtype==0)  //dudeusb
1071         {
1072                 o->hid_gpio_ctl         =  0x0c;        /* set GPIO 3 & 4 to output mode */
1073                 o->hid_gpio_ctl_loc     =  2;   /* For CTL of GPIO */
1074                 o->hid_io_cor           =  2;   /* VOLD DN is COR */
1075                 o->hid_io_cor_loc       =  0;   /* VOL DN COR */
1076                 o->hid_io_ctcss         =  2;   /* GPIO 2 is External CTCSS */
1077                 o->hid_io_ctcss_loc =  1;       /* is GPIO 2 */
1078                 o->hid_io_ptt           =  4;   /* GPIO 3 is PTT */
1079                 o->hid_gpio_loc         =  1;   /* For ALL GPIO */
1080         }
1081         else if(o->hdwtype==3)  // custom version
1082         {
1083                 o->hid_gpio_ctl         =  0x0c;        /* set GPIO 3 & 4 to output mode */
1084                 o->hid_gpio_ctl_loc     =  2;   /* For CTL of GPIO */
1085                 o->hid_io_cor           =  2;   /* VOLD DN is COR */
1086                 o->hid_io_cor_loc       =  0;   /* VOL DN COR */
1087                 o->hid_io_ctcss         =  2;   /* GPIO 2 is External CTCSS */
1088                 o->hid_io_ctcss_loc =  1;       /* is GPIO 2 */
1089                 o->hid_io_ptt           =  4;   /* GPIO 3 is PTT */
1090                 o->hid_gpio_loc         =  1;   /* For ALL GPIO */
1091         }
1092
1093         return 0;
1094 }
1095 /*
1096 */
1097 static void kickptt(struct chan_usbradio_pvt *o)
1098 {
1099         char c = 0;
1100         //printf("kickptt  %i  %i  %i\n",o->txkeyed,o->txchankey,o->txtestkey);
1101         if (!o) return;
1102         if (!o->pttkick) return;
1103         write(o->pttkick[1],&c,1);
1104 }
1105 /*
1106 */
1107 static void *hidthread(void *arg)
1108 {
1109         unsigned char buf[4],bufsave[4],keyed;
1110         char lastrx, txtmp;
1111         int res;
1112         struct usb_device *usb_dev;
1113         struct usb_dev_handle *usb_handle;
1114         struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
1115         struct timeval to;
1116         fd_set rfds;
1117
1118         usb_dev = hid_device_init(o->devstr);
1119         if (usb_dev == NULL) {
1120                 ast_log(LOG_ERROR,"USB HID device not found\n");
1121                 pthread_exit(NULL);
1122         }
1123         usb_handle = usb_open(usb_dev);
1124         if (usb_handle == NULL) {
1125                 ast_log(LOG_ERROR,"Not able to open USB device\n");
1126                 pthread_exit(NULL);
1127         }
1128         if (usb_claim_interface(usb_handle,C108_HID_INTERFACE) < 0)
1129         {
1130             if (usb_detach_kernel_driver_np(usb_handle,C108_HID_INTERFACE) < 0) {
1131                         ast_log(LOG_ERROR,"Not able to detach the USB device\n");
1132                         pthread_exit(NULL);
1133                 }
1134                 if (usb_claim_interface(usb_handle,C108_HID_INTERFACE) < 0) {
1135                         ast_log(LOG_ERROR,"Not able to claim the USB device\n");
1136                         pthread_exit(NULL);
1137                 }
1138         }
1139         memset(buf,0,sizeof(buf));
1140         buf[2] = o->hid_gpio_ctl;
1141         buf[1] = 0;
1142         hid_set_outputs(usb_handle,buf);
1143         memcpy(bufsave,buf,sizeof(buf));
1144         if (pipe(o->pttkick) == -1)
1145         {
1146             ast_log(LOG_ERROR,"Not able to create pipe\n");
1147                 pthread_exit(NULL);
1148         }
1149         traceusb1(("hidthread: Starting normally on %s!!\n",o->name));
1150         lastrx = 0;
1151         // popen 
1152         while(!o->stophid)
1153         {
1154                 to.tv_sec = 0;
1155                 to.tv_usec = 50000;   // maw sph
1156
1157                 FD_ZERO(&rfds);
1158                 FD_SET(o->pttkick[0],&rfds);
1159                 /* ast_select emulates linux behaviour in terms of timeout handling */
1160                 res = ast_select(o->pttkick[0] + 1, &rfds, NULL, NULL, &to);
1161                 if (res < 0) {
1162                         ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
1163                         usleep(10000);
1164                         continue;
1165                 }
1166                 if (FD_ISSET(o->pttkick[0],&rfds))
1167                 {
1168                         char c;
1169
1170                         read(o->pttkick[0],&c,1);
1171                 }
1172                 if(o->wanteeprom)
1173                 {
1174                         ast_mutex_lock(&o->eepromlock);
1175                         if (o->eepromctl == 1)  /* to read */
1176                         {
1177                                 /* if CS okay */
1178                                 if (!get_eeprom(usb_handle,o->eeprom))
1179                                 {
1180                                         if (o->eeprom[EEPROM_MAGIC_ADDR] != EEPROM_MAGIC)
1181                                         {
1182                                                 ast_log(LOG_NOTICE,"UNSUCCESSFUL: EEPROM MAGIC NUMBER BAD on channel %s\n",o->name);
1183                                         }
1184                                         else
1185                                         {
1186                                                 o->rxmixerset = o->eeprom[EEPROM_RXMIXERSET];
1187                                                 o->txmixaset =  o->eeprom[EEPROM_TXMIXASET];
1188                                                 o->txmixbset = o->eeprom[EEPROM_TXMIXBSET];
1189                                                 memcpy(&o->rxvoiceadj,&o->eeprom[EEPROM_RXVOICEADJ],sizeof(float));
1190                                                 memcpy(&o->rxctcssadj,&o->eeprom[EEPROM_RXCTCSSADJ],sizeof(float));
1191                                                 o->txctcssadj = o->eeprom[EEPROM_TXCTCSSADJ];
1192                                                 o->rxsquelchadj = o->eeprom[EEPROM_RXSQUELCHADJ];
1193                                                 ast_log(LOG_NOTICE,"EEPROM Loaded on channel %s\n",o->name);
1194                                         }
1195                                 }
1196                                 else
1197                                 {
1198                                         ast_log(LOG_NOTICE,"USB Adapter has no EEPROM installed or Checksum BAD on channel %s\n",o->name);
1199                                 }
1200                                 hid_set_outputs(usb_handle,bufsave);
1201                         } 
1202                         if (o->eepromctl == 2) /* to write */
1203                         {
1204                                 put_eeprom(usb_handle,o->eeprom);
1205                                 hid_set_outputs(usb_handle,bufsave);
1206                                 ast_log(LOG_NOTICE,"USB Parameters written to EEPROM on %s\n",o->name);
1207                         }
1208                         o->eepromctl = 0;
1209                         ast_mutex_unlock(&o->eepromlock);
1210                 }
1211                 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
1212                 hid_get_inputs(usb_handle,buf);
1213                 keyed = !(buf[o->hid_io_cor_loc] & o->hid_io_cor);
1214                 if (keyed != o->rxhidsq)
1215                 {
1216                         if(o->debuglevel)printf("chan_usbradio() hidthread: update rxhidsq = %d\n",keyed);
1217                         o->rxhidsq=keyed;
1218                 }
1219
1220                 /* if change in tx state as controlled by xpmr */
1221                 txtmp=o->pmrChan->txPttOut;
1222                                 
1223                 if (o->lasttx != txtmp)
1224                 {
1225                         o->pmrChan->txPttHid=o->lasttx = txtmp;
1226                         if(o->debuglevel)printf("hidthread: tx set to %d\n",txtmp);
1227                         buf[o->hid_gpio_loc] = 0;
1228                         if (!o->invertptt)
1229                         {
1230                                 if (txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
1231                         }
1232                         else
1233                         {
1234                                 if (!txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
1235                         }
1236                         buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
1237                         memcpy(bufsave,buf,sizeof(buf));
1238                         hid_set_outputs(usb_handle,buf);
1239                 }
1240                 time(&o->lasthidtime);
1241         }
1242         buf[o->hid_gpio_loc] = 0;
1243         if (o->invertptt) buf[o->hid_gpio_loc] = o->hid_io_ptt;
1244         buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
1245         hid_set_outputs(usb_handle,buf);
1246         pthread_exit(0);
1247 }
1248
1249 /*
1250  * returns a pointer to the descriptor with the given name
1251  */
1252 static struct chan_usbradio_pvt *find_desc(char *dev)
1253 {
1254         struct chan_usbradio_pvt *o = NULL;
1255
1256         if (!dev)
1257                 ast_log(LOG_WARNING, "null dev\n");
1258
1259         for (o = usbradio_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
1260         if (!o)
1261         {
1262                 ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
1263                 pthread_exit(0);
1264         }
1265
1266         return o;
1267 }
1268
1269 static struct chan_usbradio_pvt *find_desc_usb(char *devstr)
1270 {
1271         struct chan_usbradio_pvt *o = NULL;
1272
1273         if (!devstr)
1274                 ast_log(LOG_WARNING, "null dev\n");
1275
1276         for (o = usbradio_default.next; o && devstr && strcmp(o->devstr, devstr) != 0; o = o->next);
1277
1278         return o;
1279 }
1280
1281 /*
1282  * split a string in extension-context, returns pointers to malloc'ed
1283  * strings.
1284  * If we do not have 'overridecontext' then the last @ is considered as
1285  * a context separator, and the context is overridden.
1286  * This is usually not very necessary as you can play with the dialplan,
1287  * and it is nice not to need it because you have '@' in SIP addresses.
1288  * Return value is the buffer address.
1289  */
1290 #if     0
1291 static char *ast_ext_ctx(const char *src, char **ext, char **ctx)
1292 {
1293         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
1294
1295         if (ext == NULL || ctx == NULL)
1296                 return NULL;                    /* error */
1297
1298         *ext = *ctx = NULL;
1299
1300         if (src && *src != '\0')
1301                 *ext = ast_strdup(src);
1302
1303         if (*ext == NULL)
1304                 return NULL;
1305
1306         if (!o->overridecontext) {
1307                 /* parse from the right */
1308                 *ctx = strrchr(*ext, '@');
1309                 if (*ctx)
1310                         *(*ctx)++ = '\0';
1311         }
1312
1313         return *ext;
1314 }
1315 #endif
1316
1317 /*
1318  * Returns the number of blocks used in the audio output channel
1319  */
1320 static int used_blocks(struct chan_usbradio_pvt *o)
1321 {
1322         struct audio_buf_info info;
1323
1324         if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
1325                 if (!(o->warned & WARN_used_blocks)) {
1326                         ast_log(LOG_WARNING, "Error reading output space\n");
1327                         o->warned |= WARN_used_blocks;
1328                 }
1329                 return 1;
1330         }
1331
1332         if (o->total_blocks == 0) {
1333                 if (0)                                  /* debugging */
1334                         ast_log(LOG_WARNING, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
1335                 o->total_blocks = info.fragments;
1336         }
1337
1338         return o->total_blocks - info.fragments;
1339 }
1340
1341 /* Write an exactly FRAME_SIZE sized frame */
1342 static int soundcard_writeframe(struct chan_usbradio_pvt *o, short *data)
1343 {
1344         int res;
1345
1346         if (o->sounddev < 0)
1347                 setformat(o, O_RDWR);
1348         if (o->sounddev < 0)
1349                 return 0;                               /* not fatal */
1350         //  maw maw sph !!! may or may not be a good thing
1351         //  drop the frame if not transmitting, this keeps from gradually
1352         //  filling the buffer when asterisk clock > usb sound clock
1353         if(!o->pmrChan->txPttIn && !o->pmrChan->txPttOut)
1354         {
1355                 //return 0;
1356         }
1357         /*
1358          * Nothing complex to manage the audio device queue.
1359          * If the buffer is full just drop the extra, otherwise write.
1360          * XXX in some cases it might be useful to write anyways after
1361          * a number of failures, to restart the output chain.
1362          */
1363         res = used_blocks(o);
1364         if (res > o->queuesize) {       /* no room to write a block */
1365             // ast_log(LOG_WARNING, "sound device write buffer overflow\n");
1366                 if (o->w_errors++ == 0 && (usbradio_debug & 0x4))
1367                         ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
1368                 return 0;
1369         }
1370         o->w_errors = 0;
1371
1372         return write(o->sounddev, ((void *) data), FRAME_SIZE * 2 * 12);
1373 }
1374
1375 #ifndef NEW_ASTERISK
1376
1377 /*
1378  * Handler for 'sound writable' events from the sound thread.
1379  * Builds a frame from the high level description of the sounds,
1380  * and passes it to the audio device.
1381  * The actual sound is made of 1 or more sequences of sound samples
1382  * (s->datalen, repeated to make s->samplen samples) followed by
1383  * s->silencelen samples of silence. The position in the sequence is stored
1384  * in o->sampsent, which goes between 0 .. s->samplen+s->silencelen.
1385  * In case we fail to write a frame, don't update o->sampsent.
1386  */
1387 static void send_sound(struct chan_usbradio_pvt *o)
1388 {
1389         short myframe[FRAME_SIZE];
1390         int ofs, l, start;
1391         int l_sampsent = o->sampsent;
1392         struct sound *s;
1393
1394         if (o->cursound < 0)            /* no sound to send */
1395                 return;
1396
1397         s = &sounds[o->cursound];
1398
1399         for (ofs = 0; ofs < FRAME_SIZE; ofs += l) {
1400                 l = s->samplen - l_sampsent;    /* # of available samples */
1401                 if (l > 0) {
1402                         start = l_sampsent % s->datalen;        /* source offset */
1403                         if (l > FRAME_SIZE - ofs)       /* don't overflow the frame */
1404                                 l = FRAME_SIZE - ofs;
1405                         if (l > s->datalen - start)     /* don't overflow the source */
1406                                 l = s->datalen - start;
1407                         bcopy(s->data + start, myframe + ofs, l * 2);
1408                         if (0)
1409                                 ast_log(LOG_WARNING, "send_sound sound %d/%d of %d into %d\n", l_sampsent, l, s->samplen, ofs);
1410                         l_sampsent += l;
1411                 } else {                                /* end of samples, maybe some silence */
1412                         static const short silence[FRAME_SIZE] = { 0, };
1413
1414                         l += s->silencelen;
1415                         if (l > 0) {
1416                                 if (l > FRAME_SIZE - ofs)
1417                                         l = FRAME_SIZE - ofs;
1418                                 bcopy(silence, myframe + ofs, l * 2);
1419                                 l_sampsent += l;
1420                         } else {                        /* silence is over, restart sound if loop */
1421                                 if (s->repeat == 0) {   /* last block */
1422                                         o->cursound = -1;
1423                                         o->nosound = 0; /* allow audio data */
1424                                         if (ofs < FRAME_SIZE)   /* pad with silence */
1425                                                 bcopy(silence, myframe + ofs, (FRAME_SIZE - ofs) * 2);
1426                                 }
1427                                 l_sampsent = 0;
1428                         }
1429                 }
1430         }
1431         l = soundcard_writeframe(o, myframe);
1432         if (l > 0)
1433                 o->sampsent = l_sampsent;       /* update status */
1434 }
1435
1436 static void *sound_thread(void *arg)
1437 {
1438         char ign[4096];
1439         struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
1440
1441         /*
1442          * Just in case, kick the driver by trying to read from it.
1443          * Ignore errors - this read is almost guaranteed to fail.
1444          */
1445         read(o->sounddev, ign, sizeof(ign));
1446         for (;;) {
1447                 fd_set rfds, wfds;
1448                 int maxfd, res;
1449
1450                 FD_ZERO(&rfds);
1451                 FD_ZERO(&wfds);
1452                 FD_SET(o->sndcmd[0], &rfds);
1453                 maxfd = o->sndcmd[0];   /* pipe from the main process */
1454                 if (o->cursound > -1 && o->sounddev < 0)
1455                         setformat(o, O_RDWR);   /* need the channel, try to reopen */
1456                 else if (o->cursound == -1 && o->owner == NULL)
1457                 {
1458                         setformat(o, O_CLOSE);  /* can close */
1459                 }
1460                 if (o->sounddev > -1) {
1461                         if (!o->owner) {        /* no one owns the audio, so we must drain it */
1462                                 FD_SET(o->sounddev, &rfds);
1463                                 maxfd = MAX(o->sounddev, maxfd);
1464                         }
1465                         if (o->cursound > -1) {
1466                                 FD_SET(o->sounddev, &wfds);
1467                                 maxfd = MAX(o->sounddev, maxfd);
1468                         }
1469                 }
1470                 /* ast_select emulates linux behaviour in terms of timeout handling */
1471                 res = ast_select(maxfd + 1, &rfds, &wfds, NULL, NULL);
1472                 if (res < 1) {
1473                         ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
1474                         sleep(1);
1475                         continue;
1476                 }
1477                 if (FD_ISSET(o->sndcmd[0], &rfds)) {
1478                         /* read which sound to play from the pipe */
1479                         int i, what = -1;
1480
1481                         read(o->sndcmd[0], &what, sizeof(what));
1482                         for (i = 0; sounds[i].ind != -1; i++) {
1483                                 if (sounds[i].ind == what) {
1484                                         o->cursound = i;
1485                                         o->sampsent = 0;
1486                                         o->nosound = 1; /* block audio from pbx */
1487                                         break;
1488                                 }
1489                         }
1490                         if (sounds[i].ind == -1)
1491                                 ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
1492                 }
1493                 if (o->sounddev > -1) {
1494                         if (FD_ISSET(o->sounddev, &rfds))       /* read and ignore errors */
1495                                 read(o->sounddev, ign, sizeof(ign)); 
1496                         if (FD_ISSET(o->sounddev, &wfds))
1497                                 send_sound(o);
1498                 }
1499         }
1500         return NULL;                            /* Never reached */
1501 }
1502
1503 #endif
1504
1505 /*
1506  * reset and close the device if opened,
1507  * then open and initialize it in the desired mode,
1508  * trigger reads and writes so we can start using it.
1509  */
1510 static int setformat(struct chan_usbradio_pvt *o, int mode)
1511 {
1512         int fmt, desired, res, fd;
1513         char device[100];
1514
1515         if (o->sounddev >= 0) {
1516                 ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
1517                 close(o->sounddev);
1518                 o->duplex = M_UNSET;
1519                 o->sounddev = -1;
1520         }
1521         if (mode == O_CLOSE)            /* we are done */
1522                 return 0;
1523         o->lastopen = ast_tvnow();
1524         strcpy(device,"/dev/dsp");
1525         if (o->devicenum)
1526                 sprintf(device,"/dev/dsp%d",o->devicenum);
1527         fd = o->sounddev = open(device, mode | O_NONBLOCK);
1528         if (fd < 0) {
1529                 ast_log(LOG_WARNING, "Unable to re-open DSP device %d: %s\n", o->devicenum, strerror(errno));
1530                 return -1;
1531         }
1532         if (o->owner)
1533                 o->owner->fds[0] = fd;
1534
1535 #if __BYTE_ORDER == __LITTLE_ENDIAN
1536         fmt = AFMT_S16_LE;
1537 #else
1538         fmt = AFMT_S16_BE;
1539 #endif
1540         res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
1541         if (res < 0) {
1542                 ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
1543                 return -1;
1544         }
1545         switch (mode) {
1546                 case O_RDWR:
1547                         res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
1548                         /* Check to see if duplex set (FreeBSD Bug) */
1549                         res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
1550                         if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
1551                                 if (option_verbose > 1)
1552                                         ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
1553                                 o->duplex = M_FULL;
1554                         };
1555                         break;
1556                 case O_WRONLY:
1557                         o->duplex = M_WRITE;
1558                         break;
1559                 case O_RDONLY:
1560                         o->duplex = M_READ;
1561                         break;
1562         }
1563
1564         fmt = 1;
1565         res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
1566         if (res < 0) {
1567                 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
1568                 return -1;
1569         }
1570         fmt = desired = 48000;                                                  /* 8000 Hz desired */
1571         res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
1572
1573         if (res < 0) {
1574                 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
1575                 return -1;
1576         }
1577         if (fmt != desired) {
1578                 if (!(o->warned & WARN_speed)) {
1579                         ast_log(LOG_WARNING,
1580                             "Requested %d Hz, got %d Hz -- sound may be choppy\n",
1581                             desired, fmt);
1582                         o->warned |= WARN_speed;
1583                 }
1584         }
1585         /*
1586          * on Freebsd, SETFRAGMENT does not work very well on some cards.
1587          * Default to use 256 bytes, let the user override
1588          */
1589         if (o->frags) {
1590                 fmt = o->frags;
1591                 res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
1592                 if (res < 0) {
1593                         if (!(o->warned & WARN_frag)) {
1594                                 ast_log(LOG_WARNING,
1595                                         "Unable to set fragment size -- sound may be choppy\n");
1596                                 o->warned |= WARN_frag;
1597                         }
1598                 }
1599         }
1600         /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
1601         res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
1602         res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
1603         /* it may fail if we are in half duplex, never mind */
1604         return 0;
1605 }
1606
1607 /*
1608  * some of the standard methods supported by channels.
1609  */
1610 static int usbradio_digit_begin(struct ast_channel *c, char digit)
1611 {
1612         return 0;
1613 }
1614
1615 static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration)
1616 {
1617         /* no better use for received digits than print them */
1618         ast_verbose(" << Console Received digit %c of duration %u ms >> \n", 
1619                 digit, duration);
1620         return 0;
1621 }
1622 /*
1623         SETFREQ - sets spi programmable xcvr
1624         SETCHAN - sets binary parallel xcvr
1625 */
1626 static int usbradio_text(struct ast_channel *c, const char *text)
1627 {
1628         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
1629         double tx,rx;
1630         char cnt,rxs[16],txs[16],txpl[16],rxpl[16];
1631         char pwr,*cmd;
1632
1633         cmd = alloca(strlen(text) + 10);
1634
1635         /* print received messages */
1636         if(o->debuglevel)ast_verbose(" << Console Received usbradio text %s >> \n", text);
1637
1638         cnt=sscanf(text,"%s %s %s %s %s %c",cmd,rxs,txs,rxpl,txpl,&pwr);
1639
1640         if (strcmp(cmd,"SETCHAN")==0)
1641     { 
1642                 u8 chan;
1643                 chan=strtod(rxs,NULL);
1644                 ppbinout(chan);
1645         if(o->debuglevel)ast_log(LOG_NOTICE,"parse usbradio SETCHAN cmd: %s chan: %i\n",text,chan);
1646         return 0;
1647     }
1648         
1649     if (cnt < 6)
1650     {
1651             ast_log(LOG_ERROR,"Cannot parse usbradio text: %s\n",text);
1652             return 0;
1653     }
1654         else
1655         {
1656                 if(o->debuglevel)ast_verbose(" << %s %s %s %s %s %c >> \n", cmd,rxs,txs,rxpl,txpl,pwr); 
1657         }
1658     
1659     if (strcmp(cmd,"SETFREQ")==0)
1660     {
1661         if(o->debuglevel)ast_log(LOG_NOTICE,"parse usbradio SETFREQ cmd: %s\n",text);
1662                 tx=strtod(txs,NULL);
1663                 rx=strtod(rxs,NULL);
1664                 o->set_txfreq = round(tx * (double)1000000);
1665                 o->set_rxfreq = round(rx * (double)1000000);
1666                 o->pmrChan->txpower = (pwr == 'H');
1667                 strcpy(o->set_rxctcssfreqs,rxpl);
1668                 strcpy(o->set_txctcssfreqs,txpl);
1669         
1670                 o->b.remoted=1;
1671                 xpmr_config(o);
1672         return 0;
1673     }
1674         ast_log(LOG_ERROR,"Cannot parse usbradio cmd: %s\n",text);
1675         return 0;
1676 }
1677
1678 /* Play ringtone 'x' on device 'o' */
1679 static void ring(struct chan_usbradio_pvt *o, int x)
1680 {
1681 #ifndef NEW_ASTERISK
1682         write(o->sndcmd[1], &x, sizeof(x));
1683 #endif
1684 }
1685
1686 /*
1687  * handler for incoming calls. Either autoanswer, or start ringing
1688  */
1689 static int usbradio_call(struct ast_channel *c, char *dest, int timeout)
1690 {
1691         struct chan_usbradio_pvt *o = c->tech_pvt;
1692
1693         o->stophid = 0;
1694         time(&o->lasthidtime);
1695         ast_pthread_create_background(&o->hidthread, NULL, hidthread, o);
1696         ast_setstate(c, AST_STATE_UP);
1697         return 0;
1698 }
1699
1700 /*
1701  * remote side answered the phone
1702  */
1703 static int usbradio_answer(struct ast_channel *c)
1704 {
1705 #ifndef NEW_ASTERISK
1706         struct chan_usbradio_pvt *o = c->tech_pvt;
1707 #endif
1708
1709         ast_setstate(c, AST_STATE_UP);
1710 #ifndef NEW_ASTERISK
1711         o->cursound = -1;
1712         o->nosound = 0;
1713 #endif
1714         return 0;
1715 }
1716
1717 static int usbradio_hangup(struct ast_channel *c)
1718 {
1719         struct chan_usbradio_pvt *o = c->tech_pvt;
1720
1721         //ast_log(LOG_NOTICE, "usbradio_hangup()\n");
1722 #ifndef NEW_ASTERISK
1723         o->cursound = -1;
1724         o->nosound = 0;
1725 #endif
1726         c->tech_pvt = NULL;
1727         o->owner = NULL;
1728         ast_module_unref(ast_module_info->self);
1729         if (o->hookstate) {
1730                 if (o->autoanswer || o->autohangup) {
1731                         /* Assume auto-hangup too */
1732                         o->hookstate = 0;
1733                         setformat(o, O_CLOSE);
1734                 } else {
1735                         /* Make congestion noise */
1736                         ring(o, AST_CONTROL_CONGESTION);
1737                 }
1738         }
1739         o->stophid = 1;
1740         pthread_join(o->hidthread,NULL);
1741         return 0;
1742 }
1743
1744
1745 /* used for data coming from the network */
1746 static int usbradio_write(struct ast_channel *c, struct ast_frame *f)
1747 {
1748         struct chan_usbradio_pvt *o = c->tech_pvt;
1749
1750         traceusb2(("usbradio_write() o->nosound= %i\n",o->nosound));
1751
1752 #ifndef NEW_ASTERISK
1753         /* Immediately return if no sound is enabled */
1754         if (o->nosound)
1755                 return 0;
1756         /* Stop any currently playing sound */
1757         o->cursound = -1;
1758 #endif
1759         /*
1760          * we could receive a block which is not a multiple of our
1761          * FRAME_SIZE, so buffer it locally and write to the device
1762          * in FRAME_SIZE chunks.
1763          * Keep the residue stored for future use.
1764          */
1765
1766         #if DEBUG_CAPTURES == 1 // to write input data to a file   datalen=320
1767         if (ftxcapraw && o->b.txcapraw)
1768         {
1769                 i16 i, tbuff[f->datalen];
1770                 for(i=0;i<f->datalen;i+=2)
1771                 {
1772                         tbuff[i]= ((i16*)(f->data.ptr))[i/2];
1773                         tbuff[i+1]= o->txkeyed*M_Q13;
1774                 }
1775                 fwrite(tbuff,2,f->datalen,ftxcapraw);
1776                 //fwrite(f->data,1,f->datalen,ftxcapraw);
1777         }
1778         #endif
1779
1780         // maw just take the data from the network and save it for PmrRx processing
1781
1782         PmrTx(o->pmrChan,(i16*)f->data.ptr);
1783         
1784         return 0;
1785 }
1786
1787 static struct ast_frame *usbradio_read(struct ast_channel *c)
1788 {
1789         int res, src, datalen, oldpttout;
1790         int cd,sd;
1791         struct chan_usbradio_pvt *o = c->tech_pvt;
1792         struct ast_frame *f = &o->read_f,*f1;
1793         struct ast_frame wf = { AST_FRAME_CONTROL };
1794         time_t now;
1795
1796         traceusb2(("usbradio_read()\n"));
1797
1798         if (o->lasthidtime)
1799         {
1800                 time(&now);
1801                 if ((now - o->lasthidtime) > 3)
1802                 {
1803                         ast_log(LOG_ERROR,"HID process has died or something!!\n");
1804                         return NULL;
1805                 }
1806         }
1807         /* XXX can be simplified returning &ast_null_frame */
1808         /* prepare a NULL frame in case we don't have enough data to return */
1809         bzero(f, sizeof(struct ast_frame));
1810         f->frametype = AST_FRAME_NULL;
1811         f->src = usbradio_tech.type;
1812
1813         res = read(o->sounddev, o->usbradio_read_buf + o->readpos, 
1814                 sizeof(o->usbradio_read_buf) - o->readpos);
1815         if (res < 0)                            /* audio data not ready, return a NULL frame */
1816         {
1817                 if (errno != EAGAIN) return NULL;
1818                 if (o->readerrs++ > READERR_THRESHOLD)
1819                 {
1820                         ast_log(LOG_ERROR,"Stuck USB read channel [%s], un-sticking it!\n",o->name);
1821                         o->readerrs = 0;
1822                         return NULL;
1823                 }
1824                 if (o->readerrs == 1) 
1825                         ast_log(LOG_WARNING,"Possibly stuck USB read channel. [%s]\n",o->name);
1826                 return f;
1827         }
1828         if (o->readerrs) ast_log(LOG_WARNING,"Nope, USB read channel [%s] wasn't stuck after all.\n",o->name);
1829         o->readerrs = 0;
1830         o->readpos += res;
1831         if (o->readpos < sizeof(o->usbradio_read_buf))  /* not enough samples */
1832                 return f;
1833
1834         if (o->mute)
1835                 return f;
1836
1837         #if DEBUG_CAPTURES == 1
1838         if (o->b.rxcapraw && frxcapraw) fwrite((o->usbradio_read_buf + AST_FRIENDLY_OFFSET),1,FRAME_SIZE * 2 * 2 * 6,frxcapraw);
1839         #endif
1840
1841         #if 1
1842         if(o->txkeyed||o->txtestkey)
1843         {
1844                 if(!o->pmrChan->txPttIn)
1845                 {
1846                         o->pmrChan->txPttIn=1;
1847                         if(o->debuglevel) ast_log(LOG_NOTICE,"txPttIn = %i, chan %s\n",o->pmrChan->txPttIn,o->owner->name);
1848                 }
1849         }
1850         else if(o->pmrChan->txPttIn)
1851         {
1852                 o->pmrChan->txPttIn=0;
1853                 if(o->debuglevel) ast_log(LOG_NOTICE,"txPttIn = %i, chan %s\n",o->pmrChan->txPttIn,o->owner->name);
1854         }
1855         oldpttout = o->pmrChan->txPttOut;
1856
1857         PmrRx(         o->pmrChan, 
1858                    (i16 *)(o->usbradio_read_buf + AST_FRIENDLY_OFFSET),
1859                    (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET),
1860                    (i16 *)(o->usbradio_write_buf_1));
1861
1862         if (oldpttout != o->pmrChan->txPttOut)
1863         {
1864                 if(o->debuglevel) ast_log(LOG_NOTICE,"txPttOut = %i, chan %s\n",o->pmrChan->txPttOut,o->owner->name);
1865                 kickptt(o);
1866         }
1867
1868         #if 0   // to write 48KS/s stereo tx data to a file
1869         if (!ftxoutraw) ftxoutraw = fopen(TX_CAP_OUT_FILE,"w");
1870         if (ftxoutraw) fwrite(o->usbradio_write_buf_1,1,FRAME_SIZE * 2 * 6,ftxoutraw);
1871         #endif
1872
1873         #if DEBUG_CAPTURES == 1 && XPMR_DEBUG0 == 1
1874     if (o->b.txcap2 && ftxcaptrace) fwrite((o->pmrChan->ptxDebug),1,FRAME_SIZE * 2 * 16,ftxcaptrace);
1875         #endif
1876         
1877         // 160 samples * 2 bytes/sample * 2 chan * 6x oversampling to 48KS/s
1878         datalen = FRAME_SIZE * 24;  
1879         src = 0;                                        /* read position into f->data */
1880         while (src < datalen) 
1881         {
1882                 /* Compute spare room in the buffer */
1883                 int l = sizeof(o->usbradio_write_buf) - o->usbradio_write_dst;
1884
1885                 if (datalen - src >= l) 
1886                 {       
1887                         /* enough to fill a frame */
1888                         memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
1889                         soundcard_writeframe(o, (short *) o->usbradio_write_buf);
1890                         src += l;
1891                         o->usbradio_write_dst = 0;
1892                 } 
1893                 else 
1894                 {                               
1895                         /* copy residue */
1896                         l = datalen - src;
1897                         memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
1898                         src += l;                       /* but really, we are done */
1899                         o->usbradio_write_dst += l;
1900                 }
1901         }
1902         #else
1903         static FILE *hInput;
1904         i16 iBuff[FRAME_SIZE*2*6];
1905
1906         o->pmrChan->b.rxCapture=1;
1907
1908         if(!hInput)
1909         {
1910                 hInput  = fopen("/usr/src/xpmr/testdata/rx_in.pcm","r");
1911                 if(!hInput)
1912                 {
1913                         printf(" Input Data File Not Found.\n");
1914                         return 0;
1915                 }
1916         }
1917
1918         if(0==fread((void *)iBuff,2,FRAME_SIZE*2*6,hInput))exit;
1919
1920         PmrRx(  o->pmrChan, 
1921                    (i16 *)iBuff,
1922                    (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
1923
1924         #endif
1925
1926         #if 0
1927         if (!frxoutraw) frxoutraw = fopen(RX_CAP_OUT_FILE,"w");
1928     if (frxoutraw) fwrite((o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET),1,FRAME_SIZE * 2,frxoutraw);
1929         #endif
1930
1931         #if DEBUG_CAPTURES == 1 && XPMR_DEBUG0 == 1
1932     if (frxcaptrace && o->b.rxcap2 && o->pmrChan->b.radioactive) fwrite((o->pmrChan->prxDebug),1,FRAME_SIZE * 2 * 16,frxcaptrace);
1933         #endif
1934
1935         cd = 0;
1936         if(o->rxcdtype==CD_HID && (o->pmrChan->rxExtCarrierDetect!=o->rxhidsq))
1937                 o->pmrChan->rxExtCarrierDetect=o->rxhidsq;
1938         
1939         if(o->rxcdtype==CD_HID_INVERT && (o->pmrChan->rxExtCarrierDetect==o->rxhidsq))
1940                 o->pmrChan->rxExtCarrierDetect=!o->rxhidsq;
1941                 
1942         if( (o->rxcdtype==CD_HID        && o->rxhidsq)                  ||
1943                 (o->rxcdtype==CD_HID_INVERT && !o->rxhidsq)                 ||
1944                 (o->rxcdtype==CD_XPMR_NOISE && o->pmrChan->rxCarrierDetect) ||
1945                 (o->rxcdtype==CD_XPMR_VOX   && o->pmrChan->rxCarrierDetect)
1946           )
1947         {
1948                 if (!o->pmrChan->txPttOut || o->radioduplex)cd=1;       
1949         }
1950         else
1951         {
1952                 cd=0;
1953         }
1954
1955         if(cd!=o->rxcarrierdetect)
1956         {
1957                 o->rxcarrierdetect=cd;
1958                 if(o->debuglevel) ast_log(LOG_NOTICE,"rxcarrierdetect = %i, chan %s\n",cd,o->owner->name);
1959                 // printf("rxcarrierdetect = %i, chan %s\n",res,o->owner->name);
1960         }
1961
1962         if(o->pmrChan->b.ctcssRxEnable && o->pmrChan->rxCtcss->decode!=o->rxctcssdecode)
1963         {
1964                 if(o->debuglevel)ast_log(LOG_NOTICE,"rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
1965                 // printf("rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
1966                 o->rxctcssdecode=o->pmrChan->rxCtcss->decode;
1967                 strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
1968         }
1969
1970         #ifndef HAVE_XPMRX
1971         if(  !o->pmrChan->b.ctcssRxEnable ||
1972                 ( o->pmrChan->b.ctcssRxEnable && 
1973               o->pmrChan->rxCtcss->decode>CTCSS_NULL && 
1974               o->pmrChan->smode==SMODE_CTCSS )  
1975         )
1976         {
1977                 sd=1;   
1978         }
1979         else
1980         {
1981                 sd=0;
1982         }
1983         #else
1984         if( (!o->pmrChan->b.ctcssRxEnable && !o->pmrChan->b.dcsRxEnable && !o->pmrChan->b.lmrRxEnable) ||
1985                 ( o->pmrChan->b.ctcssRxEnable && 
1986               o->pmrChan->rxCtcss->decode>CTCSS_NULL && 
1987               o->pmrChan->smode==SMODE_CTCSS ) ||
1988                 ( o->pmrChan->b.dcsRxEnable && 
1989               o->pmrChan->decDcs->decode > 0 &&
1990               o->pmrChan->smode==SMODE_DCS )
1991         )
1992         {
1993                 sd=1;   
1994         }
1995         else
1996         {
1997                 sd=0;
1998         }
1999
2000         if(o->pmrChan->decDcs->decode!=o->rxdcsdecode)
2001         {                                                                                                       
2002                 if(o->debuglevel)ast_log(LOG_NOTICE,"rxdcsdecode = %s, chan %s\n",o->pmrChan->rxctcssfreq,o->owner->name);
2003                 // printf("rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
2004                 o->rxdcsdecode=o->pmrChan->decDcs->decode;
2005                 strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
2006         }                                                                                                                                                                                         
2007
2008         if(o->pmrChan->rptnum && (o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed != o->rxlsddecode))
2009         {                                                               
2010                 if(o->debuglevel)ast_log(LOG_NOTICE,"rxLSDecode = %s, chan %s\n",o->pmrChan->rxctcssfreq,o->owner->name);
2011                 o->rxlsddecode=o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed;
2012                 strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
2013         }
2014
2015         if( (o->pmrChan->rptnum>0 && o->pmrChan->smode==SMODE_LSD && o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed)||
2016             (o->pmrChan->smode==SMODE_DCS && o->pmrChan->decDcs->decode>0) )
2017         {
2018                 sd=1;
2019         }
2020         #endif
2021
2022         if ( cd && sd )
2023         {
2024                 //if(!o->rxkeyed)o->pmrChan->dd.b.doitnow=1;
2025                 if(!o->rxkeyed && o->debuglevel)ast_log(LOG_NOTICE,"o->rxkeyed = 1, chan %s\n", o->owner->name);
2026                 o->rxkeyed = 1;
2027         }
2028         else 
2029         {
2030                 //if(o->rxkeyed)o->pmrChan->dd.b.doitnow=1;
2031                 if(o->rxkeyed && o->debuglevel)ast_log(LOG_NOTICE,"o->rxkeyed = 0, chan %s\n",o->owner->name);
2032                 o->rxkeyed = 0;
2033         }
2034
2035         // provide rx signal detect conditions
2036         if (o->lastrx && (!o->rxkeyed))
2037         {
2038                 o->lastrx = 0;
2039                 //printf("AST_CONTROL_RADIO_UNKEY\n");
2040                 wf.subclass = AST_CONTROL_RADIO_UNKEY;
2041                 ast_queue_frame(o->owner, &wf);
2042         }
2043         else if ((!o->lastrx) && (o->rxkeyed))
2044         {
2045                 o->lastrx = 1;
2046                 //printf("AST_CONTROL_RADIO_KEY\n");
2047                 wf.subclass = AST_CONTROL_RADIO_KEY;
2048                 if(o->rxctcssdecode)    
2049         {
2050                 wf.data.ptr = o->rxctcssfreq;
2051                 wf.datalen = strlen(o->rxctcssfreq) + 1;
2052                         TRACEO(1,("AST_CONTROL_RADIO_KEY text=%s\n",o->rxctcssfreq));
2053         }
2054                 ast_queue_frame(o->owner, &wf);
2055         }
2056
2057         o->readpos = AST_FRIENDLY_OFFSET;       /* reset read pointer for next frame */
2058         if (c->_state != AST_STATE_UP)  /* drop data if frame is not up */
2059                 return f;
2060         /* ok we can build and deliver the frame to the caller */
2061         f->frametype = AST_FRAME_VOICE;
2062         f->subclass = AST_FORMAT_SLINEAR;
2063         f->samples = FRAME_SIZE;
2064         f->datalen = FRAME_SIZE * 2;
2065         f->data.ptr = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
2066         if (o->boost != BOOST_SCALE) {  /* scale and clip values */
2067                 int i, x;
2068                 int16_t *p = (int16_t *) f->data.ptr;
2069                 for (i = 0; i < f->samples; i++) {
2070                         x = (p[i] * o->boost) / BOOST_SCALE;
2071                         if (x > 32767)
2072                                 x = 32767;
2073                         else if (x < -32768)
2074                                 x = -32768;
2075                         p[i] = x;
2076                 }
2077         }
2078
2079         f->offset = AST_FRIENDLY_OFFSET;
2080         if (o->dsp)
2081         {
2082             f1 = ast_dsp_process(c,o->dsp,f);
2083             if ((f1->frametype == AST_FRAME_DTMF_END) ||
2084               (f1->frametype == AST_FRAME_DTMF_BEGIN))
2085             {
2086                 if ((f1->subclass == 'm') || (f1->subclass == 'u'))
2087                 {
2088                         f1->frametype = AST_FRAME_NULL;
2089                         f1->subclass = 0;
2090                         return(f1);
2091                 }
2092                 if (f1->frametype == AST_FRAME_DTMF_END)
2093                         ast_log(LOG_NOTICE,"Got DTMF char %c\n",f1->subclass);
2094                 return(f1);
2095             }
2096         }
2097         return f;
2098 }
2099
2100 static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
2101 {
2102         struct chan_usbradio_pvt *o = newchan->tech_pvt;
2103         ast_log(LOG_WARNING,"usbradio_fixup()\n");
2104         o->owner = newchan;
2105         return 0;
2106 }
2107
2108 static int usbradio_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
2109 {
2110         struct chan_usbradio_pvt *o = c->tech_pvt;
2111         int res = -1;
2112
2113         switch (cond) {
2114                 case AST_CONTROL_BUSY:
2115                 case AST_CONTROL_CONGESTION:
2116                 case AST_CONTROL_RINGING:
2117                         res = cond;
2118                         break;
2119
2120                 case -1:
2121 #ifndef NEW_ASTERISK
2122                         o->cursound = -1;
2123                         o->nosound = 0;         /* when cursound is -1 nosound must be 0 */
2124 #endif
2125                         return 0;
2126
2127                 case AST_CONTROL_VIDUPDATE:
2128                         res = -1;
2129                         break;
2130                 case AST_CONTROL_HOLD:
2131                         ast_verbose(" << Console Has Been Placed on Hold >> \n");
2132                         ast_moh_start(c, data, o->mohinterpret);
2133                         break;
2134                 case AST_CONTROL_UNHOLD:
2135                         ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
2136                         ast_moh_stop(c);
2137                         break;
2138                 case AST_CONTROL_PROCEEDING:
2139                         ast_verbose(" << Call Proceeding... >> \n");
2140                         ast_moh_stop(c);
2141                         break;
2142                 case AST_CONTROL_PROGRESS:
2143                         ast_verbose(" << Call Progress... >> \n");
2144                         ast_moh_stop(c);
2145                         break;
2146                 case AST_CONTROL_RADIO_KEY:
2147                         o->txkeyed = 1;
2148                         if(o->debuglevel)ast_verbose(" << AST_CONTROL_RADIO_KEY Radio Transmit On. >> \n");
2149                         break;
2150                 case AST_CONTROL_RADIO_UNKEY:
2151                         o->txkeyed = 0;
2152                         if(o->debuglevel)ast_verbose(" << AST_CONTROL_RADIO_UNKEY Radio Transmit Off. >> \n");
2153                         break;
2154                 default:
2155                         ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
2156                         return -1;
2157         }
2158
2159         if (res > -1)
2160                 ring(o, res);
2161
2162         return 0;
2163 }
2164
2165 /*
2166  * allocate a new channel.
2167  */
2168 static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state)
2169 {
2170         struct ast_channel *c;
2171
2172         c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "Radio/%s", o->name);
2173         if (c == NULL)
2174                 return NULL;
2175         c->tech = &usbradio_tech;
2176         if (o->sounddev < 0)
2177                 setformat(o, O_RDWR);
2178         c->fds[0] = o->sounddev;        /* -1 if device closed, override later */
2179         c->nativeformats = AST_FORMAT_SLINEAR;
2180         c->readformat = AST_FORMAT_SLINEAR;
2181         c->writeformat = AST_FORMAT_SLINEAR;
2182         c->tech_pvt = o;
2183
2184         if (!ast_strlen_zero(o->language))
2185                 ast_string_field_set(c, language, o->language);
2186         /* Don't use ast_set_callerid() here because it will
2187          * generate a needless NewCallerID event */
2188         c->cid.cid_num = ast_strdup(o->cid_num);
2189         c->cid.cid_ani = ast_strdup(o->cid_num);
2190         c->cid.cid_name = ast_strdup(o->cid_name);
2191         if (!ast_strlen_zero(ext))
2192                 c->cid.cid_dnid = ast_strdup(ext);
2193
2194         o->owner = c;
2195         ast_module_ref(ast_module_info->self);
2196         ast_jb_configure(c, &global_jbconf);
2197         if (state != AST_STATE_DOWN) {
2198                 if (ast_pbx_start(c)) {
2199                         ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
2200                         ast_hangup(c);
2201                         o->owner = c = NULL;
2202                         /* XXX what about the channel itself ? */
2203                         /* XXX what about usecnt ? */
2204                 }
2205         }
2206
2207         return c;
2208 }
2209 /*
2210 */
2211 static struct ast_channel *usbradio_request(const char *type, int format, void *data, int *cause)
2212 {
2213         struct ast_channel *c;
2214         struct chan_usbradio_pvt *o = find_desc(data);
2215
2216         TRACEO(1,("usbradio_request()\n"));
2217
2218         if (0)
2219         {
2220                 ast_log(LOG_WARNING, "usbradio_request type <%s> data 0x%p <%s>\n", type, data, (char *) data);
2221         }
2222         if (o == NULL) {
2223                 ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
2224                 /* XXX we could default to 'dsp' perhaps ? */
2225                 return NULL;
2226         }
2227         if ((format & AST_FORMAT_SLINEAR) == 0) {
2228                 ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
2229                 return NULL;
2230         }
2231         if (o->owner) {
2232                 ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
2233                 *cause = AST_CAUSE_BUSY;
2234                 return NULL;
2235         }
2236         c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
2237         if (c == NULL) {
2238                 ast_log(LOG_WARNING, "Unable to create new usb channel\n");
2239                 return NULL;
2240         }
2241                 
2242         o->b.remoted=0;
2243         xpmr_config(o);
2244
2245         return c;
2246 }
2247 /*
2248 */
2249 static int console_key(int fd, int argc, char *argv[])
2250 {
2251         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
2252
2253         if (argc != 2)
2254                 return RESULT_SHOWUSAGE; 
2255         o->txtestkey = 1;
2256         return RESULT_SUCCESS;
2257 }
2258 /*
2259 */
2260 static int console_unkey(int fd, int argc, char *argv[])
2261 {
2262         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
2263
2264         if (argc != 2)
2265                 return RESULT_SHOWUSAGE;
2266         o->txtestkey = 0;
2267         return RESULT_SUCCESS;
2268 }
2269
2270 static int radio_tune(int fd, int argc, char *argv[])
2271 {
2272         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
2273         int i=0;
2274
2275         if ((argc < 2) || (argc > 4))
2276                 return RESULT_SHOWUSAGE; 
2277
2278         if (argc == 2) /* just show stuff */
2279         {
2280                 ast_cli(fd,"Active radio interface is [%s]\n",usbradio_active);
2281                 ast_cli(fd,"Output A is currently set to ");
2282                 if(o->txmixa==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
2283                 else if (o->txmixa==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
2284                 else if (o->txmixa==TX_OUT_LSD)ast_cli(fd,"tone.\n");
2285                 else if (o->txmixa==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
2286                 else ast_cli(fd,"off.\n");
2287
2288                 ast_cli(fd,"Output B is currently set to ");
2289                 if(o->txmixb==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
2290                 else if (o->txmixb==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
2291                 else if (o->txmixb==TX_OUT_LSD)ast_cli(fd,"tone.\n");
2292                 else if (o->txmixb==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
2293                 else ast_cli(fd,"off.\n");
2294
2295                 ast_cli(fd,"Tx Voice Level currently set to %d\n",o->txmixaset);
2296                 ast_cli(fd,"Tx Tone Level currently set to %d\n",o->txctcssadj);
2297                 ast_cli(fd,"Rx Squelch currently set to %d\n",o->rxsquelchadj);
2298                 ast_cli(fd,"Device String is %s\n",o->devstr);
2299                 return RESULT_SHOWUSAGE;
2300         }
2301
2302         o->pmrChan->b.tuning=1;
2303
2304         if (!strcasecmp(argv[2],"rxnoise")) tune_rxinput(fd,o);
2305         else if (!strcasecmp(argv[2],"rxvoice")) tune_rxvoice(fd,o);
2306         else if (!strcasecmp(argv[2],"rxtone")) tune_rxctcss(fd,o);
2307         else if (!strcasecmp(argv[2],"rxsquelch"))
2308         {
2309                 if (argc == 3)
2310                 {
2311                     ast_cli(fd,"Current Signal Strength is %d\n",((32767-o->pmrChan->rxRssi)*1000/32767));
2312                     ast_cli(fd,"Current Squelch setting is %d\n",o->rxsquelchadj);
2313                         //ast_cli(fd,"Current Raw RSSI        is %d\n",o->pmrChan->rxRssi);
2314                     //ast_cli(fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
2315                 } else {
2316                         i = atoi(argv[3]);
2317                         if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
2318                         ast_cli(fd,"Changed Squelch setting to %d\n",i);
2319                         o->rxsquelchadj = i;
2320                         *(o->pmrChan->prxSquelchAdjust)= ((999 - i) * 32767) / 1000;
2321                 }
2322         }
2323         else if (!strcasecmp(argv[2],"txvoice")) {
2324                 i = 0;
2325
2326                 if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
2327                         (o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
2328                   )
2329                 {
2330                         ast_log(LOG_ERROR,"No txvoice output configured.\n");
2331                 }
2332                 else if (argc == 3)
2333                 {
2334                         if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
2335                                 ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
2336                         else
2337                                 ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
2338                 }
2339                 else
2340                 {
2341                         i = atoi(argv[3]);
2342                         if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
2343
2344                         if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
2345                         {
2346                                 o->txmixaset=i;
2347                                 ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
2348                         }
2349                         else
2350                         {
2351                                 o->txmixbset=i;   
2352                                 ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
2353                         }
2354                         mixer_write(o);
2355                         mult_set(o);
2356                         ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
2357                 }
2358                 o->pmrChan->b.txCtcssInhibit=1;
2359                 tune_txoutput(o,i,fd);
2360                 o->pmrChan->b.txCtcssInhibit=0;
2361         }
2362         else if (!strcasecmp(argv[2],"txall")) {
2363                 i = 0;
2364
2365                 if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
2366                         (o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
2367                   )
2368                 {
2369                         ast_log(LOG_ERROR,"No txvoice output configured.\n");
2370                 }
2371                 else if (argc == 3)
2372                 {
2373                         if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
2374                                 ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
2375                         else
2376                                 ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
2377                 }
2378                 else
2379                 {
2380                         i = atoi(argv[3]);
2381                         if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
2382
2383                         if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
2384                         {
2385                                 o->txmixaset=i;
2386                                 ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
2387                         }
2388                         else
2389                         {
2390                                 o->txmixbset=i;   
2391                                 ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
2392                         }
2393                         mixer_write(o);
2394                         mult_set(o);
2395                         ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
2396                 }
2397                 tune_txoutput(o,i,fd);
2398         }
2399         else if (!strcasecmp(argv[2],"auxvoice")) {
2400                 i = 0;
2401                 if( (o->txmixa!=TX_OUT_AUX) && (o->txmixb!=TX_OUT_AUX))
2402                 {
2403                         ast_log(LOG_WARNING,"No auxvoice output configured.\n");
2404                 }
2405                 else if (argc == 3)
2406                 {
2407                         if(o->txmixa==TX_OUT_AUX)
2408                                 ast_cli(fd,"Current auxvoice setting on Channel A is %d\n",o->txmixaset);
2409                         else
2410                                 ast_cli(fd,"Current auxvoice setting on Channel B is %d\n",o->txmixbset);
2411                 }
2412                 else
2413                 {
2414                         i = atoi(argv[3]);
2415                         if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
2416                         if(o->txmixa==TX_OUT_AUX)
2417                         {
2418                                 o->txmixbset=i;
2419                                 ast_cli(fd,"Changed auxvoice setting on Channel A to %d\n",o->txmixaset);
2420                         }
2421                         else
2422                         {
2423                                 o->txmixbset=i;
2424                                 ast_cli(fd,"Changed auxvoice setting on Channel B to %d\n",o->txmixbset);
2425                         }
2426                         mixer_write(o);
2427                         mult_set(o);
2428                 }
2429                 //tune_auxoutput(o,i);
2430         }
2431         else if (!strcasecmp(argv[2],"txtone"))
2432         {
2433                 if (argc == 3)
2434                         ast_cli(fd,"Current Tx CTCSS modulation setting = %d\n",o->txctcssadj);
2435                 else
2436                 {
2437                         i = atoi(argv[3]);
2438                         if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
2439                         o->txctcssadj = i;
2440                         set_txctcss_level(o);
2441                         ast_cli(fd,"Changed Tx CTCSS modulation setting to %i\n",i);
2442                 }
2443                 o->txtestkey=1;
2444                 usleep(5000000);
2445                 o->txtestkey=0;
2446         }
2447         else if (!strcasecmp(argv[2],"dump")) pmrdump(o);
2448         else if (!strcasecmp(argv[2],"nocap"))  
2449         {
2450                 ast_cli(fd,"File capture (trace) was rx=%d tx=%d and now off.\n",o->b.rxcap2,o->b.txcap2);
2451                 ast_cli(fd,"File capture (raw)   was rx=%d tx=%d and now off.\n",o->b.rxcapraw,o->b.txcapraw);
2452                 o->b.rxcapraw=o->b.txcapraw=o->b.rxcap2=o->b.txcap2=o->pmrChan->b.rxCapture=o->pmrChan->b.txCapture=0;
2453                 if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
2454                 if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
2455                 if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
2456                 if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
2457                 if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
2458                 if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
2459         }
2460         else if (!strcasecmp(argv[2],"rxtracecap")) 
2461         {
2462                 if (!frxcaptrace) frxcaptrace= fopen(RX_CAP_TRACE_FILE,"w");
2463                 ast_cli(fd,"Trace rx on.\n");
2464                 o->b.rxcap2=o->pmrChan->b.rxCapture=1;
2465         }
2466         else if (!strcasecmp(argv[2],"txtracecap")) 
2467         {
2468                 if (!ftxcaptrace) ftxcaptrace= fopen(TX_CAP_TRACE_FILE,"w");
2469                 ast_cli(fd,"Trace tx on.\n");
2470                 o->b.txcap2=o->pmrChan->b.txCapture=1;
2471         }
2472         else if (!strcasecmp(argv[2],"rxcap")) 
2473         {
2474                 if (!frxcapraw) frxcapraw = fopen(RX_CAP_RAW_FILE,"w");
2475                 ast_cli(fd,"cap rx raw on.\n");
2476                 o->b.rxcapraw=1;
2477         }
2478         else if (!strcasecmp(argv[2],"txcap")) 
2479         {
2480                 if (!ftxcapraw) ftxcapraw = fopen(TX_CAP_RAW_FILE,"w");
2481                 ast_cli(fd,"cap tx raw on.\n");
2482                 o->b.txcapraw=1;
2483         }
2484         else if (!strcasecmp(argv[2],"save"))
2485         {
2486                 tune_write(o);
2487                 ast_cli(fd,"Saved radio tuning settings to usbradio_tune_%s.conf\n",o->name);
2488         }
2489         else if (!strcasecmp(argv[2],"load"))
2490         {
2491                 ast_mutex_lock(&o->eepromlock);
2492                 while(o->eepromctl)
2493                 {
2494                         ast_mutex_unlock(&o->eepromlock);
2495                         usleep(10000);
2496                         ast_mutex_lock(&o->eepromlock);
2497                 }
2498                 o->eepromctl = 1;  /* request a load */
2499                 ast_mutex_unlock(&o->eepromlock);
2500
2501                 ast_cli(fd,"Requesting loading of tuning settings from EEPROM for channel %s\n",o->name);
2502         }
2503         else
2504         {
2505                 o->pmrChan->b.tuning=0;
2506                 return RESULT_SHOWUSAGE;
2507         }
2508         o->pmrChan->b.tuning=0;
2509         return RESULT_SUCCESS;
2510 }
2511
2512 /*
2513         set transmit ctcss modulation level
2514         adjust mixer output or internal gain depending on output type
2515         setting range is 0.0 to 0.9
2516 */
2517 static int set_txctcss_level(struct chan_usbradio_pvt *o)
2518 {                                                         
2519         if (o->txmixa == TX_OUT_LSD)
2520         {
2521 //              o->txmixaset=(151*o->txctcssadj) / 1000;
2522                 o->txmixaset=o->txctcssadj;
2523                 mixer_write(o);
2524                 mult_set(o);
2525         }
2526         else if (o->txmixb == TX_OUT_LSD)
2527         {
2528 //              o->txmixbset=(151*o->txctcssadj) / 1000;
2529                 o->txmixbset=o->txctcssadj;
2530                 mixer_write(o);
2531                 mult_set(o);
2532         }
2533         else
2534         {
2535                 *o->pmrChan->ptxCtcssAdjust=(o->txctcssadj * M_Q8) / 1000;
2536         }
2537         return 0;
2538 }
2539 /*
2540         CLI debugging on and off
2541 */
2542 static int radio_set_debug(int fd, int argc, char *argv[])
2543 {
2544         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
2545
2546         o->debuglevel=1;
2547         ast_cli(fd,"usbradio debug on.\n");
2548         return RESULT_SUCCESS;
2549 }
2550
2551 static int radio_set_debug_off(int fd, int argc, char *argv[])
2552 {
2553         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
2554
2555         o->debuglevel=0;
2556         ast_cli(fd,"usbradio debug off.\n");
2557         return RESULT_SUCCESS;
2558 }
2559
2560 static int radio_active(int fd, int argc, char *argv[])
2561 {
2562         if (argc == 2)
2563                 ast_cli(fd, "active (command) USB Radio device is [%s]\n", usbradio_active);
2564         else if (argc != 3)
2565                 return RESULT_SHOWUSAGE;
2566         else {
2567                 struct chan_usbradio_pvt *o;
2568                 if (strcmp(argv[2], "show") == 0) {
2569                         for (o = usbradio_default.next; o; o = o->next)
2570                                 ast_cli(fd, "device [%s] exists\n", o->name);
2571                         return RESULT_SUCCESS;
2572                 }
2573                 o = find_desc(argv[2]);
2574                 if (o == NULL)
2575                         ast_cli(fd, "No device [%s] exists\n", argv[2]);
2576                 else
2577                                 {
2578                                         struct chan_usbradio_pvt *ao;
2579                                         for (ao = usbradio_default.next; ao && ao->name ; ao = ao->next)ao->pmrChan->b.radioactive=0;
2580                     usbradio_active = o->name;
2581                                     o->pmrChan->b.radioactive=1;
2582                                 }
2583         }
2584         return RESULT_SUCCESS;
2585 }
2586 /*
2587         CLI debugging on and off
2588 */
2589 static int radio_set_xpmr_debug(int fd, int argc, char *argv[])
2590 {
2591         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
2592
2593         if (argc == 4)
2594         {
2595                 int i;
2596                 i = atoi(argv[3]);
2597                 if ((i >= 0) && (i <= 100))
2598                 { 
2599                         o->pmrChan->tracelevel=i;
2600                 }
2601     }
2602         // add ability to set it for a number of frames after which it reverts
2603         ast_cli(fd,"usbradio xdebug on tracelevel %i\n",o->pmrChan->tracelevel);
2604
2605         return RESULT_SUCCESS;
2606 }
2607
2608
2609 static char key_usage[] =
2610         "Usage: radio key\n"
2611         "       Simulates COR active.\n";
2612
2613 static char unkey_usage[] =
2614         "Usage: radio unkey\n"
2615         "       Simulates COR un-active.\n";
2616
2617 static char active_usage[] =
2618         "Usage: radio active [device-name]\n"
2619         "       If used without a parameter, displays which device is the current\n"
2620         "one being commanded.  If a device is specified, the commanded radio device is changed\n"
2621         "to the device specified.\n";
2622 /*
2623 radio tune 6 3000               measured tx value
2624 */
2625 static char radio_tune_usage[] =
2626         "Usage: radio tune <function>\n"
2627         "       rxnoise\n"
2628         "       rxvoice\n"
2629         "       rxtone\n"
2630         "       rxsquelch [newsetting]\n"
2631         "       txvoice [newsetting]\n"
2632         "       txtone [newsetting]\n"
2633         "       auxvoice [newsetting]\n"
2634         "       save (settings to tuning file)\n"
2635         "       load (tuning settings from EEPROM)\n"
2636         "\n       All [newsetting]'s are values 0-999\n\n";
2637                                           
2638 #ifndef NEW_ASTERISK
2639
2640 static struct ast_cli_entry cli_usbradio[] = {
2641         { { "radio", "key", NULL },
2642         console_key, "Simulate Rx Signal Present",
2643         key_usage, NULL, NULL},
2644
2645         { { "radio", "unkey", NULL },
2646         console_unkey, "Simulate Rx Signal Lusb",
2647         unkey_usage, NULL, NULL },
2648
2649         { { "radio", "tune", NULL },
2650         radio_tune, "Radio Tune",
2651         radio_tune_usage, NULL, NULL },
2652
2653         { { "radio", "set", "debug", NULL },
2654         radio_set_debug, "Radio Debug",
2655         radio_tune_usage, NULL, NULL },
2656
2657         { { "radio", "set", "debug", "off", NULL },
2658         radio_set_debug_off, "Radio Debug",
2659         radio_tune_usage, NULL, NULL },
2660
2661         { { "radio", "active", NULL },
2662         radio_active, "Change commanded device",
2663         active_usage, NULL, NULL },
2664
2665     { { "radio", "set", "xdebug", NULL },
2666         radio_set_xpmr_debug, "Radio set xpmr debug level",
2667         active_usage, NULL, NULL },
2668
2669 };
2670 #endif
2671
2672 /*
2673  * store the callerid components
2674  */
2675 #if 0
2676 static void store_callerid(struct chan_usbradio_pvt *o, char *s)
2677 {
2678         ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
2679 }
2680 #endif
2681
2682 static void store_rxdemod(struct chan_usbradio_pvt *o, char *s)
2683 {
2684         if (!strcasecmp(s,"no")){
2685                 o->rxdemod = RX_AUDIO_NONE;
2686         }
2687         else if (!strcasecmp(s,"speaker")){
2688                 o->rxdemod = RX_AUDIO_SPEAKER;
2689         }
2690         else if (!strcasecmp(s,"flat")){
2691                         o->rxdemod = RX_AUDIO_FLAT;
2692         }       
2693         else {
2694                 ast_log(LOG_WARNING,"Unrecognized rxdemod parameter: %s\n",s);
2695         }
2696
2697         //ast_log(LOG_WARNING, "set rxdemod = %s\n", s);
2698 }
2699
2700                                            
2701 static void store_txmixa(struct chan_usbradio_pvt *o, char *s)
2702 {
2703         if (!strcasecmp(s,"no")){
2704                 o->txmixa = TX_OUT_OFF;
2705         }
2706         else if (!strcasecmp(s,"voice")){
2707                 o->txmixa = TX_OUT_VOICE;
2708         }
2709         else if (!strcasecmp(s,"tone")){
2710                         o->txmixa = TX_OUT_LSD;
2711         }       
2712         else if (!strcasecmp(s,"composite")){
2713                 o->txmixa = TX_OUT_COMPOSITE;
2714         }       
2715         else if (!strcasecmp(s,"auxvoice")){
2716                 o->txmixa = TX_OUT_AUX;
2717         }       
2718         else {
2719                 ast_log(LOG_WARNING,"Unrecognized txmixa parameter: %s\n",s);
2720         }
2721
2722         //ast_log(LOG_WARNING, "set txmixa = %s\n", s);
2723 }
2724
2725 static void store_txmixb(struct chan_usbradio_pvt *o, char *s)
2726 {
2727         if (!strcasecmp(s,"no")){
2728                 o->txmixb = TX_OUT_OFF;
2729         }
2730         else if (!strcasecmp(s,"voice")){
2731                 o->txmixb = TX_OUT_VOICE;
2732         }
2733         else if (!strcasecmp(s,"tone")){
2734                         o->txmixb = TX_OUT_LSD;
2735         }       
2736         else if (!strcasecmp(s,"composite")){
2737                 o->txmixb = TX_OUT_COMPOSITE;
2738         }       
2739         else if (!strcasecmp(s,"auxvoice")){
2740                 o->txmixb = TX_OUT_AUX;
2741         }       
2742         else {
2743                 ast_log(LOG_WARNING,"Unrecognized txmixb parameter: %s\n",s);
2744         }
2745
2746         //ast_log(LOG_WARNING, "set txmixb = %s\n", s);
2747 }
2748 /*
2749 */
2750 static void store_rxcdtype(struct chan_usbradio_pvt *o, char *s)
2751 {
2752         if (!strcasecmp(s,"no")){
2753                 o->rxcdtype = CD_IGNORE;
2754         }
2755         else if (!strcasecmp(s,"usb")){
2756                 o->rxcdtype = CD_HID;
2757         }
2758         else if (!strcasecmp(s,"dsp")){
2759                 o->rxcdtype = CD_XPMR_NOISE;
2760         }       
2761         else if (!strcasecmp(s,"vox")){
2762                 o->rxcdtype = CD_XPMR_VOX;
2763         }       
2764         else if (!strcasecmp(s,"usbinvert")){
2765                 o->rxcdtype = CD_HID_INVERT;
2766         }       
2767         else {
2768                 ast_log(LOG_WARNING,"Unrecognized rxcdtype parameter: %s\n",s);
2769         }
2770
2771         //ast_log(LOG_WARNING, "set rxcdtype = %s\n", s);
2772 }
2773 /*
2774 */
2775 static void store_rxsdtype(struct chan_usbradio_pvt *o, char *s)
2776 {
2777         if (!strcasecmp(s,"no") || !strcasecmp(s,"SD_IGNORE")){
2778                 o->rxsdtype = SD_IGNORE;
2779         }
2780         else if (!strcasecmp(s,"usb") || !strcasecmp(s,"SD_HID")){
2781                 o->rxsdtype = SD_HID;
2782         }
2783         else if (!strcasecmp(s,"usbinvert") || !strcasecmp(s,"SD_HID_INVERT")){
2784                 o->rxsdtype = SD_HID_INVERT;
2785         }       
2786         else if (!strcasecmp(s,"software") || !strcasecmp(s,"SD_XPMR")){
2787                 o->rxsdtype = SD_XPMR;
2788         }       
2789         else {
2790                 ast_log(LOG_WARNING,"Unrecognized rxsdtype parameter: %s\n",s);
2791         }
2792
2793         //ast_log(LOG_WARNING, "set rxsdtype = %s\n", s);
2794 }
2795 /*
2796 */
2797 static void store_rxgain(struct chan_usbradio_pvt *o, char *s)
2798 {
2799         float f;
2800         sscanf(s,"%f",&f); 
2801         o->rxgain = f;
2802         //ast_log(LOG_WARNING, "set rxgain = %f\n", f);
2803 }
2804 /*
2805 */
2806 static void store_rxvoiceadj(struct chan_usbradio_pvt *o, char *s)
2807 {
2808         float f;
2809         sscanf(s,"%f",&f);
2810         o->rxvoiceadj = f;
2811         //ast_log(LOG_WARNING, "set rxvoiceadj = %f\n", f);
2812 }
2813 /*
2814 */
2815 static void store_rxctcssadj(struct chan_usbradio_pvt *o, char *s)
2816 {
2817         float f;
2818         sscanf(s,"%f",&f);
2819         o->rxctcssadj = f;
2820         //ast_log(LOG_WARNING, "set rxctcssadj = %f\n", f);
2821 }
2822 /*
2823 */
2824 static void store_txtoctype(struct chan_usbradio_pvt *o, char *s)
2825 {
2826         if (!strcasecmp(s,"no") || !strcasecmp(s,"TOC_NONE")){
2827                 o->txtoctype = TOC_NONE;
2828         }
2829         else if (!strcasecmp(s,"phase") || !strcasecmp(s,"TOC_PHASE")){
2830                 o->txtoctype = TOC_PHASE;
2831         }
2832         else if (!strcasecmp(s,"notone") || !strcasecmp(s,"TOC_NOTONE")){
2833                 o->txtoctype = TOC_NOTONE;
2834         }       
2835         else {
2836                 ast_log(LOG_WARNING,"Unrecognized txtoctype parameter: %s\n",s);
2837         }
2838 }
2839 /*
2840 */
2841 static void tune_txoutput(struct chan_usbradio_pvt *o, int value, int fd)
2842 {
2843         o->txtestkey=1;
2844         o->pmrChan->txPttIn=1;
2845         TxTestTone(o->pmrChan, 1);        // generate 1KHz tone at 7200 peak
2846         if (fd > 0) ast_cli(fd,"Tone output starting on channel %s...\n",o->name);
2847         usleep(5000000);
2848         TxTestTone(o->pmrChan, 0);
2849         if (fd > 0) ast_cli(fd,"Tone output ending on channel %s...\n",o->name);
2850         o->pmrChan->txPttIn=0;
2851         o->txtestkey=0;
2852 }
2853 /*
2854 */
2855 static void tune_rxinput(int fd, struct chan_usbradio_pvt *o)
2856 {
2857         const int target=23000;
2858         const int tolerance=2000;
2859         const int settingmin=1;
2860         const int settingstart=2;
2861         const int maxtries=12;
2862
2863         float settingmax;
2864         
2865         int setting=0, tries=0, tmpdiscfactor, meas;
2866         int tunetype=0;
2867
2868         settingmax = o->micmax;
2869
2870         if(o->pmrChan->rxDemod)tunetype=1;
2871         o->pmrChan->b.tuning=1;
2872
2873         setting = settingstart;
2874
2875     ast_cli(fd,"tune rxnoise maxtries=%i, target=%i, tolerance=%i\n",maxtries,target,tolerance);
2876
2877         while(tries<maxtries)
2878         {
2879                 setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL,setting,0);
2880                 setamixer(o->devicenum,MIXER_PARAM_MIC_BOOST,o->rxboostset,0);
2881        
2882                 usleep(100000);
2883                 if(o->rxcdtype!=CD_XPMR_NOISE || o->rxdemod==RX_AUDIO_SPEAKER) 
2884                 {
2885                         // printf("Measure Direct Input\n");
2886                         o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
2887                         o->pmrChan->spsMeasure->discfactor=2000;
2888                         o->pmrChan->spsMeasure->enabled=1;
2889                         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
2890                         usleep(400000); 
2891                         meas=o->pmrChan->spsMeasure->apeak;
2892                         o->pmrChan->spsMeasure->enabled=0;      
2893                 }
2894                 else
2895                 {
2896                         // printf("Measure HF Noise\n");
2897                         tmpdiscfactor=o->pmrChan->spsRx->discfactor;
2898                         o->pmrChan->spsRx->discfactor=(i16)2000;
2899                         o->pmrChan->spsRx->discounteru=o->pmrChan->spsRx->discounterl=0;
2900                         o->pmrChan->spsRx->amax=o->pmrChan->spsRx->amin=0;
2901                         usleep(200000);
2902                         meas=o->pmrChan->rxRssi;
2903                         o->pmrChan->spsRx->discfactor=tmpdiscfactor;
2904                         o->pmrChan->spsRx->discounteru=o->pmrChan->spsRx->discounterl=0;
2905                         o->pmrChan->spsRx->amax=o->pmrChan->spsRx->amin=0;
2906                 }
2907         if(!meas)meas++;
2908                 ast_cli(fd,"tries=%i, setting=%i, meas=%i\n",tries,setting,meas);
2909
2910                 if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
2911                         setting=setting*target/meas;
2912                 }
2913                 else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
2914                 {
2915                         break;
2916                 }
2917
2918                 if(setting<settingmin)setting=settingmin;
2919                 else if(setting>settingmax)setting=settingmax;
2920
2921                 tries++;
2922         }
2923         ast_cli(fd,"DONE tries=%i, setting=%i, meas=%i\n",tries,
2924                 (setting * 1000) / o->micmax,meas);
2925         if( meas<(target-tolerance) || meas>(target+tolerance) ){
2926                 ast_cli(fd,"ERROR: RX INPUT ADJUST FAILED.\n");
2927         }else{
2928                 ast_cli(fd,"INFO: RX INPUT ADJUST SUCCESS.\n"); 
2929                 o->rxmixerset=(setting * 1000) / o->micmax;
2930         }
2931         o->pmrChan->b.tuning=0;
2932 }
2933 /*
2934 */
2935 static void tune_rxvoice(int fd, struct chan_usbradio_pvt *o)
2936 {
2937         const int target=7200;                          // peak
2938         const int tolerance=360;                        // peak to peak
2939         const float settingmin=0.1;
2940         const float settingmax=4;
2941         const float settingstart=1;
2942         const int maxtries=12;
2943
2944         float setting;
2945
2946         int tries=0, meas;
2947
2948         ast_cli(fd,"INFO: RX VOICE ADJUST START.\n");   
2949         ast_cli(fd,"target=%i tolerance=%i \n",target,tolerance);
2950
2951         o->pmrChan->b.tuning=1;
2952         if(!o->pmrChan->spsMeasure)
2953                 ast_cli(fd,"ERROR: NO MEASURE BLOCK.\n");
2954
2955         if(!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
2956                 ast_cli(fd,"ERROR: NO SOURCE OR MEASURE SETTING.\n");
2957
2958         o->pmrChan->spsMeasure->source=o->pmrChan->spsRxOut->sink;
2959         o->pmrChan->spsMeasure->enabled=1;
2960         o->pmrChan->spsMeasure->discfactor=1000;
2961         
2962         setting=settingstart;
2963
2964         // ast_cli(fd,"ERROR: NO MEASURE BLOCK.\n");
2965
2966         while(tries<maxtries)
2967         {
2968                 *(o->pmrChan->prxVoiceAdjust)=setting*M_Q8;
2969                 usleep(10000);
2970         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
2971                 usleep(1000000);
2972                 meas = o->pmrChan->spsMeasure->apeak;
2973                 ast_cli(fd,"tries=%i, setting=%f, meas=%i\n",tries,setting,meas);
2974
2975                 if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
2976                         setting=setting*target/meas;
2977                 }
2978                 else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
2979                 {
2980                         break;
2981                 }
2982                 if(setting<settingmin)setting=settingmin;
2983                 else if(setting>settingmax)setting=settingmax;
2984
2985                 tries++;
2986         }
2987
2988         o->pmrChan->spsMeasure->enabled=0;
2989
2990         ast_cli(fd,"DONE tries=%i, setting=%f, meas=%f\n",tries,setting,(float)meas);
2991         if( meas<(target-tolerance) || meas>(target+tolerance) ){
2992                 ast_cli(fd,"ERROR: RX VOICE GAIN ADJUST FAILED.\n");
2993         }else{
2994                 ast_cli(fd,"INFO: RX VOICE GAIN ADJUST SUCCESS.\n");
2995                 o->rxvoiceadj=setting;
2996         }
2997         o->pmrChan->b.tuning=0;
2998 }
2999 /*
3000 */
3001 static void tune_rxctcss(int fd, struct chan_usbradio_pvt *o)
3002 {
3003         const int target=2400;           // was 4096 pre 20080205
3004         const int tolerance=100;
3005         const float settingmin=0.1;
3006         const float settingmax=8;
3007         const float settingstart=1;
3008         const int maxtries=12;
3009
3010         float setting;
3011         int tries=0, meas;
3012
3013         ast_cli(fd,"INFO: RX CTCSS ADJUST START.\n");   
3014         ast_cli(fd,"target=%i tolerance=%i \n",target,tolerance);
3015
3016         o->pmrChan->b.tuning=1;
3017         o->pmrChan->spsMeasure->source=o->pmrChan->prxCtcssMeasure;
3018         o->pmrChan->spsMeasure->discfactor=400;
3019         o->pmrChan->spsMeasure->enabled=1;
3020
3021         setting=settingstart;
3022
3023         while(tries<maxtries)
3024         {
3025                 *(o->pmrChan->prxCtcssAdjust)=setting*M_Q8;
3026                 usleep(10000);
3027         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
3028                 usleep(500000);
3029                 meas = o->pmrChan->spsMeasure->apeak;
3030                 ast_cli(fd,"tries=%i, setting=%f, meas=%i\n",tries,setting,meas);
3031
3032                 if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
3033                         setting=setting*target/meas;
3034                 }
3035                 else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
3036                 {
3037                         break;
3038                 }
3039                 if(setting<settingmin)setting=settingmin;
3040                 else if(setting>settingmax)setting=settingmax;
3041
3042                 tries++;
3043         }
3044         o->pmrChan->spsMeasure->enabled=0;
3045         ast_cli(fd,"DONE tries=%i, setting=%f, meas=%f\n",tries,setting,(float)meas);
3046         if( meas<(target-tolerance) || meas>(target+tolerance) ){
3047                 ast_cli(fd,"ERROR: RX CTCSS GAIN ADJUST FAILED.\n");
3048         }else{
3049                 ast_cli(fd,"INFO: RX CTCSS GAIN ADJUST SUCCESS.\n");
3050                 o->rxctcssadj=setting;
3051         }
3052         o->pmrChan->b.tuning=0;
3053 }
3054 /*
3055         after radio tune is performed data is serialized here 
3056 */
3057 static void tune_write(struct chan_usbradio_pvt *o)
3058 {
3059         FILE *fp;
3060         char fname[200];
3061
3062         snprintf(fname,sizeof(fname) - 1,"/etc/asterisk/usbradio_tune_%s.conf",o->name);
3063         fp = fopen(fname,"w");
3064
3065         fprintf(fp,"[%s]\n",o->name);
3066
3067         fprintf(fp,"; name=%s\n",o->name);
3068         fprintf(fp,"; devicenum=%i\n",o->devicenum);
3069         fprintf(fp,"devstr=%s\n",o->devstr);
3070         fprintf(fp,"rxmixerset=%i\n",o->rxmixerset);
3071         fprintf(fp,"txmixaset=%i\n",o->txmixaset);
3072         fprintf(fp,"txmixbset=%i\n",o->txmixbset);
3073         fprintf(fp,"rxvoiceadj=%f\n",o->rxvoiceadj);
3074         fprintf(fp,"rxctcssadj=%f\n",o->rxctcssadj);
3075         fprintf(fp,"txctcssadj=%i\n",o->txctcssadj);
3076         fprintf(fp,"rxsquelchadj=%i\n",o->rxsquelchadj);
3077         fclose(fp);
3078
3079         if(o->wanteeprom)
3080         {
3081                 ast_mutex_lock(&o->eepromlock);
3082                 while(o->eepromctl)
3083                 {
3084                         ast_mutex_unlock(&o->eepromlock);
3085                         usleep(10000);
3086                         ast_mutex_lock(&o->eepromlock);
3087                 }
3088                 o->eeprom[EEPROM_RXMIXERSET] = o->rxmixerset;
3089                 o->eeprom[EEPROM_TXMIXASET] = o->txmixaset;
3090                 o->eeprom[EEPROM_TXMIXBSET] = o->txmixbset;
3091                 memcpy(&o->eeprom[EEPROM_RXVOICEADJ],&o->rxvoiceadj,sizeof(float));
3092                 memcpy(&o->eeprom[EEPROM_RXCTCSSADJ],&o->rxctcssadj,sizeof(float));
3093                 o->eeprom[EEPROM_TXCTCSSADJ] = o->txctcssadj;
3094                 o->eeprom[EEPROM_RXSQUELCHADJ] = o->rxsquelchadj;
3095                 o->eepromctl = 2;  /* request a write */
3096                 ast_mutex_unlock(&o->eepromlock);
3097         }
3098 }
3099 //
3100 static void mixer_write(struct chan_usbradio_pvt *o)
3101 {
3102         setamixer(o->devicenum,MIXER_PARAM_MIC_PLAYBACK_SW,0,0);
3103         setamixer(o->devicenum,MIXER_PARAM_MIC_PLAYBACK_VOL,0,0);
3104         setamixer(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_SW,1,0);
3105         setamixer(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_VOL,
3106                 o->txmixaset * o->spkrmax / 1000,
3107                 o->txmixbset * o->spkrmax / 1000);
3108         setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL,
3109                 o->rxmixerset * o->micmax / 1000,0);
3110         setamixer(o->devicenum,MIXER_PARAM_MIC_BOOST,o->rxboostset,0);
3111         setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_SW,1,0);
3112 }
3113 /*
3114         adjust dsp multiplier to add resolution to tx level adjustment
3115 */
3116 static void mult_set(struct chan_usbradio_pvt *o)
3117 {
3118
3119         if(o->pmrChan->spsTxOutA) {
3120                 o->pmrChan->spsTxOutA->outputGain = 
3121                         mult_calc((o->txmixaset * 152) / 1000);
3122         }
3123         if(o->pmrChan->spsTxOutB){
3124                 o->pmrChan->spsTxOutB->outputGain = 
3125                         mult_calc((o->txmixbset * 152) / 1000);
3126         }
3127 }
3128 //
3129 // input 0 - 151 outputs are pot and multiplier
3130 //
3131 static int mult_calc(int value)
3132 {
3133         const int multx=M_Q8;
3134         int pot,mult;
3135
3136         pot=((int)(value/4)*4)+2;
3137         mult = multx-( ( multx * (3-(value%4)) ) / (pot+2) );
3138         return(mult);
3139 }
3140
3141 #define pd(x) {printf(#x" = %d\n",x);}
3142 #define pp(x) {printf(#x" = %p\n",x);}
3143 #define ps(x) {printf(#x" = %s\n",x);}
3144 #define pf(x) {printf(#x" = %f\n",x);}
3145
3146
3147 #if 0
3148 /*
3149         do hid output if only requirement is ptt out
3150         this give fastest performance with least overhead
3151         where gpio inputs are not required.
3152 */
3153
3154 static int usbhider(struct chan_usbradio_pvt *o, int opt)
3155 {
3156         unsigned char buf[4];
3157         char lastrx, txtmp;
3158
3159         if(opt)
3160         {
3161                 struct usb_device *usb_dev;
3162
3163                 usb_dev = hid_device_init(o->devstr);
3164                 if (usb_dev == NULL) {
3165                         ast_log(LOG_ERROR,"USB HID device not found\n");
3166                         return -1;
3167                 }
3168                 o->usb_handle = usb_open(usb_dev);
3169                 if (o->usb_handle == NULL) {
3170                     ast_log(LOG_ERROR,"Not able to open USB device\n");
3171                         return -1;
3172                 }
3173                 if (usb_claim_interface(o->usb_handle,C108_HID_INTERFACE) < 0)
3174                 {
3175                     if (usb_detach_kernel_driver_np(o->usb_handle,C108_HID_INTERFACE) < 0) {
3176                             ast_log(LOG_ERROR,"Not able to detach the USB device\n");
3177                                 return -1;
3178                         }
3179                         if (usb_claim_interface(o->usb_handle,C108_HID_INTERFACE) < 0) {
3180                                 ast_log(LOG_ERROR,"Not able to claim the USB device\n");
3181                                 return -1;
3182                         }
3183                 }
3184         
3185                 memset(buf,0,sizeof(buf));
3186                 buf[2] = o->hid_gpio_ctl;
3187                 buf[1] = 0;
3188                 hid_set_outputs(o->usb_handle,buf);
3189                 memcpy(bufsave,buf,sizeof(buf));
3190          
3191                 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
3192                 o->lasttx=0;
3193         }
3194
3195         /* if change in tx state as controlled by xpmr */
3196         txtmp=o->pmrChan->txPttOut;
3197                         
3198         if (o->lasttx != txtmp)
3199         {
3200                 o->pmrChan->txPttHid=o->lasttx = txtmp;
3201                 if(o->debuglevel)printf("usbhid: tx set to %d\n",txtmp);
3202                 buf[o->hid_gpio_loc] = 0;
3203                 if (!o->invertptt)
3204                 {
3205                         if (txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
3206                 }
3207                 else
3208                 {
3209                         if (!txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
3210                 }
3211                 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
3212                 hid_set_outputs(o->usb_handle,buf);
3213         }
3214
3215         return(0);
3216 }
3217 #endif
3218 /*
3219 */
3220 static void pmrdump(struct chan_usbradio_pvt *o)
3221 {
3222         t_pmr_chan *p;
3223         int i;
3224
3225         p=o->pmrChan;
3226
3227         printf("\nodump()\n");
3228
3229         pd(o->devicenum);
3230         ps(o->devstr);
3231
3232         pd(o->micmax);
3233         pd(o->spkrmax);
3234
3235         pd(o->rxdemod);
3236         pd(o->rxcdtype);
3237         pd(o->rxsdtype);
3238         pd(o->txtoctype);
3239
3240         pd(o->rxmixerset);
3241         pd(o->rxboostset);
3242
3243         pf(o->rxvoiceadj);
3244         pf(o->rxctcssadj);
3245         pd(o->rxsquelchadj);
3246
3247         ps(o->txctcssdefault);
3248         ps(o->txctcssfreq);
3249
3250         pd(o->numrxctcssfreqs);
3251         if(o->numrxctcssfreqs>0)
3252         {
3253                 for(i=0;i<o->numrxctcssfreqs;i++)
3254                 {
3255                         printf(" %i =  %s  %s\n",i,o->rxctcss[i],o->txctcss[i]); 
3256                 }
3257         }
3258
3259         pd(o->b.rxpolarity);
3260         pd(o->b.txpolarity);
3261
3262         pd(o->txprelim);
3263         pd(o->txmixa);
3264         pd(o->txmixb);
3265         
3266         pd(o->txmixaset);
3267         pd(o->txmixbset);
3268         
3269         printf("\npmrdump()\n");
3270  
3271         pd(p->devicenum);
3272
3273         printf("prxSquelchAdjust=%i\n",*(o->pmrChan->prxSquelchAdjust));
3274
3275         pd(p->rxCarrierPoint);
3276         pd(p->rxCarrierHyst);
3277
3278         pd(*p->prxVoiceAdjust);
3279         pd(*p->prxCtcssAdjust);
3280
3281         pd(p->rxfreq);
3282         pd(p->txfreq);
3283
3284         pd(p->rxCtcss->relax);
3285         //pf(p->rxCtcssFreq);   
3286         pd(p->numrxcodes);
3287         if(o->pmrChan->numrxcodes>0)
3288         {
3289                 for(i=0;i<o->pmrChan->numrxcodes;i++)
3290                 {
3291                         printf(" %i = %s\n",i,o->pmrChan->pRxCode[i]); 
3292                 }
3293         }
3294
3295         pd(p->txTocType);
3296         ps(p->pTxCodeDefault);
3297         pd(p->txcodedefaultsmode);
3298         pd(p->numtxcodes);
3299         if(o->pmrChan->numtxcodes>0)
3300         {
3301                 for(i=0;i<o->pmrChan->numtxcodes;i++)
3302                 {                                                                                                        
3303                         printf(" %i = %s\n",i,o->pmrChan->pTxCode[i]); 
3304                 }
3305         }
3306
3307         pd(p->b.rxpolarity);
3308         pd(p->b.txpolarity);
3309         pd(p->b.dcsrxpolarity);
3310         pd(p->b.dcstxpolarity);
3311         pd(p->b.lsdrxpolarity);
3312         pd(p->b.lsdtxpolarity);
3313
3314         pd(p->txMixA);
3315         pd(p->txMixB);
3316     
3317         pd(p->rxDeEmpEnable);
3318         pd(p->rxCenterSlicerEnable);
3319         pd(p->rxCtcssDecodeEnable);
3320         pd(p->rxDcsDecodeEnable);
3321         pd(p->b.ctcssRxEnable);
3322         pd(p->b.dcsRxEnable);
3323         pd(p->b.lmrRxEnable);
3324         pd(p->b.dstRxEnable);
3325         pd(p->smode);
3326
3327         pd(p->txHpfEnable);
3328         pd(p->txLimiterEnable);
3329         pd(p->txPreEmpEnable);
3330         pd(p->txLpfEnable);
3331
3332         if(p->spsTxOutA)pd(p->spsTxOutA->outputGain);
3333         if(p->spsTxOutB)pd(p->spsTxOutB->outputGain);
3334         pd(p->txPttIn);
3335         pd(p->txPttOut);
3336
3337         pd(p->tracetype);
3338
3339         return;
3340 }
3341 /*
3342         takes data from a chan_usbradio_pvt struct (e.g. o->)
3343         and configures the xpmr radio layer
3344 */
3345 static int xpmr_config(struct chan_usbradio_pvt *o)
3346 {
3347         //ast_log(LOG_NOTICE,"xpmr_config()\n");
3348
3349         TRACEO(1,("xpmr_config()\n"));
3350
3351         if(o->pmrChan==NULL)
3352         {
3353                 ast_log(LOG_ERROR,"pmr channel structure NULL\n");
3354                 return 1;
3355         }
3356
3357         o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
3358         o->pmrChan->txpower=0;
3359
3360         if(o->b.remoted)
3361         {
3362                 o->pmrChan->pTxCodeDefault = o->set_txctcssdefault;
3363                 o->pmrChan->pRxCodeSrc=o->set_rxctcssfreqs;
3364                 o->pmrChan->pTxCodeSrc=o->set_txctcssfreqs;
3365
3366                 o->pmrChan->rxfreq=o->set_rxfreq;
3367                 o->pmrChan->txfreq=o->set_txfreq;
3368                 /* printf(" remoted %s %s --> %s \n",o->pmrChan->txctcssdefault,
3369                         o->pmrChan->txctcssfreq,o->pmrChan->rxctcssfreq); */
3370         }
3371         else
3372         {
3373                 // set xpmr pointers to source strings
3374
3375                 o->pmrChan->pTxCodeDefault = o->txctcssdefault;
3376                 o->pmrChan->pRxCodeSrc     = o->rxctcssfreqs;
3377                 o->pmrChan->pTxCodeSrc     = o->txctcssfreqs;
3378         
3379                 o->pmrChan->rxfreq = o->rxfreq;
3380                 o->pmrChan->txfreq = o->txfreq;
3381         }
3382         
3383         code_string_parse(o->pmrChan);
3384         if(o->pmrChan->rxfreq) o->pmrChan->b.reprog=1;
3385
3386         return 0;
3387 }
3388 /*
3389  * grab fields from the config file, init the descriptor and open the device.
3390  */
3391 static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
3392 {
3393         struct ast_variable *v;
3394         struct chan_usbradio_pvt *o;
3395         struct ast_config *cfg1;
3396         int i;
3397         char fname[200];
3398 #ifdef  NEW_ASTERISK
3399         struct ast_flags zeroflag = {0};
3400 #endif
3401         if (ctg == NULL) {
3402                 traceusb1((" store_config() ctg == NULL\n"));
3403                 o = &usbradio_default;
3404                 ctg = "general";
3405         } else {
3406                 /* "general" is also the default thing */
3407                 if (strcmp(ctg, "general") == 0) {
3408                         o = &usbradio_default;
3409                 } else {
3410                     // ast_log(LOG_NOTICE,"ast_calloc for chan_usbradio_pvt of %s\n",ctg);
3411                         if (!(o = ast_calloc(1, sizeof(*o))))
3412                                 return NULL;
3413                         *o = usbradio_default;
3414                         o->name = ast_strdup(ctg);
3415                         if (!usbradio_active) 
3416                                 usbradio_active = o->name;
3417                 }
3418         }
3419         ast_mutex_init(&o->eepromlock);
3420         strcpy(o->mohinterpret, "default");
3421         /* fill other fields from configuration */
3422         for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
3423                 M_START((char *)v->name, (char *)v->value);
3424
3425                 /* handle jb conf */
3426                 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
3427                         continue;
3428
3429 #if     0
3430                         M_BOOL("autoanswer", o->autoanswer)
3431                         M_BOOL("autohangup", o->autohangup)
3432                         M_BOOL("overridecontext", o->overridecontext)
3433                         M_STR("context", o->ctx)
3434                         M_STR("language", o->language)
3435                         M_STR("mohinterpret", o->mohinterpret)
3436                         M_STR("extension", o->ext)
3437                         M_F("callerid", store_callerid(o, v->value))
3438 #endif
3439                         M_UINT("frags", o->frags)
3440                         M_UINT("queuesize",o->queuesize)
3441 #if 0
3442                         M_UINT("devicenum",o->devicenum)
3443 #endif
3444                         M_UINT("debug", usbradio_debug)
3445                         M_BOOL("rxcpusaver",o->rxcpusaver)
3446                         M_BOOL("txcpusaver",o->txcpusaver)
3447                         M_BOOL("invertptt",o->invertptt)
3448                         M_F("rxdemod",store_rxdemod(o,(char *)v->value))
3449                         M_BOOL("txprelim",o->txprelim);
3450                         M_F("txmixa",store_txmixa(o,(char *)v->value))
3451                         M_F("txmixb",store_txmixb(o,(char *)v->value))
3452                         M_F("carrierfrom",store_rxcdtype(o,(char *)v->value))
3453                         M_F("rxsdtype",store_rxsdtype(o,(char *)v->value))
3454                     M_UINT("rxsqvox",o->rxsqvoxadj)
3455                         M_STR("txctcssdefault",o->txctcssdefault)
3456                         M_STR("rxctcssfreqs",o->rxctcssfreqs)
3457                         M_STR("txctcssfreqs",o->txctcssfreqs)
3458                         M_UINT("rxfreq",o->rxfreq)
3459                         M_UINT("txfreq",o->txfreq)
3460                         M_F("rxgain",store_rxgain(o,(char *)v->value))
3461                         M_BOOL("rxboost",o->rxboostset)
3462                         M_UINT("rxctcssrelax",o->rxctcssrelax)
3463                         M_F("txtoctype",store_txtoctype(o,(char *)v->value))
3464                         M_UINT("hdwtype",o->hdwtype)
3465                         M_UINT("eeprom",o->wanteeprom)
3466                         M_UINT("duplex",o->radioduplex)
3467                         M_UINT("txsettletime",o->txsettletime)
3468                         M_BOOL("rxpolarity",o->b.rxpolarity)
3469                         M_BOOL("txpolarity",o->b.txpolarity)
3470                         M_BOOL("dcsrxpolarity",o->b.dcsrxpolarity)
3471                         M_BOOL("dcstxpolarity",o->b.dcstxpolarity)
3472                         M_BOOL("lsdrxpolarity",o->b.lsdrxpolarity)
3473                         M_BOOL("lsdtxpolarity",o->b.lsdtxpolarity)
3474                         M_BOOL("loopback",o->b.loopback)
3475                         M_BOOL("radioactive",o->b.radioactive)
3476                         M_UINT("rptnum",o->rptnum)
3477                         M_UINT("idleinterval",o->idleinterval)
3478                         M_UINT("turnoffs",o->turnoffs)
3479                         M_UINT("tracetype",o->tracetype)
3480                         M_UINT("tracelevel",o->tracelevel)
3481                         M_UINT("area",o->area)
3482                         M_STR("ukey",o->ukey)
3483                         M_END(;
3484                         );
3485         }
3486
3487         o->debuglevel=0;
3488
3489         if (o == &usbradio_default)             /* we are done with the default */
3490                 return NULL;
3491
3492         snprintf(fname,sizeof(fname) - 1,config1,o->name);
3493 #ifdef  NEW_ASTERISK
3494         cfg1 = ast_config_load(fname,zeroflag);
3495 #else
3496         cfg1 = ast_config_load(fname);
3497 #endif
3498         o->rxmixerset = 500;
3499         o->txmixaset = 500;
3500         o->txmixbset = 500;
3501         o->rxvoiceadj = 0.5;
3502         o->rxctcssadj = 0.5;
3503         o->txctcssadj = 200;
3504         o->rxsquelchadj = 500;
3505         o->devstr[0] = 0;
3506         if (cfg1) {
3507                 for (v = ast_variable_browse(cfg1, o->name); v; v = v->next) {
3508         
3509                         M_START((char *)v->name, (char *)v->value);
3510                         M_UINT("rxmixerset", o->rxmixerset)
3511                         M_UINT("txmixaset", o->txmixaset)
3512                         M_UINT("txmixbset", o->txmixbset)
3513                         M_F("rxvoiceadj",store_rxvoiceadj(o,(char *)v->value))
3514                         M_F("rxctcssadj",store_rxctcssadj(o,(char *)v->value))
3515                         M_UINT("txctcssadj",o->txctcssadj);
3516                         M_UINT("rxsquelchadj", o->rxsquelchadj)
3517                         M_STR("devstr", o->devstr)
3518                         M_END(;
3519                         );
3520                 }
3521                 ast_config_destroy(cfg1);
3522         } else ast_log(LOG_WARNING,"File %s not found, using default parameters.\n",fname);
3523
3524         if(o->wanteeprom)
3525         {
3526                 ast_mutex_lock(&o->eepromlock);
3527                 while(o->eepromctl)
3528                 {
3529                         ast_mutex_unlock(&o->eepromlock);
3530                         usleep(10000);
3531                         ast_mutex_lock(&o->eepromlock);
3532                 }
3533                 o->eepromctl = 1;  /* request a load */
3534                 ast_mutex_unlock(&o->eepromlock);
3535         }
3536         /* if our specified one exists in the list */
3537         if ((!usb_list_check(o->devstr)) || find_desc_usb(o->devstr))
3538         {
3539                 char *s;
3540
3541                 for(s = usb_device_list; *s; s += strlen(s) + 1)
3542                 {
3543                         if (!find_desc_usb(s)) break;
3544                 }
3545                 if (!*s)
3546                 {
3547                         ast_log(LOG_WARNING,"Unable to assign USB device for channel %s\n",o->name);
3548                         goto error;
3549                 }
3550                 ast_log(LOG_NOTICE,"Assigned USB device %s to usbradio channel %s\n",s,o->name);
3551                 strcpy(o->devstr,s);
3552         }
3553
3554         i = usb_get_usbdev(o->devstr);
3555         if (i < 0)
3556         {
3557                 ast_log(LOG_ERROR,"Not able to find alsa USB device\n");
3558                 goto error;
3559         }
3560         o->devicenum = i;
3561
3562         o->micmax = amixer_max(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL);
3563         o->spkrmax = amixer_max(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_VOL);
3564         o->lastopen = ast_tvnow();      /* don't leave it 0 or tvdiff may wrap */
3565         o->dsp = ast_dsp_new();
3566         if (o->dsp)
3567         {
3568 #ifdef  NEW_ASTERISK
3569           ast_dsp_set_features(o->dsp,DSP_FEATURE_DIGIT_DETECT);
3570           ast_dsp_set_digitmode(o->dsp,DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
3571 #else
3572           ast_dsp_set_features(o->dsp,DSP_FEATURE_DTMF_DETECT);
3573           ast_dsp_digitmode(o->dsp,DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
3574 #endif
3575         }
3576
3577         if(o->pmrChan==NULL)
3578         {
3579                 t_pmr_chan tChan;
3580
3581                 // ast_log(LOG_NOTICE,"createPmrChannel() %s\n",o->name);
3582                 memset(&tChan,0,sizeof(t_pmr_chan));
3583
3584                 tChan.pTxCodeDefault = o->txctcssdefault;
3585                 tChan.pRxCodeSrc     = o->rxctcssfreqs;
3586                 tChan.pTxCodeSrc     = o->txctcssfreqs;
3587
3588                 tChan.rxDemod=o->rxdemod;
3589                 tChan.rxCdType=o->rxcdtype;
3590                 tChan.rxSqVoxAdj=o->rxsqvoxadj;
3591
3592                 if (o->txprelim) 
3593                         tChan.txMod = 2;
3594
3595                 tChan.txMixA = o->txmixa;
3596                 tChan.txMixB = o->txmixb;
3597
3598                 tChan.rxCpuSaver=o->rxcpusaver;
3599                 tChan.txCpuSaver=o->txcpusaver;
3600
3601                 tChan.b.rxpolarity=o->b.rxpolarity;
3602                 tChan.b.txpolarity=o->b.txpolarity;
3603
3604                 tChan.b.dcsrxpolarity=o->b.dcsrxpolarity;
3605                 tChan.b.dcstxpolarity=o->b.dcstxpolarity;
3606
3607                 tChan.b.lsdrxpolarity=o->b.lsdrxpolarity;
3608                 tChan.b.lsdtxpolarity=o->b.lsdtxpolarity;
3609
3610                 tChan.tracetype=o->tracetype;
3611                 tChan.tracelevel=o->tracelevel;
3612                 tChan.rptnum=o->rptnum;
3613                 tChan.idleinterval=o->idleinterval;
3614                 tChan.turnoffs=o->turnoffs;
3615                 tChan.area=o->area;
3616                 tChan.ukey=o->ukey;
3617                 tChan.name=o->name;
3618
3619                 o->pmrChan=createPmrChannel(&tChan,FRAME_SIZE);
3620                                                                          
3621                 o->pmrChan->radioDuplex=o->radioduplex;
3622                 o->pmrChan->b.loopback=0;