Large cleanup of DSP code
[asterisk/asterisk.git] / channels / chan_usbradio.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  * Copyright (C) 2007, Jim Dixon
6  *
7  * Jim Dixon, WB6NIL <jim@lambdatel.com>
8  * Steve Henke, W9SH  <w9sh@arrl.net>
9  * Based upon work by Mark Spencer <markster@digium.com> and Luigi Rizzo
10  *
11  * See http://www.asterisk.org for more information about
12  * the Asterisk project. Please do not directly contact
13  * any of the maintainers of this project for assistance;
14  * the project provides a web site, mailing lists and IRC
15  * channels for your use.
16  *
17  * This program is free software, distributed under the terms of
18  * the GNU General Public License Version 2. See the LICENSE file
19   * at the top of the source tree.
20  */
21
22 /*! \file
23  *
24  * \brief Channel driver for CM108 USB Cards with Radio Interface
25  *
26  * \author Jim Dixon  <jim@lambdatel.com>
27  * \author Steve Henke  <w9sh@arrl.net>
28  *
29  * \par See also
30  * \arg \ref Config_usbradio
31  *
32  * \ingroup channel_drivers
33  */
34
35 /*** MODULEINFO
36         <depend>asound</depend>
37         <depend>usb</depend>
38         <defaultenabled>no</defaultenabled>
39  ***/
40
41 #include "asterisk.h"
42
43 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
44
45 #include <ctype.h>
46 #include <math.h>
47 #include <sys/ioctl.h>
48 #include <fcntl.h>
49 #include <sys/time.h>
50 #include <usb.h>
51 #include <alsa/asoundlib.h>
52
53 #define CHAN_USBRADIO           1
54
55 #define DEBUG_USBRADIO          0       
56 #define DEBUG_CAPTURES                  1
57                 
58 #define DEBUG_CAP_RX_OUT                0               
59 #define DEBUG_CAP_TX_OUT            0                   
60
61 #define DEBUG_FILETEST                  0                        
62
63 #define RX_CAP_RAW_FILE                 "/tmp/rx_cap_in.pcm"
64 #define RX_CAP_TRACE_FILE               "/tmp/rx_trace.pcm"
65 #define RX_CAP_OUT_FILE                 "/tmp/rx_cap_out.pcm"
66
67 #define TX_CAP_RAW_FILE                 "/tmp/tx_cap_in.pcm"
68 #define TX_CAP_TRACE_FILE               "/tmp/tx_trace.pcm"
69 #define TX_CAP_OUT_FILE                 "/tmp/tx_cap_out.pcm"
70
71 #define MIXER_PARAM_MIC_PLAYBACK_SW "Mic Playback Switch"
72 #define MIXER_PARAM_MIC_PLAYBACK_VOL "Mic Playback Volume"
73 #define MIXER_PARAM_MIC_CAPTURE_SW "Mic Capture Switch"
74 #define MIXER_PARAM_MIC_CAPTURE_VOL "Mic Capture Volume"
75 #define MIXER_PARAM_MIC_BOOST "Auto Gain Control"
76 #define MIXER_PARAM_SPKR_PLAYBACK_SW "Speaker Playback Switch"
77 #define MIXER_PARAM_SPKR_PLAYBACK_VOL "Speaker Playback Volume"
78
79 #include "./xpmr/xpmr.h"
80
81 #if 0
82 #define traceusb1(a, ...) ast_debug(4, a __VA_ARGS__)
83 #else
84 #define traceusb1(a, ...)
85 #endif
86
87 #if 0
88 #define traceusb2(a, ...) ast_debug(4, a __VA_ARGS__)
89 #else
90 #define traceusb2(a, ...)
91 #endif
92
93 #ifdef __linux
94 #include <linux/soundcard.h>
95 #elif defined(__FreeBSD__)
96 #include <sys/soundcard.h>
97 #else
98 #include <soundcard.h>
99 #endif
100
101 #include "asterisk/lock.h"
102 #include "asterisk/frame.h"
103 #include "asterisk/callerid.h"
104 #include "asterisk/channel.h"
105 #include "asterisk/module.h"
106 #include "asterisk/pbx.h"
107 #include "asterisk/config.h"
108 #include "asterisk/cli.h"
109 #include "asterisk/utils.h"
110 #include "asterisk/causes.h"
111 #include "asterisk/endian.h"
112 #include "asterisk/stringfields.h"
113 #include "asterisk/abstract_jb.h"
114 #include "asterisk/musiconhold.h"
115 #include "asterisk/dsp.h"
116
117 #define C108_VENDOR_ID          0x0d8c
118 #define C108_PRODUCT_ID         0x000c
119 #define C108_HID_INTERFACE      3
120
121 #define HID_REPORT_GET          0x01
122 #define HID_REPORT_SET          0x09
123
124 #define HID_RT_INPUT            0x01
125 #define HID_RT_OUTPUT           0x02
126
127 /*! Global jitterbuffer configuration - by default, jb is disabled */
128 static struct ast_jb_conf default_jbconf =
129 {
130         .flags = 0,
131         .max_size = -1,
132         .resync_threshold = -1,
133         .impl = "",
134 };
135 static struct ast_jb_conf global_jbconf;
136
137 /*! 
138  * usbradio.conf parameters are
139 START_CONFIG
140
141 [general]
142     ; General config options, with default values shown.
143     ; You should use one section per device, with [general] being used
144     ; for the device.
145     ;
146     ;
147     ; debug = 0x0               ; misc debug flags, default is 0
148
149         ; Set the device to use for I/O
150         ; devicenum = 0
151         ; Set hardware type here
152         ; hdwtype=0               ; 0=limey, 1=sph
153
154         ; rxboostset=0          ; no rx gain boost
155         ; rxctcssrelax=1        ; reduce talkoff from radios w/o CTCSS Tx HPF
156         ; rxctcssfreq=100.0      ; rx ctcss freq in floating point. must be in table
157         ; txctcssfreq=100.0      ; tx ctcss freq, any frequency permitted
158
159         ; carrierfrom=dsp     ;no,usb,usbinvert,dsp,vox
160         ; ctcssfrom=dsp       ;no,usb,dsp
161
162         ; rxdemod=flat            ; input type from radio: no,speaker,flat
163         ; txprelim=yes            ; output is pre-emphasised and limited
164         ; txtoctype=no            ; no,phase,notone
165
166         ; txmixa=composite        ;no,voice,tone,composite,auxvoice
167         ; txmixb=no               ;no,voice,tone,composite,auxvoice
168
169         ; invertptt=0
170
171     ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
172     ; jbenable = yes              ; Enables the use of a jitterbuffer on the receiving side of an
173                                   ; USBRADIO channel. Defaults to "no". An enabled jitterbuffer will
174                                   ; be used only if the sending side can create and the receiving
175                                   ; side can not accept jitter. The USBRADIO channel can't accept jitter,
176                                   ; thus an enabled jitterbuffer on the receive USBRADIO side will always
177                                   ; be used if the sending side can create jitter.
178
179     ; jbmaxsize = 200             ; Max length of the jitterbuffer in milliseconds.
180
181     ; jbresyncthreshold = 1000    ; Jump in the frame timestamps over which the jitterbuffer is
182                                   ; resynchronized. Useful to improve the quality of the voice, with
183                                   ; big jumps in/broken timestamps, usualy sent from exotic devices
184                                   ; and programs. Defaults to 1000.
185
186     ; jbimpl = fixed              ; Jitterbuffer implementation, used on the receiving side of an USBRADIO
187                                   ; channel. Two implementations are currenlty available - "fixed"
188                                   ; (with size always equals to jbmax-size) and "adaptive" (with
189                                   ; variable size, actually the new jb of IAX2). Defaults to fixed.
190
191     ; jblog = no                  ; Enables jitterbuffer frame logging. Defaults to "no".
192     ;-----------------------------------------------------------------------------------
193
194
195 END_CONFIG
196
197  */
198
199 /*!
200  * The following parameters are used in the driver:
201  *
202  *  FRAME_SIZE  the size of an audio frame, in samples.
203  *              160 is used almost universally, so you should not change it.
204  *
205  *  FRAGS       the argument for the SETFRAGMENT ioctl.
206  *              Overridden by the 'frags' parameter in usbradio.conf
207  *
208  *              Bits 0-7 are the base-2 log of the device's block size,
209  *              bits 16-31 are the number of blocks in the driver's queue.
210  *              There are a lot of differences in the way this parameter
211  *              is supported by different drivers, so you may need to
212  *              experiment a bit with the value.
213  *              A good default for linux is 30 blocks of 64 bytes, which
214  *              results in 6 frames of 320 bytes (160 samples).
215  *              FreeBSD works decently with blocks of 256 or 512 bytes,
216  *              leaving the number unspecified.
217  *              Note that this only refers to the device buffer size,
218  *              this module will then try to keep the lenght of audio
219  *              buffered within small constraints.
220  *
221  *  QUEUE_SIZE  The max number of blocks actually allowed in the device
222  *              driver's buffer, irrespective of the available number.
223  *              Overridden by the 'queuesize' parameter in usbradio.conf
224  *
225  *              Should be >=2, and at most as large as the hw queue above
226  *              (otherwise it will never be full).
227  */
228
229 #define FRAME_SIZE      160
230 #define QUEUE_SIZE      20
231
232 #if defined(__FreeBSD__)
233 #define FRAGS   0x8
234 #else
235 #define FRAGS   ( ( (6 * 5) << 16 ) | 0xc )
236 #endif
237
238 /*
239  * XXX text message sizes are probably 256 chars, but i am
240  * not sure if there is a suitable definition anywhere.
241  */
242 #define TEXT_SIZE       256
243
244 #if 0
245 #define TRYOPEN 1                               /* try to open on startup */
246 #endif
247 #define O_CLOSE 0x444                   /* special 'close' mode for device */
248 /* Which device to use */
249 #if defined( __OpenBSD__ ) || defined( __NetBSD__ )
250 #define DEV_DSP "/dev/audio"
251 #else
252 #define DEV_DSP "/dev/dsp"
253 #endif
254
255 #ifndef MIN
256 #define MIN(a,b) ((a) < (b) ? (a) : (b))
257 #endif
258 #ifndef MAX
259 #define MAX(a,b) ((a) > (b) ? (a) : (b))
260 #endif
261
262 static char *config = "usbradio.conf";  /* default config file */
263 static char *config1 = "usbradio_tune.conf";    /* tune config file */
264
265 static FILE *frxcapraw = NULL, *frxcaptrace = NULL, *frxoutraw = NULL;
266 static FILE *ftxcapraw = NULL, *ftxcaptrace = NULL, *ftxoutraw = NULL;
267
268 static int usbradio_debug;
269 #if 0 /* maw asdf sph */
270 static int usbradio_debug_level = 0;
271 #endif
272
273 enum {RX_AUDIO_NONE,RX_AUDIO_SPEAKER,RX_AUDIO_FLAT};
274 enum {CD_IGNORE,CD_XPMR_NOISE,CD_XPMR_VOX,CD_HID,CD_HID_INVERT};
275 enum {SD_IGNORE,SD_HID,SD_HID_INVERT,SD_XPMR};                                   /* no,external,externalinvert,software */
276 enum {RX_KEY_CARRIER,RX_KEY_CARRIER_CODE};
277 enum {TX_OUT_OFF,TX_OUT_VOICE,TX_OUT_LSD,TX_OUT_COMPOSITE,TX_OUT_AUX};
278 enum {TOC_NONE,TOC_PHASE,TOC_NOTONE};
279
280 /*      DECLARE STRUCTURES */
281
282 /*
283  * descriptor for one of our channels.
284  * There is one used for 'default' values (from the [general] entry in
285  * the configuration file), and then one instance for each device
286  * (the default is cloned from [general], others are only created
287  * if the relevant section exists).
288  */
289 struct chan_usbradio_pvt {
290         struct chan_usbradio_pvt *next;
291
292         char *name;
293
294         int total_blocks;           /* total blocks in the output device */
295         int sounddev;
296         enum { M_UNSET, M_FULL, M_READ, M_WRITE } duplex;
297         i16 cdMethod;
298         int autoanswer;
299         int autohangup;
300         int hookstate;
301         unsigned int queuesize;         /* max fragments in queue */
302         unsigned int frags;                     /* parameter for SETFRAGMENT */
303
304         int warned;                 /* various flags used for warnings */
305 #define WARN_used_blocks        1
306 #define WARN_speed              2
307 #define WARN_frag               4
308         int w_errors;               /* overfull in the write path */
309         struct timeval lastopen;
310
311         int overridecontext;
312         int mute;
313
314         /* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
315          * be representable in 16 bits to avoid overflows.
316          */
317 #define BOOST_SCALE     (1<<9)
318 #define BOOST_MAX       40          /* slightly less than 7 bits */
319         int boost;                  /* input boost, scaled by BOOST_SCALE */
320         char devicenum;
321         int spkrmax;
322         int micmax;
323
324         pthread_t sthread;
325         pthread_t hidthread;
326
327         int     stophid;
328         struct ast_channel *owner;
329         char    ext[AST_MAX_EXTENSION];
330         char    ctx[AST_MAX_CONTEXT];
331         char    language[MAX_LANGUAGE];
332         char    cid_name[256];          /* XXX */
333         char    cid_num[256];           /* XXX */
334         char    mohinterpret[MAX_MUSICCLASS];
335
336         /* buffers used in usbradio_write, 2 per int by 2 channels by 6 times oversampling (48KS/s) */
337         char    usbradio_write_buf[FRAME_SIZE * 2 * 2 * 6];
338         char    usbradio_write_buf_1[FRAME_SIZE * 2 * 2 * 6];
339
340         int     usbradio_write_dst;
341         /* buffers used in usbradio_read - AST_FRIENDLY_OFFSET space for headers
342          * plus enough room for a full frame
343          */
344         char    usbradio_read_buf[FRAME_SIZE * (2 * 12) + AST_FRIENDLY_OFFSET];
345         char    usbradio_read_buf_8k[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
346         int     readpos;         /* read position above */
347         struct ast_frame read_f; /* returned by usbradio_read */
348         
349
350         char    debuglevel;
351         char    radioduplex;
352
353         char    lastrx;
354         char    rxhidsq;
355         char    rxcarrierdetect; /*!< status from pmr channel */
356         char    rxctcssdecode;   /*!< status from pmr channel */
357
358         char    rxkeytype;
359         char    rxkeyed;         /*!< indicates rx signal present */
360
361         char    lasttx;
362         char    txkeyed;         /*! tx key request from upper layers  */
363         char    txchankey;
364         char    txtestkey;
365
366         time_t  lasthidtime;
367     struct ast_dsp *dsp;
368
369         t_pmr_chan *pmrChan;
370
371         char    rxcpusaver;
372         char    txcpusaver;
373
374         char    rxdemod;
375         float   rxgain;
376         char    rxcdtype;
377         char    rxsdtype;
378         int     rxsquelchadj;    /*!< this copy needs to be here for initialization */
379         char    txtoctype;
380
381         char    txprelim;
382         float   txctcssgain;
383         char    txmixa;
384         char    txmixb;
385
386         char    invertptt;
387
388         char    rxctcssrelax;
389         float   rxctcssgain;
390         float   rxctcssfreq;
391         float   txctcssfreq;
392
393         int     rxmixerset;
394         int     rxboostset;
395         float   rxvoiceadj;
396         float   rxctcssadj;
397         int     txmixaset;
398         int     txmixbset;
399         int     txctcssadj;
400
401         int     hdwtype;
402         int     hid_gpio_ctl;
403         int     hid_gpio_ctl_loc;
404         int     hid_io_cor;
405         int     hid_io_cor_loc;
406         int     hid_io_ctcss;
407         int     hid_io_ctcss_loc;
408         int     hid_io_ptt;
409         int     hid_gpio_loc;
410
411         struct {
412                 unsigned rxcapraw:1;
413                 unsigned txcapraw:1;
414                 unsigned txcap2:1;
415                 unsigned rxcap2:1;
416         } b;
417 };
418
419 /* maw add additional defaults !!! */
420 static struct chan_usbradio_pvt usbradio_default = {
421         .sounddev = -1,
422         .duplex = M_UNSET,                      /* XXX check this */
423         .autoanswer = 1,
424         .autohangup = 1,
425         .queuesize = QUEUE_SIZE,
426         .frags = FRAGS,
427         .ext = "s",
428         .ctx = "default",
429         .readpos = AST_FRIENDLY_OFFSET, /* start here on reads */
430         .lastopen = { 0, 0 },
431         .boost = BOOST_SCALE,
432 };
433
434 /*      DECLARE FUNCTION PROTOTYPES     */
435
436 static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s);
437 static int  hidhdwconfig(struct chan_usbradio_pvt *o);
438 static int  set_txctcss_level(struct chan_usbradio_pvt *o);
439 static void pmrdump(struct chan_usbradio_pvt *o);
440 static void mult_set(struct chan_usbradio_pvt *o);
441 static int  mult_calc(int value);
442 static void mixer_write(struct chan_usbradio_pvt *o);
443 static void tune_rxinput(struct chan_usbradio_pvt *o);
444 static void tune_rxvoice(struct chan_usbradio_pvt *o);
445 static void tune_rxctcss(struct chan_usbradio_pvt *o);
446 static void tune_txoutput(struct chan_usbradio_pvt *o, int value);
447 static void tune_write(struct chan_usbradio_pvt *o);
448
449 static char *usbradio_active;    /* the active device */
450
451 static int  setformat(struct chan_usbradio_pvt *o, int mode);
452
453 static struct ast_channel *usbradio_request(const char *type, int format, void *data
454 , int *cause);
455 static int usbradio_digit_begin(struct ast_channel *c, char digit);
456 static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration);
457 static int usbradio_text(struct ast_channel *c, const char *text);
458 static int usbradio_hangup(struct ast_channel *c);
459 static int usbradio_answer(struct ast_channel *c);
460 static struct ast_frame *usbradio_read(struct ast_channel *chan);
461 static int usbradio_call(struct ast_channel *c, char *dest, int timeout);
462 static int usbradio_write(struct ast_channel *chan, struct ast_frame *f);
463 static int usbradio_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
464 static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
465
466 #if     DEBUG_FILETEST == 1
467 static int RxTestIt(struct chan_usbradio_pvt *o);
468 #endif
469
470 static char tdesc[] = "USB (CM108) Radio Channel Driver";
471
472 static const struct ast_channel_tech usbradio_tech = {
473         .type = "Radio",
474         .description = tdesc,
475         .capabilities = AST_FORMAT_SLINEAR,
476         .requester = usbradio_request,
477         .send_digit_begin = usbradio_digit_begin,
478         .send_digit_end = usbradio_digit_end,
479         .send_text = usbradio_text,
480         .hangup = usbradio_hangup,
481         .answer = usbradio_answer,
482         .read = usbradio_read,
483         .call = usbradio_call,
484         .write = usbradio_write,
485         .indicate = usbradio_indicate,
486         .fixup = usbradio_fixup,
487 };
488
489 /* Call with:  devnum: alsa major device number, param: ascii Formal
490 Parameter Name, val1, first or only value, val2 second value, or 0 
491 if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
492
493 Note: must add -lasound to end of linkage */
494
495 static int amixer_max(int devnum,char *param)
496 {
497         int     rv,type;
498         char str[15];
499         snd_hctl_t *hctl;
500         snd_ctl_elem_id_t *id;
501         snd_hctl_elem_t *elem;
502         snd_ctl_elem_info_t *info;
503
504         snprintf(str, sizeof(str), "hw:%d", devnum);
505         if (snd_hctl_open(&hctl, str, 0))
506                 return -1;
507         snd_hctl_load(hctl);
508         id = alloca(snd_ctl_elem_id_sizeof());
509         memset(id, 0, snd_ctl_elem_id_sizeof());
510         snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
511         snd_ctl_elem_id_set_name(id, param);  
512         elem = snd_hctl_find_elem(hctl, id);
513         if (!elem) {
514                 snd_hctl_close(hctl);
515                 return -1;
516         }
517         info = alloca(snd_ctl_elem_info_sizeof());
518         memset(info, 0, snd_ctl_elem_info_sizeof());
519         snd_hctl_elem_info(elem,info);
520         type = snd_ctl_elem_info_get_type(info);
521         rv = 0;
522         switch (type) {
523         case SND_CTL_ELEM_TYPE_INTEGER:
524                 rv = snd_ctl_elem_info_get_max(info);
525                 break;
526         case SND_CTL_ELEM_TYPE_BOOLEAN:
527                 rv = 1;
528                 break;
529         }
530         snd_hctl_close(hctl);
531         return(rv);
532 }
533
534 /*! \brief Call with:  devnum: alsa major device number, param: ascii Formal
535 Parameter Name, val1, first or only value, val2 second value, or 0 
536 if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
537
538 Note: must add -lasound to end of linkage */
539
540 static int setamixer(int devnum, char *param, int v1, int v2)
541 {
542         int     type;
543         char str[15];
544         snd_hctl_t *hctl;
545         snd_ctl_elem_id_t *id;
546         snd_ctl_elem_value_t *control;
547         snd_hctl_elem_t *elem;
548         snd_ctl_elem_info_t *info;
549
550         snprintf(str, sizeof(str), "hw:%d", devnum);
551         if (snd_hctl_open(&hctl, str, 0))
552                 return -1;
553         snd_hctl_load(hctl);
554         id = alloca(snd_ctl_elem_id_sizeof());
555         memset(id, 0, snd_ctl_elem_id_sizeof());
556         snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
557         snd_ctl_elem_id_set_name(id, param);  
558         elem = snd_hctl_find_elem(hctl, id);
559         if (!elem) {
560                 snd_hctl_close(hctl);
561                 return -1;
562         }
563         info = alloca(snd_ctl_elem_info_sizeof());
564         memset(info, 0, snd_ctl_elem_info_sizeof());
565         snd_hctl_elem_info(elem,info);
566         type = snd_ctl_elem_info_get_type(info);
567         control = alloca(snd_ctl_elem_value_sizeof());
568         memset(control, 0, snd_ctl_elem_value_sizeof());
569         snd_ctl_elem_value_set_id(control, id);    
570         switch (type) {
571         case SND_CTL_ELEM_TYPE_INTEGER:
572                 snd_ctl_elem_value_set_integer(control, 0, v1);
573                 if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2);
574                 break;
575         case SND_CTL_ELEM_TYPE_BOOLEAN:
576                 snd_ctl_elem_value_set_integer(control, 0, (v1 != 0));
577                 break;
578         }
579         if (snd_hctl_elem_write(elem, control)) {
580                 snd_hctl_close(hctl);
581                 return(-1);
582         }
583         snd_hctl_close(hctl);
584         return 0;
585 }
586
587 static void hid_set_outputs(struct usb_dev_handle *handle,
588          unsigned char *outputs)
589 {
590         usb_control_msg(handle,
591                 USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
592                 HID_REPORT_SET,
593                 0 + (HID_RT_OUTPUT << 8),
594                 C108_HID_INTERFACE,
595                 (char *)outputs, 4, 5000);
596 }
597
598 static void hid_get_inputs(struct usb_dev_handle *handle,
599          unsigned char *inputs)
600 {
601         usb_control_msg(handle,
602                 USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
603                 HID_REPORT_GET,
604                 0 + (HID_RT_INPUT << 8),
605                 C108_HID_INTERFACE,
606                 (char *)inputs, 4, 5000);
607 }
608
609 static struct usb_device *hid_device_init(void)
610 {
611         struct usb_bus *usb_bus;
612         struct usb_device *dev;
613
614         usb_init();
615         usb_find_busses();
616         usb_find_devices();
617         for (usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next) {
618                 for (dev = usb_bus->devices; dev; dev = dev->next) {
619                         if ((dev->descriptor.idVendor == C108_VENDOR_ID) && (dev->descriptor.idProduct == C108_PRODUCT_ID))
620                                 return dev;
621                 }
622         }
623         return NULL;
624 }
625
626 static int hidhdwconfig(struct chan_usbradio_pvt *o)
627 {
628         if (o->hdwtype == 1) {         /*sphusb */
629                 o->hid_gpio_ctl     =  0x08; /* set GPIO4 to output mode */
630                 o->hid_gpio_ctl_loc =  2;    /* For CTL of GPIO */
631                 o->hid_io_cor       =  4;    /* GPIO3 is COR */
632                 o->hid_io_cor_loc   =  1;    /* GPIO3 is COR */
633                 o->hid_io_ctcss     =  2;    /* GPIO 2 is External CTCSS */
634                 o->hid_io_ctcss_loc =  1;    /* is GPIO 2 */
635                 o->hid_io_ptt       =  8;    /* GPIO 4 is PTT */
636                 o->hid_gpio_loc     =  1;    /* For ALL GPIO */
637         } else if (o->hdwtype == 0) {  /* dudeusb */
638                 o->hid_gpio_ctl     =  0x0c;/* set GPIO 3 & 4 to output mode */
639                 o->hid_gpio_ctl_loc =  2;    /* For CTL of GPIO */
640                 o->hid_io_cor       =  2;    /* VOLD DN is COR */
641                 o->hid_io_cor_loc   =  0;    /* VOL DN COR */
642                 o->hid_io_ctcss     =  2;    /* GPIO 2 is External CTCSS */
643                 o->hid_io_ctcss_loc =  1;    /* is GPIO 2 */
644                 o->hid_io_ptt       =  4;    /* GPIO 3 is PTT */
645                 o->hid_gpio_loc     =  1;    /* For ALL GPIO */
646         } else if (o->hdwtype == 3) {  /* custom version */
647                 o->hid_gpio_ctl     =  0x0c; /* set GPIO 3 & 4 to output mode */
648                 o->hid_gpio_ctl_loc =  2;    /* For CTL of GPIO */
649                 o->hid_io_cor       =  2;    /* VOLD DN is COR */
650                 o->hid_io_cor_loc   =  0;    /* VOL DN COR */
651                 o->hid_io_ctcss     =  2;    /* GPIO 2 is External CTCSS */
652                 o->hid_io_ctcss_loc =  1;    /* is GPIO 2 */
653                 o->hid_io_ptt       =  4;    /* GPIO 3 is PTT */
654                 o->hid_gpio_loc     =  1;    /* For ALL GPIO */
655         }
656
657         return 0;
658 }
659
660
661 static void *hidthread(void *arg)
662 {
663         unsigned char buf[4], keyed;
664         char lastrx, txtmp;
665         struct usb_device *usb_dev;
666         struct usb_dev_handle *usb_handle;
667         struct chan_usbradio_pvt *o = arg;
668
669         usb_dev = hid_device_init();
670         if (usb_dev == NULL) {
671                 ast_log(LOG_ERROR, "USB HID device not found\n");
672                 pthread_exit(NULL);
673         }
674         usb_handle = usb_open(usb_dev);
675         if (usb_handle == NULL) {
676                 ast_log(LOG_ERROR, "Not able to open USB device\n");
677                 pthread_exit(NULL);
678         }
679         if (usb_claim_interface(usb_handle, C108_HID_INTERFACE) < 0) {
680                 if (usb_detach_kernel_driver_np(usb_handle, C108_HID_INTERFACE) < 0) {
681                         ast_log(LOG_ERROR, "Not able to detach the USB device\n");
682                         pthread_exit(NULL);
683                 }
684                 if (usb_claim_interface(usb_handle, C108_HID_INTERFACE) < 0) {
685                         ast_log(LOG_ERROR, "Not able to claim the USB device\n");
686                         pthread_exit(NULL);
687                 }
688         }
689         memset(buf, 0, sizeof(buf));
690         buf[2] = o->hid_gpio_ctl;
691         buf[1] = 0;
692         hid_set_outputs(usb_handle, buf);
693         traceusb1("hidthread: Starting normally!!\n");
694         lastrx = 0;
695         while (!o->stophid) {
696                 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
697                 hid_get_inputs(usb_handle, buf);
698                 keyed = !(buf[o->hid_io_cor_loc] & o->hid_io_cor);
699                 if (keyed != o->rxhidsq) {
700                         if (o->debuglevel)
701                                 ast_log(LOG_NOTICE, "chan_usbradio() hidthread: update rxhidsq = %d\n", keyed);
702                         o->rxhidsq = keyed;              
703                 }
704
705                 /* if change in tx stuff */
706                 txtmp = 0;
707                 if (o->txkeyed || o->txchankey || o->txtestkey || o->pmrChan->txPttOut)
708                         txtmp = 1;
709                 
710                 if (o->lasttx != txtmp) {
711                         o->lasttx = txtmp;
712                         if (o->debuglevel)
713                                 ast_log(LOG_NOTICE, "hidthread: tx set to %d\n", txtmp);
714                         buf[o->hid_gpio_loc] = 0;
715                         if (txtmp)
716                                 buf[o->hid_gpio_loc] = o->hid_io_ptt;
717                         buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
718                         hid_set_outputs(usb_handle, buf);
719                 }
720
721                 time(&o->lasthidtime);
722                 usleep(50000);
723         }
724         buf[o->hid_gpio_loc] = 0;
725         if (o->invertptt)
726                 buf[o->hid_gpio_loc] = o->hid_io_ptt;
727         buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
728         hid_set_outputs(usb_handle, buf);
729         pthread_exit(0);
730 }
731
732 /*! \brief
733  * returns a pointer to the descriptor with the given name
734  */
735 static struct chan_usbradio_pvt *find_desc(char *dev)
736 {
737         struct chan_usbradio_pvt *o = NULL;
738
739         if (!dev)
740                 ast_log(LOG_WARNING, "null dev\n");
741
742         for (o = usbradio_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
743
744         if (!o)
745                 ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
746
747         return o;
748 }
749
750 /*! \brief
751  * split a string in extension-context, returns pointers to malloc'ed
752  * strings.
753  * If we do not have 'overridecontext' then the last @ is considered as
754  * a context separator, and the context is overridden.
755  * This is usually not very necessary as you can play with the dialplan,
756  * and it is nice not to need it because you have '@' in SIP addresses.
757  * Return value is the buffer address.
758  */
759 #if     0
760 static char *ast_ext_ctx(const char *src, char **ext, char **ctx)
761 {
762         struct chan_usbradio_pvt *o = find_desc(usbradio_active);
763
764         if (ext == NULL || ctx == NULL)
765                 return NULL;                    /* error */
766
767         *ext = *ctx = NULL;
768
769         if (src && *src != '\0')
770                 *ext = ast_strdup(src);
771
772         if (*ext == NULL)
773                 return NULL;
774
775         if (!o->overridecontext) {
776                 /* parse from the right */
777                 *ctx = strrchr(*ext, '@');
778                 if (*ctx)
779                         *(*ctx)++ = '\0';
780         }
781
782         return *ext;
783 }
784 #endif
785
786 /*! \brief
787  * Returns the number of blocks used in the audio output channel
788  */
789 static int used_blocks(struct chan_usbradio_pvt *o)
790 {
791         struct audio_buf_info info;
792
793         if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
794                 if (!(o->warned & WARN_used_blocks)) {
795                         ast_log(LOG_WARNING, "Error reading output space\n");
796                         o->warned |= WARN_used_blocks;
797                 }
798                 return 1;
799         }
800
801         if (o->total_blocks == 0) {
802                 ast_debug(4, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
803                 o->total_blocks = info.fragments;
804         }
805
806         return o->total_blocks - info.fragments;
807 }
808
809 /*! \brief Write an exactly FRAME_SIZE sized frame */
810 static int soundcard_writeframe(struct chan_usbradio_pvt *o, short *data)
811 {
812         int res;
813
814         if (o->sounddev < 0)
815                 setformat(o, O_RDWR);
816         if (o->sounddev < 0)
817                 return 0;                               /* not fatal */
818         /*
819          * Nothing complex to manage the audio device queue.
820          * If the buffer is full just drop the extra, otherwise write.
821          * XXX in some cases it might be useful to write anyways after
822          * a number of failures, to restart the output chain.
823          */
824         res = used_blocks(o);
825         if (res > o->queuesize) {       /* no room to write a block */
826                 if (o->w_errors++ == 0 && (usbradio_debug & 0x4))
827                         ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
828                 return 0;
829         }
830         o->w_errors = 0;
831
832         return write(o->sounddev, ((void *) data), FRAME_SIZE * 2 * 12);
833 }
834
835 /*
836  * reset and close the device if opened,
837  * then open and initialize it in the desired mode,
838  * trigger reads and writes so we can start using it.
839  */
840 static int setformat(struct chan_usbradio_pvt *o, int mode)
841 {
842         int fmt, desired, res, fd;
843         char device[20];
844
845         if (o->sounddev >= 0) {
846                 ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
847                 close(o->sounddev);
848                 o->duplex = M_UNSET;
849                 o->sounddev = -1;
850         }
851         if (mode == O_CLOSE)            /* we are done */
852                 return 0;
853         if (ast_tvdiff_ms(ast_tvnow(), o->lastopen) < 1000)
854                 return -1;                              /* don't open too often */
855         o->lastopen = ast_tvnow();
856         strcpy(device, "/dev/dsp");
857         if (o->devicenum)
858                 snprintf(device + strlen("/dev/dsp"), sizeof(device) - strlen("/dev/dsp"), "%d", o->devicenum);
859         fd = o->sounddev = open(device, mode | O_NONBLOCK);
860         if (fd < 0) {
861                 ast_log(LOG_WARNING, "Unable to re-open DSP device %d: %s\n", o->devicenum, strerror(errno));
862                 return -1;
863         }
864         if (o->owner)
865                 o->owner->fds[0] = fd;
866
867 #if __BYTE_ORDER == __LITTLE_ENDIAN
868         fmt = AFMT_S16_LE;
869 #else
870         fmt = AFMT_S16_BE;
871 #endif
872         res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
873         if (res < 0) {
874                 ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
875                 return -1;
876         }
877         switch (mode) {
878                 case O_RDWR:
879                         res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
880                         /* Check to see if duplex set (FreeBSD Bug) */
881                         res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
882                         if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
883                                 ast_verb(2, "Console is full duplex\n");
884                                 o->duplex = M_FULL;
885                         };
886                         break;
887                 case O_WRONLY:
888                         o->duplex = M_WRITE;
889                         break;
890                 case O_RDONLY:
891                         o->duplex = M_READ;
892                         break;
893         }
894
895         fmt = 1;
896         res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
897         if (res < 0) {
898                 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
899                 return -1;
900         }
901         fmt = desired = 48000;                                                  /* 8000 Hz desired */
902         res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
903
904         if (res < 0) {
905                 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
906                 return -1;
907         }
908         if (fmt != desired) {
909                 if (!(o->warned & WARN_speed)) {
910                         ast_log(LOG_WARNING,
911                             "Requested %d Hz, got %d Hz -- sound may be choppy\n",
912                             desired, fmt);
913                         o->warned |= WARN_speed;
914                 }
915         }
916         /*
917          * on Freebsd, SETFRAGMENT does not work very well on some cards.
918          * Default to use 256 bytes, let the user override
919          */
920         if (o->frags) {
921                 fmt = o->frags;
922                 res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
923                 if (res < 0) {
924                         if (!(o->warned & WARN_frag)) {
925                                 ast_log(LOG_WARNING,
926                                         "Unable to set fragment size -- sound may be choppy\n");
927                                 o->warned |= WARN_frag;
928                         }
929                 }
930         }
931         /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
932         res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
933         res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
934         /* it may fail if we are in half duplex, never mind */
935         return 0;
936 }
937
938 /*
939  * some of the standard methods supported by channels.
940  */
941 static int usbradio_digit_begin(struct ast_channel *c, char digit)
942 {
943         return 0;
944 }
945
946 static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration)
947 {
948         /* no better use for received digits than print them */
949         ast_verb(0, " << Console Received digit %c of duration %u ms >> \n", 
950                 digit, duration);
951         return 0;
952 }
953
954 static int usbradio_text(struct ast_channel *c, const char *text)
955 {
956         /* print received messages */
957         ast_verb(0, " << Console Received text %s >> \n", text);
958         return 0;
959 }
960
961 /*
962  * handler for incoming calls. Either autoanswer, or start ringing
963  */
964 static int usbradio_call(struct ast_channel *c, char *dest, int timeout)
965 {
966         struct chan_usbradio_pvt *o = c->tech_pvt;
967
968         time(&o->lasthidtime);
969         ast_pthread_create_background(&o->hidthread, NULL, hidthread, o);
970         ast_setstate(c, AST_STATE_UP);
971         return 0;
972 }
973
974 /*
975  * remote side answered the phone
976  */
977 static int usbradio_answer(struct ast_channel *c)
978 {
979         ast_setstate(c, AST_STATE_UP);
980
981         return 0;
982 }
983
984 static int usbradio_hangup(struct ast_channel *c)
985 {
986         struct chan_usbradio_pvt *o = c->tech_pvt;
987
988         c->tech_pvt = NULL;
989         o->owner = NULL;
990         ast_module_unref(ast_module_info->self);
991         if (o->hookstate) {
992                 if (o->autoanswer || o->autohangup) {
993                         /* Assume auto-hangup too */
994                         o->hookstate = 0;
995                         setformat(o, O_CLOSE);
996                 }
997         }
998         o->stophid = 1;
999         pthread_join(o->hidthread, NULL);
1000         return 0;
1001 }
1002
1003
1004 /* used for data coming from the network */
1005 static int usbradio_write(struct ast_channel *c, struct ast_frame *f)
1006 {
1007         int src,datalen;
1008         struct chan_usbradio_pvt *o = c->tech_pvt;
1009
1010         traceusb2("usbradio_write() o->nosound=%d\n", o->nosound);      /*sph maw asdf */
1011
1012         /*
1013          * we could receive a block which is not a multiple of our
1014          * FRAME_SIZE, so buffer it locally and write to the device
1015          * in FRAME_SIZE chunks.
1016          * Keep the residue stored for future use.
1017          */
1018
1019         if (o->txkeyed || o->txtestkey)
1020                 o->pmrChan->txPttIn = 1;
1021         else
1022                 o->pmrChan->txPttIn = 0;
1023
1024         #if DEBUG_CAPTURES == 1 /* to write input data to a file   datalen=320 */
1025         if (ftxcapraw && o->b.txcapraw) {
1026                 i16 i, tbuff[f->datalen];
1027                 for (i = 0; i < f->datalen; i += 2) {
1028                         tbuff[i] = ((i16 *)(f->data))[i / 2];
1029                         tbuff[i + 1] = o->txkeyed * M_Q13;
1030                 }
1031                 fwrite(tbuff, 2, f->datalen, ftxcapraw);
1032                 /*fwrite(f->data,1,f->datalen,ftxcapraw); */
1033         }
1034         #endif
1035
1036         PmrTx(o->pmrChan,(i16*)f->data,(i16*)o->usbradio_write_buf_1);
1037
1038         #if 0   /* to write 48KS/s stereo data to a file */
1039         if (!ftxoutraw) ftxoutraw = fopen(TX_CAP_OUT_FILE,"w");
1040         if (ftxoutraw) fwrite(o->usbradio_write_buf_1,1,f->datalen * 2 * 6,ftxoutraw);
1041         #endif
1042
1043         #if DEBUG_CAPTURES == 1
1044     if (o->b.txcap2 && ftxcaptrace)
1045                 fwrite((o->pmrChan->ptxDebug), 1, FRAME_SIZE * 2 * 16, ftxcaptrace);
1046         #endif
1047
1048         src = 0;                                        /* read position into f->data */
1049         datalen = f->datalen * 12;
1050         while (src < datalen) {
1051                 /* Compute spare room in the buffer */
1052                 int l = sizeof(o->usbradio_write_buf) - o->usbradio_write_dst;
1053
1054                 if (datalen - src >= l) {       /* enough to fill a frame */
1055                         memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
1056                         soundcard_writeframe(o, (short *) o->usbradio_write_buf);
1057                         src += l;
1058                         o->usbradio_write_dst = 0;
1059                 } else {                                /* copy residue */
1060                         l = datalen - src;
1061                         memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
1062                         src += l;                       /* but really, we are done */
1063                         o->usbradio_write_dst += l;
1064                 }
1065         }
1066         return 0;
1067 }
1068
1069 static struct ast_frame *usbradio_read(struct ast_channel *c)
1070 {
1071         int res;
1072         struct chan_usbradio_pvt *o = c->tech_pvt;
1073         struct ast_frame *f = &o->read_f, *f1;
1074         struct ast_frame wf = { AST_FRAME_CONTROL };
1075         time_t now;
1076
1077         traceusb2("usbradio_read()\n"); /* sph maw asdf */
1078
1079         if (o->lasthidtime) {
1080                 time(&now);
1081                 if ((now - o->lasthidtime) > 3) {
1082                         ast_log(LOG_ERROR, "HID process has died or something!!\n");
1083                         return NULL;
1084                 }
1085         }
1086         if (o->lastrx && (!o->rxkeyed)) {
1087                 o->lastrx = 0;
1088                 wf.subclass = AST_CONTROL_RADIO_UNKEY;
1089                 ast_queue_frame(o->owner, &wf);
1090         } else if ((!o->lastrx) && (o->rxkeyed)) {
1091                 o->lastrx = 1;
1092                 wf.subclass = AST_CONTROL_RADIO_KEY;
1093                 ast_queue_frame(o->owner, &wf);
1094         }
1095         /* XXX can be simplified returning &ast_null_frame */
1096         /* prepare a NULL frame in case we don't have enough data to return */
1097         memset(f, 0, sizeof(struct ast_frame));
1098         f->frametype = AST_FRAME_NULL;
1099         f->src = usbradio_tech.type;
1100
1101         res = read(o->sounddev, o->usbradio_read_buf + o->readpos, 
1102                 sizeof(o->usbradio_read_buf) - o->readpos);
1103         if (res < 0)                            /* audio data not ready, return a NULL frame */
1104                 return f;
1105
1106         o->readpos += res;
1107         if (o->readpos < sizeof(o->usbradio_read_buf))  /* not enough samples */
1108                 return f;
1109
1110         if (o->mute)
1111                 return f;
1112
1113         #if DEBUG_CAPTURES == 1
1114         if (o->b.rxcapraw && frxcapraw)
1115                 fwrite((o->usbradio_read_buf + AST_FRIENDLY_OFFSET), 1, FRAME_SIZE * 2 * 2 * 6, frxcapraw);
1116         #endif
1117
1118         #if 1
1119         PmrRx(         o->pmrChan,
1120                    (i16 *)(o->usbradio_read_buf + AST_FRIENDLY_OFFSET),
1121                    (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
1122
1123         #else
1124         static FILE *hInput;
1125         i16 iBuff[FRAME_SIZE * 2 * 6];
1126
1127         o->pmrChan->b.rxCapture = 1;
1128
1129         if(!hInput) {
1130                 hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm", "r");
1131                 if(!hInput) {
1132                         ast_log(LOG_ERROR, " Input Data File Not Found.\n");
1133                         return 0;
1134                 }
1135         }
1136
1137         if (0 == fread((void *)iBuff, 2, FRAME_SIZE * 2 * 6, hInput))
1138                 exit;
1139
1140         PmrRx(         o->pmrChan, 
1141                    (i16 *)iBuff,
1142                    (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
1143
1144         #endif
1145
1146         #if 0
1147         if (!frxoutraw) frxoutraw = fopen(RX_CAP_OUT_FILE, "w");
1148     if (frxoutraw) fwrite((o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET), 1, FRAME_SIZE * 2, frxoutraw);
1149         #endif
1150
1151         #if DEBUG_CAPTURES == 1
1152     if (frxcaptrace && o->b.rxcap2) fwrite((o->pmrChan->prxDebug), 1, FRAME_SIZE * 2 * 16, frxcaptrace);
1153         #endif
1154
1155         if (o->rxcdtype == CD_HID && (o->pmrChan->rxExtCarrierDetect != o->rxhidsq))
1156                 o->pmrChan->rxExtCarrierDetect = o->rxhidsq;
1157         if (o->rxcdtype == CD_HID_INVERT && (o->pmrChan->rxExtCarrierDetect == o->rxhidsq))
1158                 o->pmrChan->rxExtCarrierDetect = !o->rxhidsq;
1159                 
1160         if ( (o->rxcdtype == CD_HID && o->rxhidsq) ||
1161                  (o->rxcdtype == CD_HID_INVERT && !o->rxhidsq) ||
1162                  (o->rxcdtype == CD_XPMR_NOISE && o->pmrChan->rxCarrierDetect) ||
1163                  (o->rxcdtype == CD_XPMR_VOX && o->pmrChan->rxCarrierDetect) )
1164                 res = 1;
1165         else
1166                 res = 0;
1167
1168         if (res != o->rxcarrierdetect) {
1169                 o->rxcarrierdetect = res;
1170                 if (o->debuglevel)
1171                         ast_debug(4, "rxcarrierdetect = %d\n", res);
1172         }
1173
1174         if (o->pmrChan->rxCtcss->decode != o->rxctcssdecode) {
1175                 if (o->debuglevel)
1176                         ast_debug(4, "rxctcssdecode = %d\n", o->pmrChan->rxCtcss->decode);
1177                 o->rxctcssdecode = o->pmrChan->rxCtcss->decode;
1178         }
1179
1180         if ( (  o->rxctcssfreq && (o->rxctcssdecode == o->pmrChan->rxCtcssIndex)) || 
1181                  ( !o->rxctcssfreq && o->rxcarrierdetect) ) 
1182                 o->rxkeyed = 1;
1183         else
1184                 o->rxkeyed = 0;
1185
1186
1187         o->readpos = AST_FRIENDLY_OFFSET;       /* reset read pointer for next frame */
1188         if (c->_state != AST_STATE_UP)  /* drop data if frame is not up */
1189                 return f;
1190         /* ok we can build and deliver the frame to the caller */
1191         f->frametype = AST_FRAME_VOICE;
1192         f->subclass = AST_FORMAT_SLINEAR;
1193         f->samples = FRAME_SIZE;
1194         f->datalen = FRAME_SIZE * 2;
1195         f->data = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
1196         if (o->boost != BOOST_SCALE) {  /* scale and clip values */
1197                 int i, x;
1198                 int16_t *p = (int16_t *) f->data;
1199                 for (i = 0; i < f->samples; i++) {
1200                         x = (p[i] * o->boost) / BOOST_SCALE;
1201                         if (x > 32767)
1202                                 x = 32767;
1203                         else if (x < -32768)
1204                                 x = -32768;
1205                         p[i] = x;
1206                 }
1207         }
1208
1209         f->offset = AST_FRIENDLY_OFFSET;
1210         if (o->dsp) {
1211                 f1 = ast_dsp_process(c, o->dsp, f);
1212                 if ((f1->frametype == AST_FRAME_DTMF_END) || (f1->frametype == AST_FRAME_DTMF_BEGIN)) {
1213                         if (f1->frametype == AST_FRAME_DTMF_END)
1214                             ast_log(LOG_NOTICE,"Got DTMF char %c\n",f1->subclass);
1215                         return f1;
1216                 }
1217         }
1218         return f;
1219 }
1220
1221 static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1222 {
1223         struct chan_usbradio_pvt *o = newchan->tech_pvt;
1224         ast_log(LOG_WARNING,"usbradio_fixup()\n");
1225         o->owner = newchan;
1226         return 0;
1227 }
1228
1229 static int usbradio_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
1230 {
1231         struct chan_usbradio_pvt *o = c->tech_pvt;
1232         int res = 0;
1233
1234         switch (cond) {
1235         case AST_CONTROL_BUSY:
1236         case AST_CONTROL_CONGESTION:
1237         case AST_CONTROL_RINGING:
1238         case -1:
1239                 res = -1;
1240                 break;
1241         case AST_CONTROL_PROGRESS:
1242         case AST_CONTROL_PROCEEDING:
1243         case AST_CONTROL_VIDUPDATE:
1244                 break;
1245         case AST_CONTROL_HOLD:
1246                 ast_verb(0, " << Console Has Been Placed on Hold >> \n");
1247                 ast_moh_start(c, data, o->mohinterpret);
1248                 break;
1249         case AST_CONTROL_UNHOLD:
1250                 ast_verb(0, " << Console Has Been Retrieved from Hold >> \n");
1251                 ast_moh_stop(c);
1252                 break;
1253         case AST_CONTROL_RADIO_KEY:
1254                 o->txkeyed = 1;
1255                 if (o->debuglevel)
1256                         ast_verb(0, " << Radio Transmit On. >> \n");
1257                 break;
1258         case AST_CONTROL_RADIO_UNKEY:
1259                 o->txkeyed = 0;
1260                 if (o->debuglevel)
1261                         ast_verb(0, " << Radio Transmit Off. >> \n");
1262                 break;
1263         default:
1264                 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
1265                 return -1;
1266         }
1267
1268         return res;
1269 }
1270
1271 /*
1272  * allocate a new channel.
1273  */
1274 static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state)
1275 {
1276         struct ast_channel *c;
1277         char device[15] = "dsp";
1278
1279         if (o->devicenum)
1280                 snprintf(device + 3, sizeof(device) - 3, "%d", o->devicenum);
1281         c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "usbRadio/%s", device);
1282         if (c == NULL)
1283                 return NULL;
1284         c->tech = &usbradio_tech;
1285         if (o->sounddev < 0)
1286                 setformat(o, O_RDWR);
1287         c->fds[0] = o->sounddev;        /* -1 if device closed, override later */
1288         c->nativeformats = AST_FORMAT_SLINEAR;
1289         c->readformat = AST_FORMAT_SLINEAR;
1290         c->writeformat = AST_FORMAT_SLINEAR;
1291         c->tech_pvt = o;
1292
1293         if (!ast_strlen_zero(o->language))
1294                 ast_string_field_set(c, language, o->language);
1295         /* Don't use ast_set_callerid() here because it will
1296          * generate a needless NewCallerID event */
1297         c->cid.cid_num = ast_strdup(o->cid_num);
1298         c->cid.cid_ani = ast_strdup(o->cid_num);
1299         c->cid.cid_name = ast_strdup(o->cid_name);
1300         if (!ast_strlen_zero(ext))
1301                 c->cid.cid_dnid = ast_strdup(ext);
1302
1303         o->owner = c;
1304         ast_module_ref(ast_module_info->self);
1305         ast_jb_configure(c, &global_jbconf);
1306         if (state != AST_STATE_DOWN) {
1307                 if (ast_pbx_start(c)) {
1308                         ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
1309                         ast_hangup(c);
1310                         o->owner = c = NULL;
1311                         /* XXX what about the channel itself ? */
1312                         /* XXX what about usecnt ? */
1313                 }
1314         }
1315
1316         return c;
1317 }
1318
1319 static struct ast_channel *usbradio_request(const char *type, int format, void *data, int *cause)
1320 {
1321         struct ast_channel *c;
1322         struct chan_usbradio_pvt *o = find_desc(data);
1323
1324         ast_debug(4, "usbradio_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data);
1325         if (o == NULL) {
1326                 ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
1327                 /* XXX we could default to 'dsp' perhaps ? */
1328                 return NULL;
1329         }
1330         if ((format & AST_FORMAT_SLINEAR) == 0) {
1331                 ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
1332                 return NULL;
1333         }
1334         if (o->owner) {
1335                 ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
1336                 *cause = AST_CAUSE_BUSY;
1337                 return NULL;
1338         }
1339         c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
1340         if (c == NULL) {
1341                 ast_log(LOG_WARNING, "Unable to create new usb channel\n");
1342                 return NULL;
1343         }
1344         return c;
1345 }
1346
1347 static char *handle_cli_radio_key(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1348 {
1349         struct chan_usbradio_pvt *o = NULL;
1350
1351         switch (cmd) {
1352         case CLI_INIT:
1353                 e->command = "radio key";
1354                 e->usage =
1355                         "Usage: radio key\n"
1356                         "       Simulates COR active.\n";
1357                 return NULL;
1358         case CLI_GENERATE:
1359                 return NULL;
1360         }
1361
1362         if (a->argc != 2)
1363                 return CLI_SHOWUSAGE;
1364
1365         o = find_desc(usbradio_active);
1366         o->txtestkey = 1;
1367
1368         return CLI_SUCCESS;
1369 }
1370
1371 static char *handle_cli_radio_unkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1372 {
1373         struct chan_usbradio_pvt *o = NULL;
1374
1375         switch (cmd) {
1376         case CLI_INIT:
1377                 e->command = "radio unkey";
1378                 e->usage =
1379                         "Usage: radio unkey\n"
1380                         "       Simulates COR un-active.\n";
1381                 return NULL;
1382         case CLI_GENERATE:
1383                 return NULL;
1384         }
1385
1386         if (a->argc != 2)
1387                 return CLI_SHOWUSAGE;
1388
1389         o = find_desc(usbradio_active);
1390         o->txtestkey = 0;
1391
1392         return CLI_SUCCESS;
1393 }
1394
1395 static char *handle_cli_radio_tune(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1396 {
1397         struct chan_usbradio_pvt *o = NULL;
1398         int i = 0;
1399
1400         switch (cmd) {
1401         case CLI_INIT:
1402                 e->command = "radio tune [rxnoise|rxvoice|rxtone|rxsquelch|rxcap|rxtracecap|"
1403                         "txvoice|txtone|txcap|txtracecap|auxvoice|nocap|dump|save]";
1404                 /* radio tune 6 3000        measured tx value */
1405                 e->usage =
1406                         "Usage: radio tune <function>\n"
1407                         "       rxnoise\n"
1408                         "       rxvoice\n"
1409                         "       rxtone\n"
1410                         "       rxsquelch [newsetting]\n"
1411                         "       rxcap\n"
1412                         "       rxtracecap\n"
1413                         "       txvoice [newsetting]\n"
1414                         "       txtone [newsetting]\n"
1415                         "       txcap\n"
1416                         "       txtracecap\n"
1417                         "       auxvoice [newsetting]\n"
1418                         "       nocap\n"
1419                         "       dump\n"
1420                         "       save (settings to tuning file)\n"
1421                         "\n"
1422                         "       All [newsetting]s are values 0-999\n";
1423                 return NULL;
1424         case CLI_GENERATE:
1425                 return NULL;
1426         }
1427
1428         if ((a->argc < 2) || (a->argc > 4))
1429                 return CLI_SHOWUSAGE; 
1430
1431         if (a->argc == 2) { /* just show stuff */
1432                 ast_cli(a->fd, "Output A is currently set to %s.\n",
1433                         o->txmixa == TX_OUT_COMPOSITE ? "composite" :
1434                         o->txmixa == TX_OUT_VOICE ? "voice" :
1435                         o->txmixa == TX_OUT_LSD ? "tone" :
1436                         o->txmixa == TX_OUT_AUX ? "auxvoice" :
1437                         "off");
1438
1439                 ast_cli(a->fd, "Output B is currently set to %s.\n",
1440                         o->txmixb == TX_OUT_COMPOSITE ? "composite" :
1441                         o->txmixb == TX_OUT_VOICE ? "voice" :
1442                         o->txmixb == TX_OUT_LSD ? "tone" :
1443                         o->txmixb == TX_OUT_AUX ? "auxvoice" :
1444                         "off");
1445
1446                 ast_cli(a->fd, "Tx Voice Level currently set to %d\n", o->txmixaset);
1447                 ast_cli(a->fd, "Tx Tone Level currently set to %d\n", o->txctcssadj);
1448                 ast_cli(a->fd, "Rx Squelch currently set to %d\n", o->rxsquelchadj);
1449                 return CLI_SHOWUSAGE;
1450         }
1451
1452         o = find_desc(usbradio_active);
1453
1454         if (!strcasecmp(a->argv[2], "rxnoise"))
1455                 tune_rxinput(o);
1456         else if (!strcasecmp(a->argv[2], "rxvoice"))
1457                 tune_rxvoice(o);
1458         else if (!strcasecmp(a->argv[2], "rxtone"))
1459                 tune_rxctcss(o);
1460         else if (!strcasecmp(a->argv[2], "rxsquelch")) {
1461                 if (a->argc == 3) {
1462                     ast_cli(a->fd, "Current Signal Strength is %d\n", ((32767 - o->pmrChan->rxRssi) * 1000 / 32767));
1463                     ast_cli(a->fd, "Current Squelch setting is %d\n", o->rxsquelchadj);
1464 #if 0
1465                         ast_cli(a->fd,"Current Raw RSSI        is %d\n",o->pmrChan->rxRssi);
1466                     ast_cli(a->fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
1467 #endif
1468                 } else {
1469                         i = atoi(a->argv[3]);
1470                         if ((i < 0) || (i > 999))
1471                                 return CLI_SHOWUSAGE;
1472                         ast_cli(a->fd, "Changed Squelch setting to %d\n", i);
1473                         o->rxsquelchadj = i;
1474                         *(o->pmrChan->prxSquelchAdjust) = ((999 - i) * 32767) / 1000;
1475                 }
1476         } else if (!strcasecmp(a->argv[2], "txvoice")) {
1477                 i = 0;
1478
1479                 if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
1480                         (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE)) {
1481                         ast_log(LOG_ERROR, "No txvoice output configured.\n");
1482                 } else if (a->argc == 3) {
1483                         if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE))
1484                                 ast_cli(a->fd, "Current txvoice setting on Channel A is %d\n", o->txmixaset);
1485                         else
1486                                 ast_cli(a->fd, "Current txvoice setting on Channel B is %d\n", o->txmixbset);
1487                 } else {
1488                         i = atoi(a->argv[3]);
1489                         if ((i < 0) || (i > 999))
1490                                 return CLI_SHOWUSAGE;
1491
1492                         if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE)) {
1493                                 o->txmixaset = i;
1494                                 ast_cli(a->fd, "Changed txvoice setting on Channel A to %d\n", o->txmixaset);
1495                         } else {
1496                                 o->txmixbset = i;   
1497                                 ast_cli(a->fd, "Changed txvoice setting on Channel B to %d\n", o->txmixbset);
1498                         }
1499                         mixer_write(o);
1500                         mult_set(o);
1501                         ast_cli(a->fd, "Changed Tx Voice Output setting to %d\n", i);
1502                 }
1503                 tune_txoutput(o,i);
1504         } else if (!strcasecmp(a->argv[2], "auxvoice")) {
1505                 i = 0;
1506                 if ( (o->txmixa != TX_OUT_AUX) && (o->txmixb != TX_OUT_AUX))
1507                         ast_log(LOG_WARNING, "No auxvoice output configured.\n");
1508                 else if (a->argc == 3) {
1509                         if (o->txmixa == TX_OUT_AUX)
1510                                 ast_cli(a->fd, "Current auxvoice setting on Channel A is %d\n", o->txmixaset);
1511                         else
1512                                 ast_cli(a->fd, "Current auxvoice setting on Channel B is %d\n", o->txmixbset);
1513                 } else {
1514                         i = atoi(a->argv[3]);
1515                         if ((i < 0) || (i > 999))
1516                                 return CLI_SHOWUSAGE;
1517                         if (o->txmixa == TX_OUT_AUX) {
1518                                 o->txmixbset = i;
1519                                 ast_cli(a->fd, "Changed auxvoice setting on Channel A to %d\n", o->txmixaset);
1520                         } else {
1521                                 o->txmixbset = i;
1522                                 ast_cli(a->fd, "Changed auxvoice setting on Channel B to %d\n", o->txmixbset);
1523                         }
1524                         mixer_write(o);
1525                         mult_set(o);
1526                 }
1527                 /* tune_auxoutput(o,i); */
1528         } else if (!strcasecmp(a->argv[2], "txtone")) {
1529                 if (a->argc == 3)
1530                         ast_cli(a->fd, "Current Tx CTCSS modulation setting = %d\n", o->txctcssadj);
1531                 else {
1532                         i = atoi(a->argv[3]);
1533                         if ((i < 0) || (i > 999))
1534                                 return CLI_SHOWUSAGE;
1535                         o->txctcssadj = i;
1536                         set_txctcss_level(o);
1537                         ast_cli(a->fd, "Changed Tx CTCSS modulation setting to %i\n", i);
1538                 }
1539                 o->txtestkey = 1;
1540                 usleep(5000000);
1541                 o->txtestkey = 0;
1542         } else if (!strcasecmp(a->argv[2],"dump"))
1543                 pmrdump(o);
1544         else if (!strcasecmp(a->argv[2],"nocap")) {
1545                 ast_cli(a->fd, "File capture (trace) was rx=%d tx=%d and now off.\n", o->b.rxcap2, o->b.txcap2);
1546                 ast_cli(a->fd, "File capture (raw)   was rx=%d tx=%d and now off.\n", o->b.rxcapraw, o->b.txcapraw);
1547                 o->b.rxcapraw = o->b.txcapraw = o->b.rxcap2 = o->b.txcap2 = o->pmrChan->b.rxCapture = o->pmrChan->b.txCapture = 0;
1548                 if (frxcapraw) {
1549                         fclose(frxcapraw);
1550                         frxcapraw = NULL;
1551                 }
1552                 if (frxcaptrace) {
1553                         fclose(frxcaptrace);
1554                         frxcaptrace = NULL;
1555                 }
1556                 if (frxoutraw) {
1557                         fclose(frxoutraw);
1558                         frxoutraw = NULL;
1559                 }
1560                 if (ftxcapraw) {
1561                         fclose(ftxcapraw);
1562                         ftxcapraw = NULL;
1563                 }
1564                 if (ftxcaptrace) {
1565                         fclose(ftxcaptrace);
1566                         ftxcaptrace = NULL;
1567                 }
1568                 if (ftxoutraw) {
1569                         fclose(ftxoutraw);
1570                         ftxoutraw = NULL;
1571                 }
1572         } else if (!strcasecmp(a->argv[2], "rxtracecap")) {
1573                 if (!frxcaptrace)
1574                         frxcaptrace = fopen(RX_CAP_TRACE_FILE, "w");
1575                 ast_cli(a->fd, "Trace rx on.\n");
1576                 o->b.rxcap2 = o->pmrChan->b.rxCapture = 1;
1577         } else if (!strcasecmp(a->argv[2], "txtracecap")) {
1578                 if (!ftxcaptrace)
1579                         ftxcaptrace = fopen(TX_CAP_TRACE_FILE, "w");
1580                 ast_cli(a->fd, "Trace tx on.\n");
1581                 o->b.txcap2 = o->pmrChan->b.txCapture = 1;
1582         } else if (!strcasecmp(a->argv[2], "rxcap")) {
1583                 if (!frxcapraw)
1584                         frxcapraw = fopen(RX_CAP_RAW_FILE, "w");
1585                 ast_cli(a->fd, "cap rx raw on.\n");
1586                 o->b.rxcapraw = 1;
1587         } else if (!strcasecmp(a->argv[2], "txcap")) {
1588                 if (!ftxcapraw)
1589                         ftxcapraw = fopen(TX_CAP_RAW_FILE, "w");
1590                 ast_cli(a->fd, "cap tx raw on.\n");
1591                 o->b.txcapraw = 1;
1592         } else if (!strcasecmp(a->argv[2], "save")) {
1593                 tune_write(o);
1594                 ast_cli(a->fd, "Saved radio tuning settings to usbradio_tune.conf\n");
1595         } else
1596                 return CLI_SHOWUSAGE;
1597         return CLI_SUCCESS;
1598 }
1599
1600 /*
1601         set transmit ctcss modulation level
1602         adjust mixer output or internal gain depending on output type
1603         setting range is 0.0 to 0.9
1604 */
1605 static int set_txctcss_level(struct chan_usbradio_pvt *o)
1606 {                                                         
1607         if (o->txmixa == TX_OUT_LSD) {
1608                 o->txmixaset = (151 * o->txctcssadj) / 1000;
1609                 mixer_write(o);
1610                 mult_set(o);
1611         } else if (o->txmixb == TX_OUT_LSD) {
1612                 o->txmixbset = (151 * o->txctcssadj) / 1000;
1613                 mixer_write(o);
1614                 mult_set(o);
1615         } else {
1616                 *o->pmrChan->ptxCtcssAdjust = (o->txctcssadj * M_Q8) / 1000;
1617         }
1618         return 0;
1619 }
1620 /*
1621         CLI debugging on and off
1622 */
1623 static char *handle_cli_radio_set_debug_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1624 {
1625         struct chan_usbradio_pvt *o = NULL;
1626
1627         switch (cmd) {
1628         case CLI_INIT:
1629                 e->command = "radio set debug [off]";
1630                 e->usage =
1631                         "Usage: radio set debug [off]\n"
1632                         "       Enable/Disable radio debugging.\n";
1633         case CLI_GENERATE:
1634                 return NULL;
1635         }
1636         if (a->argc < 3 || a->argc > 4)
1637                 return CLI_SHOWUSAGE;
1638         if (a->argc == 4 && strncasecmp(a->argv[3], "off", 3))
1639                 return CLI_SHOWUSAGE;
1640
1641         o = find_desc(usbradio_active);
1642
1643         if (a->argc == 3)
1644                 o->debuglevel = 1;
1645         else
1646                 o->debuglevel = 0;
1647
1648         ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
1649
1650         return CLI_SUCCESS;
1651 }
1652
1653 static char *handle_cli_radio_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1654 {
1655         struct chan_usbradio_pvt *o = NULL;
1656
1657         switch (cmd) {
1658         case CLI_INIT:
1659                 e->command = "radio set debug {on|off}";
1660                 e->usage =
1661                         "Usage: radio set debug {on|off}\n"
1662                         "       Enable/Disable radio debugging.\n";
1663         case CLI_GENERATE:
1664                 return NULL;
1665         }
1666
1667         if (a->argc != e->args)
1668                 return CLI_SHOWUSAGE;
1669
1670         o = find_desc(usbradio_active);
1671
1672         if (!strncasecmp(a->argv[e->args - 1], "on", 2))
1673                 o->debuglevel = 1;
1674         else if (!strncasecmp(a->argv[e->args - 1], "off", 3))
1675                 o->debuglevel = 0;
1676         else
1677                 return CLI_SHOWUSAGE;
1678
1679         ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
1680
1681         return CLI_SUCCESS;
1682 }
1683
1684 static struct ast_cli_entry cli_radio_set_debug_deprecated = AST_CLI_DEFINE(handle_cli_radio_set_debug_deprecated, "Enable/Disable Radio Debugging");
1685 static struct ast_cli_entry cli_usbradio[] = {
1686         AST_CLI_DEFINE(handle_cli_radio_key,       "Simulate Rx Signal Present"),
1687         AST_CLI_DEFINE(handle_cli_radio_unkey,     "Simulate Rx Signal Lusb"),
1688         AST_CLI_DEFINE(handle_cli_radio_tune,      "Radio Tune"),
1689         AST_CLI_DEFINE(handle_cli_radio_set_debug, "Enable/Disable Radio Debugging", .deprecate_cmd = &cli_radio_set_debug_deprecated),
1690 };
1691
1692 /*
1693  * store the callerid components
1694  */
1695 #if 0
1696 static void store_callerid(struct chan_usbradio_pvt *o, const char *s)
1697 {
1698         ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
1699 }
1700 #endif
1701
1702 static void store_rxdemod(struct chan_usbradio_pvt *o, const char *s)
1703 {
1704         if (!strcasecmp(s, "no")) {
1705                 o->rxdemod = RX_AUDIO_NONE;
1706         } else if (!strcasecmp(s, "speaker")) {
1707                 o->rxdemod = RX_AUDIO_SPEAKER;
1708         } else if (!strcasecmp(s, "flat")) {
1709                         o->rxdemod = RX_AUDIO_FLAT;
1710         } else {
1711                 ast_log(LOG_WARNING, "Unrecognized rxdemod parameter: %s\n", s);
1712         }
1713
1714         ast_debug(4, "set rxdemod = %s\n", s);
1715 }
1716
1717                                            
1718 static void store_txmixa(struct chan_usbradio_pvt *o, const char *s)
1719 {
1720         if (!strcasecmp(s, "no"))
1721                 o->txmixa = TX_OUT_OFF;
1722
1723         else if (!strcasecmp(s, "voice"))
1724                 o->txmixa = TX_OUT_VOICE;
1725         else if (!strcasecmp(s, "tone"))
1726                         o->txmixa = TX_OUT_LSD;
1727         else if (!strcasecmp(s, "composite"))
1728                 o->txmixa = TX_OUT_COMPOSITE;
1729         else if (!strcasecmp(s, "auxvoice"))
1730                 o->txmixb = TX_OUT_AUX;
1731         else
1732                 ast_log(LOG_WARNING, "Unrecognized txmixa parameter: %s\n", s);
1733
1734         ast_debug(4, "set txmixa = %s\n", s);
1735 }
1736
1737 static void store_txmixb(struct chan_usbradio_pvt *o, const char *s)
1738 {
1739         if (!strcasecmp(s, "no"))
1740                 o->txmixb = TX_OUT_OFF;
1741         else if (!strcasecmp(s, "voice"))
1742                 o->txmixb = TX_OUT_VOICE;
1743         else if (!strcasecmp(s, "tone"))
1744                         o->txmixb = TX_OUT_LSD;
1745         else if (!strcasecmp(s, "composite"))
1746                 o->txmixb = TX_OUT_COMPOSITE;
1747         else if (!strcasecmp(s, "auxvoice"))
1748                 o->txmixb = TX_OUT_AUX;
1749         else
1750                 ast_log(LOG_WARNING, "Unrecognized txmixb parameter: %s\n", s);
1751
1752         ast_debug(4, "set txmixb = %s\n", s);
1753 }
1754
1755 static void store_rxcdtype(struct chan_usbradio_pvt *o, const char *s)
1756 {
1757         if (!strcasecmp(s, "no"))
1758                 o->rxcdtype = CD_IGNORE;
1759         else if (!strcasecmp(s, "usb"))
1760                 o->rxcdtype = CD_HID;
1761         else if (!strcasecmp(s, "dsp"))
1762                 o->rxcdtype = CD_XPMR_NOISE;
1763         else if (!strcasecmp(s, "vox"))
1764                 o->rxcdtype = CD_XPMR_VOX;
1765         else if (!strcasecmp(s, "usbinvert"))
1766                 o->rxcdtype = CD_HID_INVERT;
1767         else
1768                 ast_log(LOG_WARNING, "Unrecognized rxcdtype parameter: %s\n", s);
1769
1770         ast_debug(4, "set rxcdtype = %s\n", s);
1771 }
1772
1773 static void store_rxsdtype(struct chan_usbradio_pvt *o, const char *s)
1774 {
1775         if (!strcasecmp(s, "no") || !strcasecmp(s, "SD_IGNORE"))
1776                 o->rxsdtype = SD_IGNORE;
1777         else if (!strcasecmp(s, "usb") || !strcasecmp(s, "SD_HID"))
1778                 o->rxsdtype = SD_HID;
1779         else if (!strcasecmp(s, "usbinvert") || !strcasecmp(s, "SD_HID_INVERT"))
1780                 o->rxsdtype = SD_HID_INVERT;
1781         else if (!strcasecmp(s, "software") || !strcasecmp(s, "SD_XPMR"))
1782                 o->rxsdtype = SD_XPMR;
1783         else
1784                 ast_log(LOG_WARNING, "Unrecognized rxsdtype parameter: %s\n", s);
1785
1786         ast_debug(4, "set rxsdtype = %s\n", s);
1787 }
1788
1789 static void store_rxgain(struct chan_usbradio_pvt *o, const char *s)
1790 {
1791         float f;
1792         if (sscanf(s, "%f", &f) == 1)
1793                 o->rxgain = f;
1794         ast_debug(4, "set rxgain = %f\n", f);
1795 }
1796
1797 static void store_rxvoiceadj(struct chan_usbradio_pvt *o, const char *s)
1798 {
1799         float f;
1800         if (sscanf(s, "%f", &f) == 1)
1801                 o->rxvoiceadj = f;
1802         ast_debug(4, "set rxvoiceadj = %f\n", f);
1803 }
1804
1805 static void store_rxctcssadj(struct chan_usbradio_pvt *o, const char *s)
1806 {
1807         float f;
1808         if (sscanf(s, "%f", &f) == 1)
1809                 o->rxctcssadj = f;
1810         ast_debug(4, "set rxctcssadj = %f\n", f);
1811 }
1812
1813 static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s)
1814 {
1815         if (!strcasecmp(s, "no") || !strcasecmp(s, "TOC_NONE"))
1816                 o->txtoctype = TOC_NONE;
1817         else if (!strcasecmp(s, "phase") || !strcasecmp(s, "TOC_PHASE"))
1818                 o->txtoctype = TOC_PHASE;
1819         else if (!strcasecmp(s, "notone") || !strcasecmp(s, "TOC_NOTONE"))
1820                 o->txtoctype = TOC_NOTONE;
1821         else
1822                 ast_log(LOG_WARNING, "Unrecognized txtoctype parameter: %s\n", s);
1823
1824         ast_debug(4, "set txtoctype = %s\n", s);
1825 }
1826
1827 static void store_rxctcssfreq(struct chan_usbradio_pvt *o, const char *s)
1828 {
1829         float f;
1830         if (sscanf(s, "%f", &f) == 1)
1831                 o->rxctcssfreq = f;
1832         ast_debug(4, "set rxctcss = %f\n", f);
1833 }
1834
1835 static void store_txctcssfreq(struct chan_usbradio_pvt *o, const char *s)
1836 {
1837         float f;
1838         if (sscanf(s, "%f", &f) == 1)
1839                 o->txctcssfreq = f;
1840         ast_debug(4, "set txctcss = %f\n", f);
1841 }
1842
1843 static void tune_txoutput(struct chan_usbradio_pvt *o, int value)
1844 {
1845         o->txtestkey = 1;
1846         o->pmrChan->txPttIn = 1;
1847
1848 #if 0
1849         /* generate 1KHz tone at 7200 peak */
1850         o->pmrChan->spsSigGen1->freq = 10000;
1851         o->pmrChan->spsSigGen1->outputGain = (float)(0.22 * M_Q8);
1852         o->pmrChan->b.startSpecialTone = 1;
1853 #endif
1854
1855         TxTestTone(o->pmrChan, 1);
1856
1857         usleep(5000000);
1858         /* o->pmrChan->b.stopSpecialTone = 1; */
1859         usleep(100000);
1860
1861         TxTestTone(o->pmrChan, 0);
1862
1863         o->pmrChan->txPttIn = 0;
1864         o->txtestkey = 0;
1865 }
1866
1867 static void tune_rxinput(struct chan_usbradio_pvt *o)
1868 {
1869         const int target = 23000;
1870         const int tolerance = 2000;
1871         const int settingmin = 1;
1872         const int settingstart = 2;
1873         const int maxtries = 12;
1874
1875         float settingmax;
1876         
1877         int setting = 0, tries = 0, tmpdiscfactor, meas;
1878         int tunetype = 0;
1879
1880         settingmax = o->micmax;
1881
1882         if (o->pmrChan->rxDemod)
1883                 tunetype = 1;
1884
1885         setting = settingstart;
1886
1887         while (tries < maxtries) {
1888                 setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL, setting, 0);
1889                 setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
1890                 usleep(100000);
1891                 if (o->rxcdtype == CD_XPMR_VOX || o->rxdemod == RX_AUDIO_SPEAKER) {
1892                         ast_debug(4, "Measure Direct Input\n");
1893                         o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
1894                         o->pmrChan->spsMeasure->discfactor = 1000;
1895                         o->pmrChan->spsMeasure->enabled = 1;
1896                         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
1897                         usleep(400000); 
1898                         meas = o->pmrChan->spsMeasure->apeak;
1899                         o->pmrChan->spsMeasure->enabled = 0;    
1900                 } else {
1901                         ast_debug(4, "Measure HF Noise\n");
1902                         tmpdiscfactor = o->pmrChan->spsRx->discfactor;
1903                         o->pmrChan->spsRx->discfactor = (i16)1000;
1904                         o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
1905                         o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
1906                         usleep(200000);
1907                         meas = o->pmrChan->rxRssi;
1908                         o->pmrChan->spsRx->discfactor = tmpdiscfactor;
1909                         o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
1910                         o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
1911                 }
1912         if (!meas)
1913                         meas++;
1914                 ast_log(LOG_NOTICE, "tries=%d, setting=%d, meas=%i\n", tries, setting, meas);
1915
1916                 if ( meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
1917                         setting = setting * target / meas;
1918                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance) )
1919                         break;
1920
1921                 if (setting < settingmin)
1922                         setting = settingmin;
1923                 else if (setting > settingmax)
1924                         setting = settingmax;
1925
1926                 tries++;
1927         }
1928         ast_log(LOG_NOTICE, "DONE tries=%d, setting=%d, meas=%i\n", tries,
1929                 (setting * 1000) / o->micmax, meas);
1930         if (meas < (target - tolerance) || meas > (target + tolerance))
1931                 ast_log(LOG_NOTICE, "ERROR: RX INPUT ADJUST FAILED.\n");
1932         else {
1933                 ast_log(LOG_NOTICE, "INFO: RX INPUT ADJUST SUCCESS.\n");        
1934                 o->rxmixerset = (setting * 1000) / o->micmax;
1935         }
1936 }
1937 /*
1938 */
1939 static void tune_rxvoice(struct chan_usbradio_pvt *o)
1940 {
1941         const int target = 7200;        /* peak */
1942         const int tolerance = 360;      /* peak to peak */
1943         const float settingmin = 0.1;
1944         const float settingmax = 4;
1945         const float settingstart = 1;
1946         const int maxtries = 12;
1947
1948         float setting;
1949
1950         int tries = 0, meas;
1951
1952         ast_log(LOG_NOTICE, "INFO: RX VOICE ADJUST START.\n");  
1953         ast_log(LOG_NOTICE, "target=%d tolerance=%d\n", target, tolerance);
1954
1955         if (!o->pmrChan->spsMeasure)
1956                 ast_log(LOG_ERROR, "NO MEASURE BLOCK.\n");
1957
1958         if (!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
1959                 ast_log(LOG_ERROR, "NO SOURCE OR MEASURE SETTING.\n");
1960
1961         o->pmrChan->spsMeasure->source = o->pmrChan->spsRxOut->sink;
1962         o->pmrChan->spsMeasure->enabled = 1;
1963         o->pmrChan->spsMeasure->discfactor = 1000;
1964
1965         setting=settingstart;
1966
1967         ast_debug(4, "ERROR: NO MEASURE BLOCK.\n");
1968
1969         while (tries < maxtries) {
1970                 *(o->pmrChan->prxVoiceAdjust) = setting * M_Q8;
1971                 usleep(10000);
1972         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
1973                 usleep(1000000);
1974                 meas = o->pmrChan->spsMeasure->apeak;
1975                 ast_log(LOG_NOTICE, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
1976
1977                 if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
1978                         setting = setting * target / meas;
1979                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
1980                         break;
1981                 if (setting < settingmin)
1982                         setting = settingmin;
1983                 else if (setting > settingmax)
1984                         setting = settingmax;
1985
1986                 tries++;
1987         }
1988
1989         o->pmrChan->spsMeasure->enabled = 0;
1990
1991         ast_log(LOG_NOTICE, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
1992         if (meas < (target - tolerance) || meas > (target + tolerance))
1993                 ast_log(LOG_ERROR, "RX VOICE GAIN ADJUST FAILED.\n");
1994         else {
1995                 ast_log(LOG_NOTICE, "RX VOICE GAIN ADJUST SUCCESS.\n");
1996                 o->rxvoiceadj = setting;
1997         }
1998 }
1999
2000 static void tune_rxctcss(struct chan_usbradio_pvt *o)
2001 {
2002         const int target = 4096;
2003         const int tolerance = 100;
2004         const float settingmin = 0.1;
2005         const float settingmax = 4;
2006         const float settingstart = 1;
2007         const int maxtries = 12;
2008
2009         float setting;
2010         int tries = 0, meas;
2011
2012         ast_log(LOG_NOTICE, "RX CTCSS ADJUST START.\n");        
2013         ast_log(LOG_NOTICE, "target=%d tolerance=%d \n", target, tolerance);
2014
2015         o->pmrChan->spsMeasure->source = o->pmrChan->prxCtcssMeasure;
2016         o->pmrChan->spsMeasure->discfactor = 400;
2017         o->pmrChan->spsMeasure->enabled = 1;
2018
2019         setting = settingstart;
2020
2021         while (tries < maxtries) {
2022                 *(o->pmrChan->prxCtcssAdjust) = setting * M_Q8;
2023                 usleep(10000);
2024         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
2025                 usleep(500000);
2026                 meas = o->pmrChan->spsMeasure->apeak;
2027                 ast_debug(4, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
2028
2029                 if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
2030                         setting = setting * target / meas;
2031                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
2032                         break;
2033                 if (setting < settingmin)
2034                         setting = settingmin;
2035                 else if (setting > settingmax)
2036                         setting = settingmax;
2037
2038                 tries++;
2039         }
2040         o->pmrChan->spsMeasure->enabled = 0;
2041         ast_debug(4, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
2042         if (meas < (target - tolerance) || meas > (target + tolerance))
2043                 ast_log(LOG_ERROR, "RX CTCSS GAIN ADJUST FAILED.\n");
2044         else {
2045                 ast_log(LOG_NOTICE, "RX CTCSS GAIN ADJUST SUCCESS.\n");
2046                 o->rxctcssadj = setting;
2047         }
2048 }
2049 /*
2050         this file then is included in chan_usbradio.conf
2051         #include /etc/asterisk/usbradio_tune.conf 
2052 */
2053 static void tune_write(struct chan_usbradio_pvt *o)
2054 {
2055         FILE *fp;
2056         
2057         fp = fopen("/etc/asterisk/usbradio_tune.conf", "w");
2058  
2059         if (!strcmp(o->name, "dsp"))
2060                 fprintf(fp, "[general]\n");
2061         else
2062                 fprintf(fp, "[%s]\n", o->name);
2063
2064         fprintf(fp, "; name=%s\n", o->name);
2065         fprintf(fp, "; devicenum=%d\n", o->devicenum);
2066
2067         fprintf(fp, "rxmixerset=%d\n", o->rxmixerset);
2068         fprintf(fp, "rxboostset=%d\n", o->rxboostset);
2069         fprintf(fp, "txmixaset=%d\n", o->txmixaset);
2070         fprintf(fp, "txmixbset=%d\n", o->txmixbset);
2071
2072         fprintf(fp, "rxvoiceadj=%f\n", o->rxvoiceadj);
2073         fprintf(fp, "rxctcssadj=%f\n", o->rxctcssadj);
2074         fprintf(fp, "txctcssadj=%d\n", o->txctcssadj);
2075
2076         fprintf(fp, "rxsquelchadj=%d\n", o->rxsquelchadj);
2077         fclose(fp);
2078 }
2079
2080 static void mixer_write(struct chan_usbradio_pvt *o)
2081 {
2082         setamixer(o->devicenum, MIXER_PARAM_MIC_PLAYBACK_SW, 0, 0);
2083         setamixer(o->devicenum, MIXER_PARAM_MIC_PLAYBACK_VOL, 0, 0);
2084         setamixer(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_SW, 1, 0);
2085         setamixer(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL,
2086                 o->txmixaset * o->spkrmax / 1000,
2087                 o->txmixbset * o->spkrmax / 1000);
2088         setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL,
2089                 o->rxmixerset * o->micmax / 1000, 0);
2090         setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
2091         setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_SW, 1, 0);
2092 }
2093 /*
2094         adjust dsp multiplier to add resolution to tx level adjustment
2095 */
2096 static void mult_set(struct chan_usbradio_pvt *o)
2097 {
2098
2099         if (o->pmrChan->spsTxOutA) {
2100                 o->pmrChan->spsTxOutA->outputGain = 
2101                         mult_calc((o->txmixaset * 152) / 1000);
2102         }
2103         if (o->pmrChan->spsTxOutB) {
2104                 o->pmrChan->spsTxOutB->outputGain = 
2105                         mult_calc((o->txmixbset * 152) / 1000);
2106         }
2107 }
2108 /*
2109  * input 0 - 151 outputs are pot and multiplier
2110  */
2111 static int mult_calc(int value)
2112 {
2113         const int multx = M_Q8;
2114         int pot, mult;
2115
2116         pot= ((int)(value / 4) * 4) + 2;
2117         mult = multx - ((multx * (3 - (value % 4))) / (pot + 2));
2118         return mult;
2119 }
2120
2121 #define pd(x) ast_debug(4, #x" = %d\n", x)
2122 #define pp(x) ast_debug(4, #x" = %p\n", x)
2123 #define ps(x) ast_debug(4, #x" = %s\n", x)
2124 #define pf(x) ast_debug(4, #x" = %f\n", x)
2125 /*
2126 */
2127 static void pmrdump(struct chan_usbradio_pvt *o)
2128 {
2129         t_pmr_chan *p;
2130
2131         p = o->pmrChan;
2132
2133         ast_debug(4, "odump()\n");
2134
2135         pd(o->devicenum);
2136
2137         pd(o->rxdemod);
2138         pd(o->rxcdtype);
2139         pd(o->rxsdtype);
2140         pd(o->txtoctype);
2141
2142         pd(o->rxmixerset);
2143         pf(o->rxvoiceadj);
2144         pf(o->rxctcssadj);
2145         pd(o->rxsquelchadj);
2146          
2147         pd(o->txprelim);
2148         pd(o->txmixa);
2149         pd(o->txmixb);
2150         
2151         pd(o->txmixaset);
2152         pd(o->txmixbset);
2153         
2154         ast_debug(4, "pmrdump()\n");
2155  
2156         ast_debug(4, "prxSquelchAdjust=%d\n", *(o->pmrChan->prxSquelchAdjust));
2157
2158         pd(p->rxCarrierPoint);
2159         pd(p->rxCarrierHyst);
2160
2161         pd(p->rxCtcss->relax);
2162         pf(p->rxCtcssFreq);     
2163         pd(p->rxCtcssIndex);
2164         pf(p->txCtcssFreq);
2165
2166         pd(p->txMixA);
2167         pd(p->txMixB);
2168     
2169         pd(p->rxDeEmpEnable);
2170         pd(p->rxCenterSlicerEnable);
2171         pd(p->rxCtcssDecodeEnable);
2172         pd(p->rxDcsDecodeEnable);
2173
2174         pd(p->txHpfEnable);
2175         pd(p->txLimiterEnable);
2176         pd(p->txPreEmpEnable);
2177         pd(p->txLpfEnable);
2178
2179         if (p->spsTxOutA)
2180                 pd(p->spsTxOutA->outputGain);
2181         if (p->spsTxOutB)
2182                 pd(p->spsTxOutB->outputGain);
2183
2184         return;
2185 }
2186
2187
2188 /*
2189  * grab fields from the config file, init the descriptor and open the device.
2190  */
2191 static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
2192 {
2193         struct ast_variable *v;
2194         struct chan_usbradio_pvt *o;
2195         struct ast_config *cfg1;
2196         struct ast_flags config_flags = { 0 };
2197
2198         if (ctg == NULL) {
2199                 traceusb1(" store_config() ctg == NULL\n");
2200                 o = &usbradio_default;
2201                 ctg = "general";
2202         } else {
2203                 if (!(o = ast_calloc(1, sizeof(*o)))){
2204                         return NULL;
2205                 }
2206                 *o = usbradio_default;
2207                 /* "general" is also the default thing */
2208                 if (strcmp(ctg, "general") == 0) {
2209                         o->name = ast_strdup("dsp");
2210                         usbradio_active = o->name;
2211                 } else
2212                         o->name = ast_strdup(ctg);
2213         }
2214
2215         strcpy(o->mohinterpret, "default");
2216         o->micmax = amixer_max(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL);
2217         o->spkrmax = amixer_max(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL);
2218         /* fill other fields from configuration */
2219         for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
2220
2221                 /* handle jb conf */
2222                 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
2223                         continue;
2224                 CV_START(v->name, v->value);
2225
2226                 CV_UINT("frags", o->frags);
2227                 CV_UINT("queuesize", o->queuesize);
2228                 CV_UINT("devicenum", o->devicenum);
2229                 CV_UINT("debug", usbradio_debug);
2230                 CV_BOOL("rxcpusaver", o->rxcpusaver);
2231                 CV_BOOL("txcpusaver", o->txcpusaver);
2232                 CV_BOOL("invertptt", o->invertptt);
2233                 CV_F("rxdemod", store_rxdemod(o, v->value));
2234                 CV_BOOL("txprelim", o->txprelim);;
2235                 CV_F("txmixa", store_txmixa(o, v->value));
2236                 CV_F("txmixb", store_txmixb(o, v->value));
2237                 CV_F("carrierfrom", store_rxcdtype(o, v->value));
2238                 CV_F("rxsdtype", store_rxsdtype(o, v->value));
2239                 CV_F("rxctcssfreq", store_rxctcssfreq(o, v->value));
2240                 CV_F("txctcssfreq", store_txctcssfreq(o, v->value));
2241                 CV_F("rxgain", store_rxgain(o, v->value));
2242                 CV_BOOL("rxboostset", o->rxboostset);
2243                 CV_UINT("rxctcssrelax", o->rxctcssrelax);
2244                 CV_F("txtoctype", store_txtoctype(o, v->value));
2245                 CV_UINT("hdwtype", o->hdwtype);
2246                 CV_UINT("duplex", o->radioduplex);
2247
2248                 CV_END;
2249         }
2250         
2251         cfg1 = ast_config_load(config1, config_flags);
2252         if (!cfg1) {
2253                 o->rxmixerset = 500;
2254                 o->txmixaset = 500;
2255                 o->txmixbset = 500;
2256                 o->rxvoiceadj = 0.5;
2257                 o->rxctcssadj = 0.5;
2258                 o->txctcssadj = 200;
2259                 o->rxsquelchadj = 500;
2260                 ast_log(LOG_WARNING, "File %s not found, using default parameters.\n", config1);
2261         } else  {
2262                 for (v = ast_variable_browse(cfg1, ctg); v; v = v->next) {
2263         
2264                         CV_START(v->name, v->value);
2265                         CV_UINT("rxmixerset", o->rxmixerset);
2266                         CV_UINT("txmixaset", o->txmixaset);
2267                         CV_UINT("txmixbset", o->txmixbset);
2268                         CV_F("rxvoiceadj", store_rxvoiceadj(o, v->value));
2269                         CV_F("rxctcssadj", store_rxctcssadj(o, v->value));
2270                         CV_UINT("txctcssadj", o->txctcssadj);
2271                         CV_UINT("rxsquelchadj", o->rxsquelchadj);
2272                         CV_END;
2273                 }
2274                 ast_config_destroy(cfg1);
2275         }
2276
2277         o->debuglevel = 0;
2278
2279         if (o == &usbradio_default)             /* we are done with the default */
2280                 return NULL;
2281
2282         o->lastopen = ast_tvnow();      /* don't leave it 0 or tvdiff may wrap */
2283         o->dsp = ast_dsp_new();
2284         if (o->dsp) {
2285                 ast_dsp_set_features(o->dsp, DSP_FEATURE_DTMF_DETECT);
2286                 ast_dsp_set_digitmode(o->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
2287         }
2288
2289         if (o->rxctcssfreq != 0 && o->rxdemod == RX_AUDIO_SPEAKER)
2290                 ast_log(LOG_ERROR, "Incompatable Options  o->rxctcssfreq=%f and o->rxdemod=speaker\n", o->rxctcssfreq); 
2291
2292         if (o->pmrChan == NULL) {
2293                 t_pmr_chan tChan;
2294
2295                 memset(&tChan, 0, sizeof(tChan));
2296
2297                 tChan.rxDemod = o->rxdemod;
2298                 tChan.rxCdType = o->rxcdtype;
2299
2300                 tChan.txMod = o->txprelim;
2301
2302                 tChan.txMixA = o->txmixa;
2303                 tChan.txMixB = o->txmixb;
2304
2305                 tChan.rxCpuSaver = o->rxcpusaver;
2306                 tChan.txCpuSaver = o->txcpusaver;
2307
2308                 tChan.rxCtcssFreq = o->rxctcssfreq;
2309                 tChan.txCtcssFreq = o->txctcssfreq;
2310
2311                 o->pmrChan = createPmrChannel(&tChan, FRAME_SIZE);
2312
2313                 o->pmrChan->radioDuplex = o->radioduplex;
2314
2315                 o->pmrChan->rxCpuSaver = o->rxcpusaver;
2316                 o->pmrChan->txCpuSaver = o->txcpusaver;
2317
2318                 *(o->pmrChan->prxSquelchAdjust) = 
2319                         ((999 - o->rxsquelchadj) * 32767) / 1000;
2320
2321                 o->pmrChan->spsRx->outputGain = o->rxvoiceadj*M_Q8;
2322
2323                 o->pmrChan->txTocType = o->txtoctype;
2324
2325                 if ((o->txmixa == TX_OUT_LSD) ||
2326                         (o->txmixa == TX_OUT_COMPOSITE) ||
2327                         (o->txmixb == TX_OUT_LSD) ||
2328                         (o->txmixb == TX_OUT_COMPOSITE)) {
2329                         *(o->pmrChan->prxCtcssAdjust) = o->rxctcssadj * M_Q8;
2330                         set_txctcss_level(o);
2331                 }
2332
2333                 o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
2334
2335         }
2336
2337         if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
2338                 (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE))
2339                 ast_log(LOG_ERROR, "No txvoice output configured.\n");
2340
2341         if (o->txctcssfreq && 
2342             o->txmixa != TX_OUT_LSD && o->txmixa != TX_OUT_COMPOSITE  &&
2343                 o->txmixb != TX_OUT_LSD && o->txmixb != TX_OUT_COMPOSITE)
2344                 ast_log(LOG_ERROR, "No txtone output configured.\n");
2345
2346         if (o->rxctcssfreq && o->pmrChan->rxCtcssIndex < 0)
2347                 ast_log(LOG_ERROR, "Invalid CTCSS Frequency.\n");
2348
2349         /* RxTestIt(o); */
2350
2351         mixer_write(o);
2352         mult_set(o);    
2353         hidhdwconfig(o);
2354
2355         /* pmrdump(o); */
2356
2357         /* link into list of devices */
2358         if (o != &usbradio_default) {
2359                 o->next = usbradio_default.next;
2360                 usbradio_default.next = o;
2361         }
2362         return o;
2363 }
2364
2365 #if     DEBUG_FILETEST == 1
2366 /*
2367         Test It on a File
2368 */
2369 int RxTestIt(struct chan_usbradio_pvt *o)
2370 {
2371         const int numSamples = SAMPLES_PER_BLOCK;
2372         const int numChannels = 16;
2373
2374         i16 sample, i, ii;
2375         
2376         i32 txHangTime;
2377
2378         i16 txEnable;
2379
2380         t_pmr_chan tChan;
2381         t_pmr_chan *pChan;
2382
2383         FILE *hInput = NULL, *hOutput = NULL, *hOutputTx = NULL;
2384  
2385         i16 iBuff[numSamples * 2 * 6], oBuff[numSamples];
2386
2387         ast_debug(4, "RxTestIt()\n");
2388
2389         pChan = o->pmrChan;
2390         pChan->b.txCapture = 1;
2391         pChan->b.rxCapture = 1;
2392
2393         txEnable = 0;
2394
2395         hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm", "r");
2396         if (!hInput){
2397                 ast_debug(4, " RxTestIt() File Not Found.\n");
2398                 return 0;
2399         }
2400         hOutput = fopen("/usr/src/xpmr/testdata/rx_debug.pcm", "w");
2401
2402         ast_debug(4, " RxTestIt() Working...\n");
2403                                 
2404         while (!feof(hInput)) {
2405                 fread((void *)iBuff, 2, numSamples * 2 * 6, hInput);
2406                  
2407                 if (txHangTime)
2408                         txHangTime -= numSamples;
2409                 if (txHangTime < 0)
2410                         txHangTime = 0;
2411                 
2412                 if (pChan->rxCtcss->decode)
2413                         txHangTime = (8000 / 1000 * 2000);
2414
2415                 if (pChan->rxCtcss->decode && !txEnable) {
2416                         txEnable = 1;
2417                         /* pChan->inputBlanking = (8000 / 1000 * 200); */
2418                 } else if (!pChan->rxCtcss->decode && txEnable) {
2419                         txEnable = 0;
2420                 }
2421
2422                 PmrRx(pChan, iBuff, oBuff);
2423
2424                 fwrite((void *)pChan->prxDebug, 2, numSamples * numChannels, hOutput);
2425         }
2426         pChan->b.txCapture = 0;
2427         pChan->b.rxCapture = 0;
2428
2429         if (hInput)
2430                 fclose(hInput);
2431         if (hOutput)
2432                 fclose(hOutput);
2433
2434         ast_debug(4, " RxTestIt() Complete.\n");
2435
2436         return 0;
2437 }
2438 #endif
2439
2440 #include "./xpmr/xpmr.c"
2441 /*
2442 */
2443 static int load_module(void)
2444 {
2445         struct ast_config *cfg = NULL;
2446         char *ctg = NULL;
2447         struct ast_flags config_flags = { 0 };
2448
2449         /* Copy the default jb config over global_jbconf */
2450         memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2451
2452         /* load config file */
2453         if (!(cfg = ast_config_load(config, config_flags))) {
2454                 ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
2455                 return AST_MODULE_LOAD_DECLINE;
2456         }
2457
2458         do {
2459                 store_config(cfg, ctg);
2460         } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
2461
2462         ast_config_destroy(cfg);
2463
2464         if (find_desc(usbradio_active) == NULL) {
2465                 ast_log(LOG_NOTICE, "Device %s not found\n", usbradio_active);
2466                 /* XXX we could default to 'dsp' perhaps ? */
2467                 /* XXX should cleanup allocated memory etc. */
2468                 return AST_MODULE_LOAD_FAILURE;
2469         }
2470
2471         if (ast_channel_register(&usbradio_tech)) {
2472                 ast_log(LOG_ERROR, "Unable to register channel type 'usb'\n");
2473                 return AST_MODULE_LOAD_FAILURE;
2474         }
2475
2476         ast_cli_register_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
2477
2478         return AST_MODULE_LOAD_SUCCESS;
2479 }
2480 /*
2481 */
2482 static int unload_module(void)
2483 {
2484         struct chan_usbradio_pvt *o;
2485
2486         ast_log(LOG_WARNING, "unload_module() called\n");
2487
2488         ast_channel_unregister(&usbradio_tech);
2489         ast_cli_unregister_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
2490
2491         for (o = usbradio_default.next; o; o = o->next) {
2492
2493                 ast_log(LOG_WARNING, "destroyPmrChannel() called\n");
2494                 if (o->pmrChan)
2495                         destroyPmrChannel(o->pmrChan);
2496                 
2497                 #if DEBUG_CAPTURES == 1
2498                 if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
2499                 if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
2500                 if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
2501                 if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
2502                 if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
2503                 if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
2504                 #endif
2505
2506                 close(o->sounddev);
2507                 if (o->dsp)
2508                         ast_dsp_free(o->dsp);
2509                 if (o->owner)
2510                         ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
2511                 if (o->owner)                   /* XXX how ??? */
2512                         return -1;
2513                 /* XXX what about the thread ? */
2514                 /* XXX what about the memory allocated ? */
2515         }
2516         return 0;
2517 }
2518
2519 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "usb Console Channel Driver");
2520
2521 /*      end of file */
2522
2523