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