Get rid of any remaining ast_verbose calls in the code in favor of
[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->subclass == 'm') || (f1->subclass == 'u'))
1214                             f1->frametype = AST_FRAME_DTMF_BEGIN;
1215                         if (f1->frametype == AST_FRAME_DTMF_END)
1216                             ast_log(LOG_NOTICE,"Got DTMF char %c\n",f1->subclass);
1217                         return f1;
1218                 }
1219         }
1220         return f;
1221 }
1222
1223 static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1224 {
1225         struct chan_usbradio_pvt *o = newchan->tech_pvt;
1226         ast_log(LOG_WARNING,"usbradio_fixup()\n");
1227         o->owner = newchan;
1228         return 0;
1229 }
1230
1231 static int usbradio_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
1232 {
1233         struct chan_usbradio_pvt *o = c->tech_pvt;
1234         int res = 0;
1235
1236         switch (cond) {
1237         case AST_CONTROL_BUSY:
1238         case AST_CONTROL_CONGESTION:
1239         case AST_CONTROL_RINGING:
1240         case -1:
1241                 res = -1;
1242                 break;
1243         case AST_CONTROL_PROGRESS:
1244         case AST_CONTROL_PROCEEDING:
1245         case AST_CONTROL_VIDUPDATE:
1246                 break;
1247         case AST_CONTROL_HOLD:
1248                 ast_verb(0, " << Console Has Been Placed on Hold >> \n");
1249                 ast_moh_start(c, data, o->mohinterpret);
1250                 break;
1251         case AST_CONTROL_UNHOLD:
1252                 ast_verb(0, " << Console Has Been Retrieved from Hold >> \n");
1253                 ast_moh_stop(c);
1254                 break;
1255         case AST_CONTROL_RADIO_KEY:
1256                 o->txkeyed = 1;
1257                 if (o->debuglevel)
1258                         ast_verb(0, " << Radio Transmit On. >> \n");
1259                 break;
1260         case AST_CONTROL_RADIO_UNKEY:
1261                 o->txkeyed = 0;
1262                 if (o->debuglevel)
1263                         ast_verb(0, " << Radio Transmit Off. >> \n");
1264                 break;
1265         default:
1266                 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
1267                 return -1;
1268         }
1269
1270         return res;
1271 }
1272
1273 /*
1274  * allocate a new channel.
1275  */
1276 static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state)
1277 {
1278         struct ast_channel *c;
1279         char device[15] = "dsp";
1280
1281         if (o->devicenum)
1282                 snprintf(device + 3, sizeof(device) - 3, "%d", o->devicenum);
1283         c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "usbRadio/%s", device);
1284         if (c == NULL)
1285                 return NULL;
1286         c->tech = &usbradio_tech;
1287         if (o->sounddev < 0)
1288                 setformat(o, O_RDWR);
1289         c->fds[0] = o->sounddev;        /* -1 if device closed, override later */
1290         c->nativeformats = AST_FORMAT_SLINEAR;
1291         c->readformat = AST_FORMAT_SLINEAR;
1292         c->writeformat = AST_FORMAT_SLINEAR;
1293         c->tech_pvt = o;
1294
1295         if (!ast_strlen_zero(o->language))
1296                 ast_string_field_set(c, language, o->language);
1297         /* Don't use ast_set_callerid() here because it will
1298          * generate a needless NewCallerID event */
1299         c->cid.cid_num = ast_strdup(o->cid_num);
1300         c->cid.cid_ani = ast_strdup(o->cid_num);
1301         c->cid.cid_name = ast_strdup(o->cid_name);
1302         if (!ast_strlen_zero(ext))
1303                 c->cid.cid_dnid = ast_strdup(ext);
1304
1305         o->owner = c;
1306         ast_module_ref(ast_module_info->self);
1307         ast_jb_configure(c, &global_jbconf);
1308         if (state != AST_STATE_DOWN) {
1309                 if (ast_pbx_start(c)) {
1310                         ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
1311                         ast_hangup(c);
1312                         o->owner = c = NULL;
1313                         /* XXX what about the channel itself ? */
1314                         /* XXX what about usecnt ? */
1315                 }
1316         }
1317
1318         return c;
1319 }
1320
1321 static struct ast_channel *usbradio_request(const char *type, int format, void *data, int *cause)
1322 {
1323         struct ast_channel *c;
1324         struct chan_usbradio_pvt *o = find_desc(data);
1325
1326         ast_debug(4, "usbradio_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data);
1327         if (o == NULL) {
1328                 ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
1329                 /* XXX we could default to 'dsp' perhaps ? */
1330                 return NULL;
1331         }
1332         if ((format & AST_FORMAT_SLINEAR) == 0) {
1333                 ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
1334                 return NULL;
1335         }
1336         if (o->owner) {
1337                 ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
1338                 *cause = AST_CAUSE_BUSY;
1339                 return NULL;
1340         }
1341         c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
1342         if (c == NULL) {
1343                 ast_log(LOG_WARNING, "Unable to create new usb channel\n");
1344                 return NULL;
1345         }
1346         return c;
1347 }
1348
1349 static char *handle_cli_radio_key(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1350 {
1351         struct chan_usbradio_pvt *o = NULL;
1352
1353         switch (cmd) {
1354         case CLI_INIT:
1355                 e->command = "radio key";
1356                 e->usage =
1357                         "Usage: radio key\n"
1358                         "       Simulates COR active.\n";
1359                 return NULL;
1360         case CLI_GENERATE:
1361                 return NULL;
1362         }
1363
1364         if (a->argc != 2)
1365                 return CLI_SHOWUSAGE;
1366
1367         o = find_desc(usbradio_active);
1368         o->txtestkey = 1;
1369
1370         return CLI_SUCCESS;
1371 }
1372
1373 static char *handle_cli_radio_unkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1374 {
1375         struct chan_usbradio_pvt *o = NULL;
1376
1377         switch (cmd) {
1378         case CLI_INIT:
1379                 e->command = "radio unkey";
1380                 e->usage =
1381                         "Usage: radio unkey\n"
1382                         "       Simulates COR un-active.\n";
1383                 return NULL;
1384         case CLI_GENERATE:
1385                 return NULL;
1386         }
1387
1388         if (a->argc != 2)
1389                 return CLI_SHOWUSAGE;
1390
1391         o = find_desc(usbradio_active);
1392         o->txtestkey = 0;
1393
1394         return CLI_SUCCESS;
1395 }
1396
1397 static char *handle_cli_radio_tune(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1398 {
1399         struct chan_usbradio_pvt *o = NULL;
1400         int i = 0;
1401
1402         switch (cmd) {
1403         case CLI_INIT:
1404                 e->command = "radio tune [rxnoise|rxvoice|rxtone|rxsquelch|rxcap|rxtracecap|"
1405                         "txvoice|txtone|txcap|txtracecap|auxvoice|nocap|dump|save]";
1406                 /* radio tune 6 3000        measured tx value */
1407                 e->usage =
1408                         "Usage: radio tune <function>\n"
1409                         "       rxnoise\n"
1410                         "       rxvoice\n"
1411                         "       rxtone\n"
1412                         "       rxsquelch [newsetting]\n"
1413                         "       rxcap\n"
1414                         "       rxtracecap\n"
1415                         "       txvoice [newsetting]\n"
1416                         "       txtone [newsetting]\n"
1417                         "       txcap\n"
1418                         "       txtracecap\n"
1419                         "       auxvoice [newsetting]\n"
1420                         "       nocap\n"
1421                         "       dump\n"
1422                         "       save (settings to tuning file)\n"
1423                         "\n"
1424                         "       All [newsetting]s are values 0-999\n";
1425                 return NULL;
1426         case CLI_GENERATE:
1427                 return NULL;
1428         }
1429
1430         if ((a->argc < 2) || (a->argc > 4))
1431                 return CLI_SHOWUSAGE; 
1432
1433         if (a->argc == 2) { /* just show stuff */
1434                 ast_cli(a->fd, "Output A is currently set to %s.\n",
1435                         o->txmixa == TX_OUT_COMPOSITE ? "composite" :
1436                         o->txmixa == TX_OUT_VOICE ? "voice" :
1437                         o->txmixa == TX_OUT_LSD ? "tone" :
1438                         o->txmixa == TX_OUT_AUX ? "auxvoice" :
1439                         "off");
1440
1441                 ast_cli(a->fd, "Output B is currently set to %s.\n",
1442                         o->txmixb == TX_OUT_COMPOSITE ? "composite" :
1443                         o->txmixb == TX_OUT_VOICE ? "voice" :
1444                         o->txmixb == TX_OUT_LSD ? "tone" :
1445                         o->txmixb == TX_OUT_AUX ? "auxvoice" :
1446                         "off");
1447
1448                 ast_cli(a->fd, "Tx Voice Level currently set to %d\n", o->txmixaset);
1449                 ast_cli(a->fd, "Tx Tone Level currently set to %d\n", o->txctcssadj);
1450                 ast_cli(a->fd, "Rx Squelch currently set to %d\n", o->rxsquelchadj);
1451                 return CLI_SHOWUSAGE;
1452         }
1453
1454         o = find_desc(usbradio_active);
1455
1456         if (!strcasecmp(a->argv[2], "rxnoise"))
1457                 tune_rxinput(o);
1458         else if (!strcasecmp(a->argv[2], "rxvoice"))
1459                 tune_rxvoice(o);
1460         else if (!strcasecmp(a->argv[2], "rxtone"))
1461                 tune_rxctcss(o);
1462         else if (!strcasecmp(a->argv[2], "rxsquelch")) {
1463                 if (a->argc == 3) {
1464                     ast_cli(a->fd, "Current Signal Strength is %d\n", ((32767 - o->pmrChan->rxRssi) * 1000 / 32767));
1465                     ast_cli(a->fd, "Current Squelch setting is %d\n", o->rxsquelchadj);
1466 #if 0
1467                         ast_cli(a->fd,"Current Raw RSSI        is %d\n",o->pmrChan->rxRssi);
1468                     ast_cli(a->fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
1469 #endif
1470                 } else {
1471                         i = atoi(a->argv[3]);
1472                         if ((i < 0) || (i > 999))
1473                                 return CLI_SHOWUSAGE;
1474                         ast_cli(a->fd, "Changed Squelch setting to %d\n", i);
1475                         o->rxsquelchadj = i;
1476                         *(o->pmrChan->prxSquelchAdjust) = ((999 - i) * 32767) / 1000;
1477                 }
1478         } else if (!strcasecmp(a->argv[2], "txvoice")) {
1479                 i = 0;
1480
1481                 if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
1482                         (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE)) {
1483                         ast_log(LOG_ERROR, "No txvoice output configured.\n");
1484                 } else if (a->argc == 3) {
1485                         if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE))
1486                                 ast_cli(a->fd, "Current txvoice setting on Channel A is %d\n", o->txmixaset);
1487                         else
1488                                 ast_cli(a->fd, "Current txvoice setting on Channel B is %d\n", o->txmixbset);
1489                 } else {
1490                         i = atoi(a->argv[3]);
1491                         if ((i < 0) || (i > 999))
1492                                 return CLI_SHOWUSAGE;
1493
1494                         if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE)) {
1495                                 o->txmixaset = i;
1496                                 ast_cli(a->fd, "Changed txvoice setting on Channel A to %d\n", o->txmixaset);
1497                         } else {
1498                                 o->txmixbset = i;   
1499                                 ast_cli(a->fd, "Changed txvoice setting on Channel B to %d\n", o->txmixbset);
1500                         }
1501                         mixer_write(o);
1502                         mult_set(o);
1503                         ast_cli(a->fd, "Changed Tx Voice Output setting to %d\n", i);
1504                 }
1505                 tune_txoutput(o,i);
1506         } else if (!strcasecmp(a->argv[2], "auxvoice")) {
1507                 i = 0;
1508                 if ( (o->txmixa != TX_OUT_AUX) && (o->txmixb != TX_OUT_AUX))
1509                         ast_log(LOG_WARNING, "No auxvoice output configured.\n");
1510                 else if (a->argc == 3) {
1511                         if (o->txmixa == TX_OUT_AUX)
1512                                 ast_cli(a->fd, "Current auxvoice setting on Channel A is %d\n", o->txmixaset);
1513                         else
1514                                 ast_cli(a->fd, "Current auxvoice setting on Channel B is %d\n", o->txmixbset);
1515                 } else {
1516                         i = atoi(a->argv[3]);
1517                         if ((i < 0) || (i > 999))
1518                                 return CLI_SHOWUSAGE;
1519                         if (o->txmixa == TX_OUT_AUX) {
1520                                 o->txmixbset = i;
1521                                 ast_cli(a->fd, "Changed auxvoice setting on Channel A to %d\n", o->txmixaset);
1522                         } else {
1523                                 o->txmixbset = i;
1524                                 ast_cli(a->fd, "Changed auxvoice setting on Channel B to %d\n", o->txmixbset);
1525                         }
1526                         mixer_write(o);
1527                         mult_set(o);
1528                 }
1529                 /* tune_auxoutput(o,i); */
1530         } else if (!strcasecmp(a->argv[2], "txtone")) {
1531                 if (a->argc == 3)
1532                         ast_cli(a->fd, "Current Tx CTCSS modulation setting = %d\n", o->txctcssadj);
1533                 else {
1534                         i = atoi(a->argv[3]);
1535                         if ((i < 0) || (i > 999))
1536                                 return CLI_SHOWUSAGE;
1537                         o->txctcssadj = i;
1538                         set_txctcss_level(o);
1539                         ast_cli(a->fd, "Changed Tx CTCSS modulation setting to %i\n", i);
1540                 }
1541                 o->txtestkey = 1;
1542                 usleep(5000000);
1543                 o->txtestkey = 0;
1544         } else if (!strcasecmp(a->argv[2],"dump"))
1545                 pmrdump(o);
1546         else if (!strcasecmp(a->argv[2],"nocap")) {
1547                 ast_cli(a->fd, "File capture (trace) was rx=%d tx=%d and now off.\n", o->b.rxcap2, o->b.txcap2);
1548                 ast_cli(a->fd, "File capture (raw)   was rx=%d tx=%d and now off.\n", o->b.rxcapraw, o->b.txcapraw);
1549                 o->b.rxcapraw = o->b.txcapraw = o->b.rxcap2 = o->b.txcap2 = o->pmrChan->b.rxCapture = o->pmrChan->b.txCapture = 0;
1550                 if (frxcapraw) {
1551                         fclose(frxcapraw);
1552                         frxcapraw = NULL;
1553                 }
1554                 if (frxcaptrace) {
1555                         fclose(frxcaptrace);
1556                         frxcaptrace = NULL;
1557                 }
1558                 if (frxoutraw) {
1559                         fclose(frxoutraw);
1560                         frxoutraw = NULL;
1561                 }
1562                 if (ftxcapraw) {
1563                         fclose(ftxcapraw);
1564                         ftxcapraw = NULL;
1565                 }
1566                 if (ftxcaptrace) {
1567                         fclose(ftxcaptrace);
1568                         ftxcaptrace = NULL;
1569                 }
1570                 if (ftxoutraw) {
1571                         fclose(ftxoutraw);
1572                         ftxoutraw = NULL;
1573                 }
1574         } else if (!strcasecmp(a->argv[2], "rxtracecap")) {
1575                 if (!frxcaptrace)
1576                         frxcaptrace = fopen(RX_CAP_TRACE_FILE, "w");
1577                 ast_cli(a->fd, "Trace rx on.\n");
1578                 o->b.rxcap2 = o->pmrChan->b.rxCapture = 1;
1579         } else if (!strcasecmp(a->argv[2], "txtracecap")) {
1580                 if (!ftxcaptrace)
1581                         ftxcaptrace = fopen(TX_CAP_TRACE_FILE, "w");
1582                 ast_cli(a->fd, "Trace tx on.\n");
1583                 o->b.txcap2 = o->pmrChan->b.txCapture = 1;
1584         } else if (!strcasecmp(a->argv[2], "rxcap")) {
1585                 if (!frxcapraw)
1586                         frxcapraw = fopen(RX_CAP_RAW_FILE, "w");
1587                 ast_cli(a->fd, "cap rx raw on.\n");
1588                 o->b.rxcapraw = 1;
1589         } else if (!strcasecmp(a->argv[2], "txcap")) {
1590                 if (!ftxcapraw)
1591                         ftxcapraw = fopen(TX_CAP_RAW_FILE, "w");
1592                 ast_cli(a->fd, "cap tx raw on.\n");
1593                 o->b.txcapraw = 1;
1594         } else if (!strcasecmp(a->argv[2], "save")) {
1595                 tune_write(o);
1596                 ast_cli(a->fd, "Saved radio tuning settings to usbradio_tune.conf\n");
1597         } else
1598                 return CLI_SHOWUSAGE;
1599         return CLI_SUCCESS;
1600 }
1601
1602 /*
1603         set transmit ctcss modulation level
1604         adjust mixer output or internal gain depending on output type
1605         setting range is 0.0 to 0.9
1606 */
1607 static int set_txctcss_level(struct chan_usbradio_pvt *o)
1608 {                                                         
1609         if (o->txmixa == TX_OUT_LSD) {
1610                 o->txmixaset = (151 * o->txctcssadj) / 1000;
1611                 mixer_write(o);
1612                 mult_set(o);
1613         } else if (o->txmixb == TX_OUT_LSD) {
1614                 o->txmixbset = (151 * o->txctcssadj) / 1000;
1615                 mixer_write(o);
1616                 mult_set(o);
1617         } else {
1618                 *o->pmrChan->ptxCtcssAdjust = (o->txctcssadj * M_Q8) / 1000;
1619         }
1620         return 0;
1621 }
1622 /*
1623         CLI debugging on and off
1624 */
1625 static char *handle_cli_radio_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1626 {
1627         struct chan_usbradio_pvt *o = NULL;
1628
1629         switch (cmd) {
1630         case CLI_INIT:
1631                 e->command = "radio set debug [off]";
1632                 e->usage =
1633                         "Usage: radio set debug [off]\n"
1634                         "       Enable/Disable radio debugging.\n";
1635         case CLI_GENERATE:
1636                 return NULL;
1637         }
1638         if (a->argc < 3 || a->argc > 4)
1639                 return CLI_SHOWUSAGE;
1640         if (a->argc == 4 && strncasecmp(a->argv[3], "off", 3))
1641                 return CLI_SHOWUSAGE;
1642
1643         o = find_desc(usbradio_active);
1644
1645         if (a->argc == 3)
1646                 o->debuglevel = 1;
1647         else
1648                 o->debuglevel = 0;
1649
1650         ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
1651
1652         return CLI_SUCCESS;
1653 }
1654
1655 static struct ast_cli_entry cli_usbradio[] = {
1656         AST_CLI_DEFINE(handle_cli_radio_key,       "Simulate Rx Signal Present"),
1657         AST_CLI_DEFINE(handle_cli_radio_unkey,     "Simulate Rx Signal Lusb"),
1658         AST_CLI_DEFINE(handle_cli_radio_tune,      "Radio Tune"),
1659         AST_CLI_DEFINE(handle_cli_radio_set_debug, "Enable/Disable Radio Debugging"),
1660 };
1661
1662 /*
1663  * store the callerid components
1664  */
1665 #if 0
1666 static void store_callerid(struct chan_usbradio_pvt *o, const char *s)
1667 {
1668         ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
1669 }
1670 #endif
1671
1672 static void store_rxdemod(struct chan_usbradio_pvt *o, const char *s)
1673 {
1674         if (!strcasecmp(s, "no")) {
1675                 o->rxdemod = RX_AUDIO_NONE;
1676         } else if (!strcasecmp(s, "speaker")) {
1677                 o->rxdemod = RX_AUDIO_SPEAKER;
1678         } else if (!strcasecmp(s, "flat")) {
1679                         o->rxdemod = RX_AUDIO_FLAT;
1680         } else {
1681                 ast_log(LOG_WARNING, "Unrecognized rxdemod parameter: %s\n", s);
1682         }
1683
1684         ast_debug(4, "set rxdemod = %s\n", s);
1685 }
1686
1687                                            
1688 static void store_txmixa(struct chan_usbradio_pvt *o, const char *s)
1689 {
1690         if (!strcasecmp(s, "no"))
1691                 o->txmixa = TX_OUT_OFF;
1692
1693         else if (!strcasecmp(s, "voice"))
1694                 o->txmixa = TX_OUT_VOICE;
1695         else if (!strcasecmp(s, "tone"))
1696                         o->txmixa = TX_OUT_LSD;
1697         else if (!strcasecmp(s, "composite"))
1698                 o->txmixa = TX_OUT_COMPOSITE;
1699         else if (!strcasecmp(s, "auxvoice"))
1700                 o->txmixb = TX_OUT_AUX;
1701         else
1702                 ast_log(LOG_WARNING, "Unrecognized txmixa parameter: %s\n", s);
1703
1704         ast_debug(4, "set txmixa = %s\n", s);
1705 }
1706
1707 static void store_txmixb(struct chan_usbradio_pvt *o, const char *s)
1708 {
1709         if (!strcasecmp(s, "no"))
1710                 o->txmixb = TX_OUT_OFF;
1711         else if (!strcasecmp(s, "voice"))
1712                 o->txmixb = TX_OUT_VOICE;
1713         else if (!strcasecmp(s, "tone"))
1714                         o->txmixb = TX_OUT_LSD;
1715         else if (!strcasecmp(s, "composite"))
1716                 o->txmixb = TX_OUT_COMPOSITE;
1717         else if (!strcasecmp(s, "auxvoice"))
1718                 o->txmixb = TX_OUT_AUX;
1719         else
1720                 ast_log(LOG_WARNING, "Unrecognized txmixb parameter: %s\n", s);
1721
1722         ast_debug(4, "set txmixb = %s\n", s);
1723 }
1724
1725 static void store_rxcdtype(struct chan_usbradio_pvt *o, const char *s)
1726 {
1727         if (!strcasecmp(s, "no"))
1728                 o->rxcdtype = CD_IGNORE;
1729         else if (!strcasecmp(s, "usb"))
1730                 o->rxcdtype = CD_HID;
1731         else if (!strcasecmp(s, "dsp"))
1732                 o->rxcdtype = CD_XPMR_NOISE;
1733         else if (!strcasecmp(s, "vox"))
1734                 o->rxcdtype = CD_XPMR_VOX;
1735         else if (!strcasecmp(s, "usbinvert"))
1736                 o->rxcdtype = CD_HID_INVERT;
1737         else
1738                 ast_log(LOG_WARNING, "Unrecognized rxcdtype parameter: %s\n", s);
1739
1740         ast_debug(4, "set rxcdtype = %s\n", s);
1741 }
1742
1743 static void store_rxsdtype(struct chan_usbradio_pvt *o, const char *s)
1744 {
1745         if (!strcasecmp(s, "no") || !strcasecmp(s, "SD_IGNORE"))
1746                 o->rxsdtype = SD_IGNORE;
1747         else if (!strcasecmp(s, "usb") || !strcasecmp(s, "SD_HID"))
1748                 o->rxsdtype = SD_HID;
1749         else if (!strcasecmp(s, "usbinvert") || !strcasecmp(s, "SD_HID_INVERT"))
1750                 o->rxsdtype = SD_HID_INVERT;
1751         else if (!strcasecmp(s, "software") || !strcasecmp(s, "SD_XPMR"))
1752                 o->rxsdtype = SD_XPMR;
1753         else
1754                 ast_log(LOG_WARNING, "Unrecognized rxsdtype parameter: %s\n", s);
1755
1756         ast_debug(4, "set rxsdtype = %s\n", s);
1757 }
1758
1759 static void store_rxgain(struct chan_usbradio_pvt *o, const char *s)
1760 {
1761         float f;
1762         if (sscanf(s, "%f", &f) == 1)
1763                 o->rxgain = f;
1764         ast_debug(4, "set rxgain = %f\n", f);
1765 }
1766
1767 static void store_rxvoiceadj(struct chan_usbradio_pvt *o, const char *s)
1768 {
1769         float f;
1770         if (sscanf(s, "%f", &f) == 1)
1771                 o->rxvoiceadj = f;
1772         ast_debug(4, "set rxvoiceadj = %f\n", f);
1773 }
1774
1775 static void store_rxctcssadj(struct chan_usbradio_pvt *o, const char *s)
1776 {
1777         float f;
1778         if (sscanf(s, "%f", &f) == 1)
1779                 o->rxctcssadj = f;
1780         ast_debug(4, "set rxctcssadj = %f\n", f);
1781 }
1782
1783 static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s)
1784 {
1785         if (!strcasecmp(s, "no") || !strcasecmp(s, "TOC_NONE"))
1786                 o->txtoctype = TOC_NONE;
1787         else if (!strcasecmp(s, "phase") || !strcasecmp(s, "TOC_PHASE"))
1788                 o->txtoctype = TOC_PHASE;
1789         else if (!strcasecmp(s, "notone") || !strcasecmp(s, "TOC_NOTONE"))
1790                 o->txtoctype = TOC_NOTONE;
1791         else
1792                 ast_log(LOG_WARNING, "Unrecognized txtoctype parameter: %s\n", s);
1793
1794         ast_debug(4, "set txtoctype = %s\n", s);
1795 }
1796
1797 static void store_rxctcssfreq(struct chan_usbradio_pvt *o, const char *s)
1798 {
1799         float f;
1800         if (sscanf(s, "%f", &f) == 1)
1801                 o->rxctcssfreq = f;
1802         ast_debug(4, "set rxctcss = %f\n", f);
1803 }
1804
1805 static void store_txctcssfreq(struct chan_usbradio_pvt *o, const char *s)
1806 {
1807         float f;
1808         if (sscanf(s, "%f", &f) == 1)
1809                 o->txctcssfreq = f;
1810         ast_debug(4, "set txctcss = %f\n", f);
1811 }
1812
1813 static void tune_txoutput(struct chan_usbradio_pvt *o, int value)
1814 {
1815         o->txtestkey = 1;
1816         o->pmrChan->txPttIn = 1;
1817
1818 #if 0
1819         /* generate 1KHz tone at 7200 peak */
1820         o->pmrChan->spsSigGen1->freq = 10000;
1821         o->pmrChan->spsSigGen1->outputGain = (float)(0.22 * M_Q8);
1822         o->pmrChan->b.startSpecialTone = 1;
1823 #endif
1824
1825         TxTestTone(o->pmrChan, 1);
1826
1827         usleep(5000000);
1828         /* o->pmrChan->b.stopSpecialTone = 1; */
1829         usleep(100000);
1830
1831         TxTestTone(o->pmrChan, 0);
1832
1833         o->pmrChan->txPttIn = 0;
1834         o->txtestkey = 0;
1835 }
1836
1837 static void tune_rxinput(struct chan_usbradio_pvt *o)
1838 {
1839         const int target = 23000;
1840         const int tolerance = 2000;
1841         const int settingmin = 1;
1842         const int settingstart = 2;
1843         const int maxtries = 12;
1844
1845         float settingmax;
1846         
1847         int setting = 0, tries = 0, tmpdiscfactor, meas;
1848         int tunetype = 0;
1849
1850         settingmax = o->micmax;
1851
1852         if (o->pmrChan->rxDemod)
1853                 tunetype = 1;
1854
1855         setting = settingstart;
1856
1857         while (tries < maxtries) {
1858                 setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL, setting, 0);
1859                 setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
1860                 usleep(100000);
1861                 if (o->rxcdtype == CD_XPMR_VOX || o->rxdemod == RX_AUDIO_SPEAKER) {
1862                         ast_debug(4, "Measure Direct Input\n");
1863                         o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
1864                         o->pmrChan->spsMeasure->discfactor = 1000;
1865                         o->pmrChan->spsMeasure->enabled = 1;
1866                         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
1867                         usleep(400000); 
1868                         meas = o->pmrChan->spsMeasure->apeak;
1869                         o->pmrChan->spsMeasure->enabled = 0;    
1870                 } else {
1871                         ast_debug(4, "Measure HF Noise\n");
1872                         tmpdiscfactor = o->pmrChan->spsRx->discfactor;
1873                         o->pmrChan->spsRx->discfactor = (i16)1000;
1874                         o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
1875                         o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
1876                         usleep(200000);
1877                         meas = o->pmrChan->rxRssi;
1878                         o->pmrChan->spsRx->discfactor = tmpdiscfactor;
1879                         o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
1880                         o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
1881                 }
1882         if (!meas)
1883                         meas++;
1884                 ast_log(LOG_NOTICE, "tries=%d, setting=%d, meas=%i\n", tries, setting, meas);
1885
1886                 if ( meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
1887                         setting = setting * target / meas;
1888                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance) )
1889                         break;
1890
1891                 if (setting < settingmin)
1892                         setting = settingmin;
1893                 else if (setting > settingmax)
1894                         setting = settingmax;
1895
1896                 tries++;
1897         }
1898         ast_log(LOG_NOTICE, "DONE tries=%d, setting=%d, meas=%i\n", tries,
1899                 (setting * 1000) / o->micmax, meas);
1900         if (meas < (target - tolerance) || meas > (target + tolerance))
1901                 ast_log(LOG_NOTICE, "ERROR: RX INPUT ADJUST FAILED.\n");
1902         else {
1903                 ast_log(LOG_NOTICE, "INFO: RX INPUT ADJUST SUCCESS.\n");        
1904                 o->rxmixerset = (setting * 1000) / o->micmax;
1905         }
1906 }
1907 /*
1908 */
1909 static void tune_rxvoice(struct chan_usbradio_pvt *o)
1910 {
1911         const int target = 7200;        /* peak */
1912         const int tolerance = 360;      /* peak to peak */
1913         const float settingmin = 0.1;
1914         const float settingmax = 4;
1915         const float settingstart = 1;
1916         const int maxtries = 12;
1917
1918         float setting;
1919
1920         int tries = 0, meas;
1921
1922         ast_log(LOG_NOTICE, "INFO: RX VOICE ADJUST START.\n");  
1923         ast_log(LOG_NOTICE, "target=%d tolerance=%d\n", target, tolerance);
1924
1925         if (!o->pmrChan->spsMeasure)
1926                 ast_log(LOG_ERROR, "NO MEASURE BLOCK.\n");
1927
1928         if (!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
1929                 ast_log(LOG_ERROR, "NO SOURCE OR MEASURE SETTING.\n");
1930
1931         o->pmrChan->spsMeasure->source = o->pmrChan->spsRxOut->sink;
1932         o->pmrChan->spsMeasure->enabled = 1;
1933         o->pmrChan->spsMeasure->discfactor = 1000;
1934
1935         setting=settingstart;
1936
1937         ast_debug(4, "ERROR: NO MEASURE BLOCK.\n");
1938
1939         while (tries < maxtries) {
1940                 *(o->pmrChan->prxVoiceAdjust) = setting * M_Q8;
1941                 usleep(10000);
1942         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
1943                 usleep(1000000);
1944                 meas = o->pmrChan->spsMeasure->apeak;
1945                 ast_log(LOG_NOTICE, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
1946
1947                 if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
1948                         setting = setting * target / meas;
1949                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
1950                         break;
1951                 if (setting < settingmin)
1952                         setting = settingmin;
1953                 else if (setting > settingmax)
1954                         setting = settingmax;
1955
1956                 tries++;
1957         }
1958
1959         o->pmrChan->spsMeasure->enabled = 0;
1960
1961         ast_log(LOG_NOTICE, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
1962         if (meas < (target - tolerance) || meas > (target + tolerance))
1963                 ast_log(LOG_ERROR, "RX VOICE GAIN ADJUST FAILED.\n");
1964         else {
1965                 ast_log(LOG_NOTICE, "RX VOICE GAIN ADJUST SUCCESS.\n");
1966                 o->rxvoiceadj = setting;
1967         }
1968 }
1969
1970 static void tune_rxctcss(struct chan_usbradio_pvt *o)
1971 {
1972         const int target = 4096;
1973         const int tolerance = 100;
1974         const float settingmin = 0.1;
1975         const float settingmax = 4;
1976         const float settingstart = 1;
1977         const int maxtries = 12;
1978
1979         float setting;
1980         int tries = 0, meas;
1981
1982         ast_log(LOG_NOTICE, "RX CTCSS ADJUST START.\n");        
1983         ast_log(LOG_NOTICE, "target=%d tolerance=%d \n", target, tolerance);
1984
1985         o->pmrChan->spsMeasure->source = o->pmrChan->prxCtcssMeasure;
1986         o->pmrChan->spsMeasure->discfactor = 400;
1987         o->pmrChan->spsMeasure->enabled = 1;
1988
1989         setting = settingstart;
1990
1991         while (tries < maxtries) {
1992                 *(o->pmrChan->prxCtcssAdjust) = setting * M_Q8;
1993                 usleep(10000);
1994         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
1995                 usleep(500000);
1996                 meas = o->pmrChan->spsMeasure->apeak;
1997                 ast_debug(4, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
1998
1999                 if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
2000                         setting = setting * target / meas;
2001                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
2002                         break;
2003                 if (setting < settingmin)
2004                         setting = settingmin;
2005                 else if (setting > settingmax)
2006                         setting = settingmax;
2007
2008                 tries++;
2009         }
2010         o->pmrChan->spsMeasure->enabled = 0;
2011         ast_debug(4, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
2012         if (meas < (target - tolerance) || meas > (target + tolerance))
2013                 ast_log(LOG_ERROR, "RX CTCSS GAIN ADJUST FAILED.\n");
2014         else {
2015                 ast_log(LOG_NOTICE, "RX CTCSS GAIN ADJUST SUCCESS.\n");
2016                 o->rxctcssadj = setting;
2017         }
2018 }
2019 /*
2020         this file then is included in chan_usbradio.conf
2021         #include /etc/asterisk/usbradio_tune.conf 
2022 */
2023 static void tune_write(struct chan_usbradio_pvt *o)
2024 {
2025         FILE *fp;
2026         
2027         fp = fopen("/etc/asterisk/usbradio_tune.conf", "w");
2028  
2029         if (!strcmp(o->name, "dsp"))
2030                 fprintf(fp, "[general]\n");
2031         else
2032                 fprintf(fp, "[%s]\n", o->name);
2033
2034         fprintf(fp, "; name=%s\n", o->name);
2035         fprintf(fp, "; devicenum=%d\n", o->devicenum);
2036
2037         fprintf(fp, "rxmixerset=%d\n", o->rxmixerset);
2038         fprintf(fp, "rxboostset=%d\n", o->rxboostset);
2039         fprintf(fp, "txmixaset=%d\n", o->txmixaset);
2040         fprintf(fp, "txmixbset=%d\n", o->txmixbset);
2041
2042         fprintf(fp, "rxvoiceadj=%f\n", o->rxvoiceadj);
2043         fprintf(fp, "rxctcssadj=%f\n", o->rxctcssadj);
2044         fprintf(fp, "txctcssadj=%d\n", o->txctcssadj);
2045
2046         fprintf(fp, "rxsquelchadj=%d\n", o->rxsquelchadj);
2047         fclose(fp);
2048 }
2049
2050 static void mixer_write(struct chan_usbradio_pvt *o)
2051 {
2052         setamixer(o->devicenum, MIXER_PARAM_MIC_PLAYBACK_SW, 0, 0);
2053         setamixer(o->devicenum, MIXER_PARAM_MIC_PLAYBACK_VOL, 0, 0);
2054         setamixer(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_SW, 1, 0);
2055         setamixer(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL,
2056                 o->txmixaset * o->spkrmax / 1000,
2057                 o->txmixbset * o->spkrmax / 1000);
2058         setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL,
2059                 o->rxmixerset * o->micmax / 1000, 0);
2060         setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
2061         setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_SW, 1, 0);
2062 }
2063 /*
2064         adjust dsp multiplier to add resolution to tx level adjustment
2065 */
2066 static void mult_set(struct chan_usbradio_pvt *o)
2067 {
2068
2069         if (o->pmrChan->spsTxOutA) {
2070                 o->pmrChan->spsTxOutA->outputGain = 
2071                         mult_calc((o->txmixaset * 152) / 1000);
2072         }
2073         if (o->pmrChan->spsTxOutB) {
2074                 o->pmrChan->spsTxOutB->outputGain = 
2075                         mult_calc((o->txmixbset * 152) / 1000);
2076         }
2077 }
2078 /*
2079  * input 0 - 151 outputs are pot and multiplier
2080  */
2081 static int mult_calc(int value)
2082 {
2083         const int multx = M_Q8;
2084         int pot, mult;
2085
2086         pot= ((int)(value / 4) * 4) + 2;
2087         mult = multx - ((multx * (3 - (value % 4))) / (pot + 2));
2088         return mult;
2089 }
2090
2091 #define pd(x) ast_debug(4, #x" = %d\n", x)
2092 #define pp(x) ast_debug(4, #x" = %p\n", x)
2093 #define ps(x) ast_debug(4, #x" = %s\n", x)
2094 #define pf(x) ast_debug(4, #x" = %f\n", x)
2095 /*
2096 */
2097 static void pmrdump(struct chan_usbradio_pvt *o)
2098 {
2099         t_pmr_chan *p;
2100
2101         p = o->pmrChan;
2102
2103         ast_debug(4, "odump()\n");
2104
2105         pd(o->devicenum);
2106
2107         pd(o->rxdemod);
2108         pd(o->rxcdtype);
2109         pd(o->rxsdtype);
2110         pd(o->txtoctype);
2111
2112         pd(o->rxmixerset);
2113         pf(o->rxvoiceadj);
2114         pf(o->rxctcssadj);
2115         pd(o->rxsquelchadj);
2116          
2117         pd(o->txprelim);
2118         pd(o->txmixa);
2119         pd(o->txmixb);
2120         
2121         pd(o->txmixaset);
2122         pd(o->txmixbset);
2123         
2124         ast_debug(4, "pmrdump()\n");
2125  
2126         ast_debug(4, "prxSquelchAdjust=%d\n", *(o->pmrChan->prxSquelchAdjust));
2127
2128         pd(p->rxCarrierPoint);
2129         pd(p->rxCarrierHyst);
2130
2131         pd(p->rxCtcss->relax);
2132         pf(p->rxCtcssFreq);     
2133         pd(p->rxCtcssIndex);
2134         pf(p->txCtcssFreq);
2135
2136         pd(p->txMixA);
2137         pd(p->txMixB);
2138     
2139         pd(p->rxDeEmpEnable);
2140         pd(p->rxCenterSlicerEnable);
2141         pd(p->rxCtcssDecodeEnable);
2142         pd(p->rxDcsDecodeEnable);
2143
2144         pd(p->txHpfEnable);
2145         pd(p->txLimiterEnable);
2146         pd(p->txPreEmpEnable);
2147         pd(p->txLpfEnable);
2148
2149         if (p->spsTxOutA)
2150                 pd(p->spsTxOutA->outputGain);
2151         if (p->spsTxOutB)
2152                 pd(p->spsTxOutB->outputGain);
2153
2154         return;
2155 }
2156
2157
2158 /*
2159  * grab fields from the config file, init the descriptor and open the device.
2160  */
2161 static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
2162 {
2163         struct ast_variable *v;
2164         struct chan_usbradio_pvt *o;
2165         struct ast_config *cfg1;
2166         struct ast_flags config_flags = { 0 };
2167
2168         if (ctg == NULL) {
2169                 traceusb1(" store_config() ctg == NULL\n");
2170                 o = &usbradio_default;
2171                 ctg = "general";
2172         } else {
2173                 if (!(o = ast_calloc(1, sizeof(*o)))){
2174                         return NULL;
2175                 }
2176                 *o = usbradio_default;
2177                 /* "general" is also the default thing */
2178                 if (strcmp(ctg, "general") == 0) {
2179                         o->name = ast_strdup("dsp");
2180                         usbradio_active = o->name;
2181                 } else
2182                         o->name = ast_strdup(ctg);
2183         }
2184
2185         strcpy(o->mohinterpret, "default");
2186         o->micmax = amixer_max(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL);
2187         o->spkrmax = amixer_max(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL);
2188         /* fill other fields from configuration */
2189         for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
2190
2191                 /* handle jb conf */
2192                 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
2193                         continue;
2194                 CV_START(v->name, v->value);
2195
2196                 CV_UINT("frags", o->frags);
2197                 CV_UINT("queuesize", o->queuesize);
2198                 CV_UINT("devicenum", o->devicenum);
2199                 CV_UINT("debug", usbradio_debug);
2200                 CV_BOOL("rxcpusaver", o->rxcpusaver);
2201                 CV_BOOL("txcpusaver", o->txcpusaver);
2202                 CV_BOOL("invertptt", o->invertptt);
2203                 CV_F("rxdemod", store_rxdemod(o, v->value));
2204                 CV_BOOL("txprelim", o->txprelim);;
2205                 CV_F("txmixa", store_txmixa(o, v->value));
2206                 CV_F("txmixb", store_txmixb(o, v->value));
2207                 CV_F("carrierfrom", store_rxcdtype(o, v->value));
2208                 CV_F("rxsdtype", store_rxsdtype(o, v->value));
2209                 CV_F("rxctcssfreq", store_rxctcssfreq(o, v->value));
2210                 CV_F("txctcssfreq", store_txctcssfreq(o, v->value));
2211                 CV_F("rxgain", store_rxgain(o, v->value));
2212                 CV_BOOL("rxboostset", o->rxboostset);
2213                 CV_UINT("rxctcssrelax", o->rxctcssrelax);
2214                 CV_F("txtoctype", store_txtoctype(o, v->value));
2215                 CV_UINT("hdwtype", o->hdwtype);
2216                 CV_UINT("duplex", o->radioduplex);
2217
2218                 CV_END;
2219         }
2220         
2221         cfg1 = ast_config_load(config1, config_flags);
2222         if (!cfg1) {
2223                 o->rxmixerset = 500;
2224                 o->txmixaset = 500;
2225                 o->txmixbset = 500;
2226                 o->rxvoiceadj = 0.5;
2227                 o->rxctcssadj = 0.5;
2228                 o->txctcssadj = 200;
2229                 o->rxsquelchadj = 500;
2230                 ast_log(LOG_WARNING, "File %s not found, using default parameters.\n", config1);
2231         } else  {
2232                 for (v = ast_variable_browse(cfg1, ctg); v; v = v->next) {
2233         
2234                         CV_START(v->name, v->value);
2235                         CV_UINT("rxmixerset", o->rxmixerset);
2236                         CV_UINT("txmixaset", o->txmixaset);
2237                         CV_UINT("txmixbset", o->txmixbset);
2238                         CV_F("rxvoiceadj", store_rxvoiceadj(o, v->value));
2239                         CV_F("rxctcssadj", store_rxctcssadj(o, v->value));
2240                         CV_UINT("txctcssadj", o->txctcssadj);
2241                         CV_UINT("rxsquelchadj", o->rxsquelchadj);
2242                         CV_END;
2243                 }
2244                 ast_config_destroy(cfg1);
2245         }
2246
2247         o->debuglevel = 0;
2248
2249         if (o == &usbradio_default)             /* we are done with the default */
2250                 return NULL;
2251
2252         o->lastopen = ast_tvnow();      /* don't leave it 0 or tvdiff may wrap */
2253         o->dsp = ast_dsp_new();
2254         if (o->dsp) {
2255                 ast_dsp_set_features(o->dsp, DSP_FEATURE_DTMF_DETECT);
2256                 ast_dsp_digitmode(o->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
2257         }
2258
2259         if (o->rxctcssfreq != 0 && o->rxdemod == RX_AUDIO_SPEAKER)
2260                 ast_log(LOG_ERROR, "Incompatable Options  o->rxctcssfreq=%f and o->rxdemod=speaker\n", o->rxctcssfreq); 
2261
2262         if (o->pmrChan == NULL) {
2263                 t_pmr_chan tChan;
2264
2265                 memset(&tChan, 0, sizeof(tChan));
2266
2267                 tChan.rxDemod = o->rxdemod;
2268                 tChan.rxCdType = o->rxcdtype;
2269
2270                 tChan.txMod = o->txprelim;
2271
2272                 tChan.txMixA = o->txmixa;
2273                 tChan.txMixB = o->txmixb;
2274
2275                 tChan.rxCpuSaver = o->rxcpusaver;
2276                 tChan.txCpuSaver = o->txcpusaver;
2277
2278                 tChan.rxCtcssFreq = o->rxctcssfreq;
2279                 tChan.txCtcssFreq = o->txctcssfreq;
2280
2281                 o->pmrChan = createPmrChannel(&tChan, FRAME_SIZE);
2282
2283                 o->pmrChan->radioDuplex = o->radioduplex;
2284
2285                 o->pmrChan->rxCpuSaver = o->rxcpusaver;
2286                 o->pmrChan->txCpuSaver = o->txcpusaver;
2287
2288                 *(o->pmrChan->prxSquelchAdjust) = 
2289                         ((999 - o->rxsquelchadj) * 32767) / 1000;
2290
2291                 o->pmrChan->spsRx->outputGain = o->rxvoiceadj*M_Q8;
2292
2293                 o->pmrChan->txTocType = o->txtoctype;
2294
2295                 if ((o->txmixa == TX_OUT_LSD) ||
2296                         (o->txmixa == TX_OUT_COMPOSITE) ||
2297                         (o->txmixb == TX_OUT_LSD) ||
2298                         (o->txmixb == TX_OUT_COMPOSITE)) {
2299                         *(o->pmrChan->prxCtcssAdjust) = o->rxctcssadj * M_Q8;
2300                         set_txctcss_level(o);
2301                 }
2302
2303                 o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
2304
2305         }
2306
2307         if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
2308                 (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE))
2309                 ast_log(LOG_ERROR, "No txvoice output configured.\n");
2310
2311         if (o->txctcssfreq && 
2312             o->txmixa != TX_OUT_LSD && o->txmixa != TX_OUT_COMPOSITE  &&
2313                 o->txmixb != TX_OUT_LSD && o->txmixb != TX_OUT_COMPOSITE)
2314                 ast_log(LOG_ERROR, "No txtone output configured.\n");
2315
2316         if (o->rxctcssfreq && o->pmrChan->rxCtcssIndex < 0)
2317                 ast_log(LOG_ERROR, "Invalid CTCSS Frequency.\n");
2318
2319         /* RxTestIt(o); */
2320
2321         mixer_write(o);
2322         mult_set(o);    
2323         hidhdwconfig(o);
2324
2325         /* pmrdump(o); */
2326
2327         /* link into list of devices */
2328         if (o != &usbradio_default) {
2329                 o->next = usbradio_default.next;
2330                 usbradio_default.next = o;
2331         }
2332         return o;
2333 }
2334
2335 #if     DEBUG_FILETEST == 1
2336 /*
2337         Test It on a File
2338 */
2339 int RxTestIt(struct chan_usbradio_pvt *o)
2340 {
2341         const int numSamples = SAMPLES_PER_BLOCK;
2342         const int numChannels = 16;
2343
2344         i16 sample, i, ii;
2345         
2346         i32 txHangTime;
2347
2348         i16 txEnable;
2349
2350         t_pmr_chan tChan;
2351         t_pmr_chan *pChan;
2352
2353         FILE *hInput = NULL, *hOutput = NULL, *hOutputTx = NULL;
2354  
2355         i16 iBuff[numSamples * 2 * 6], oBuff[numSamples];
2356
2357         ast_debug(4, "RxTestIt()\n");
2358
2359         pChan = o->pmrChan;
2360         pChan->b.txCapture = 1;
2361         pChan->b.rxCapture = 1;
2362
2363         txEnable = 0;
2364
2365         hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm", "r");
2366         if (!hInput){
2367                 ast_debug(4, " RxTestIt() File Not Found.\n");
2368                 return 0;
2369         }
2370         hOutput = fopen("/usr/src/xpmr/testdata/rx_debug.pcm", "w");
2371
2372         ast_debug(4, " RxTestIt() Working...\n");
2373                                 
2374         while (!feof(hInput)) {
2375                 fread((void *)iBuff, 2, numSamples * 2 * 6, hInput);
2376                  
2377                 if (txHangTime)
2378                         txHangTime -= numSamples;
2379                 if (txHangTime < 0)
2380                         txHangTime = 0;
2381                 
2382                 if (pChan->rxCtcss->decode)
2383                         txHangTime = (8000 / 1000 * 2000);
2384
2385                 if (pChan->rxCtcss->decode && !txEnable) {
2386                         txEnable = 1;
2387                         /* pChan->inputBlanking = (8000 / 1000 * 200); */
2388                 } else if (!pChan->rxCtcss->decode && txEnable) {
2389                         txEnable = 0;
2390                 }
2391
2392                 PmrRx(pChan, iBuff, oBuff);
2393
2394                 fwrite((void *)pChan->prxDebug, 2, numSamples * numChannels, hOutput);
2395         }
2396         pChan->b.txCapture = 0;
2397         pChan->b.rxCapture = 0;
2398
2399         if (hInput)
2400                 fclose(hInput);
2401         if (hOutput)
2402                 fclose(hOutput);
2403
2404         ast_debug(4, " RxTestIt() Complete.\n");
2405
2406         return 0;
2407 }
2408 #endif
2409
2410 #include "./xpmr/xpmr.c"
2411 /*
2412 */
2413 static int load_module(void)
2414 {
2415         struct ast_config *cfg = NULL;
2416         char *ctg = NULL;
2417         struct ast_flags config_flags = { 0 };
2418
2419         /* Copy the default jb config over global_jbconf */
2420         memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2421
2422         /* load config file */
2423         if (!(cfg = ast_config_load(config, config_flags))) {
2424                 ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
2425                 return AST_MODULE_LOAD_DECLINE;
2426         }
2427
2428         do {
2429                 store_config(cfg, ctg);
2430         } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
2431
2432         ast_config_destroy(cfg);
2433
2434         if (find_desc(usbradio_active) == NULL) {
2435                 ast_log(LOG_NOTICE, "Device %s not found\n", usbradio_active);
2436                 /* XXX we could default to 'dsp' perhaps ? */
2437                 /* XXX should cleanup allocated memory etc. */
2438                 return AST_MODULE_LOAD_FAILURE;
2439         }
2440
2441         if (ast_channel_register(&usbradio_tech)) {
2442                 ast_log(LOG_ERROR, "Unable to register channel type 'usb'\n");
2443                 return AST_MODULE_LOAD_FAILURE;
2444         }
2445
2446         ast_cli_register_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
2447
2448         return AST_MODULE_LOAD_SUCCESS;
2449 }
2450 /*
2451 */
2452 static int unload_module(void)
2453 {
2454         struct chan_usbradio_pvt *o;
2455
2456         ast_log(LOG_WARNING, "unload_module() called\n");
2457
2458         ast_channel_unregister(&usbradio_tech);
2459         ast_cli_unregister_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
2460
2461         for (o = usbradio_default.next; o; o = o->next) {
2462
2463                 ast_log(LOG_WARNING, "destroyPmrChannel() called\n");
2464                 if (o->pmrChan)
2465                         destroyPmrChannel(o->pmrChan);
2466                 
2467                 #if DEBUG_CAPTURES == 1
2468                 if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
2469                 if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
2470                 if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
2471                 if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
2472                 if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
2473                 if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
2474                 #endif
2475
2476                 close(o->sounddev);
2477                 if (o->dsp)
2478                         ast_dsp_free(o->dsp);
2479                 if (o->owner)
2480                         ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
2481                 if (o->owner)                   /* XXX how ??? */
2482                         return -1;
2483                 /* XXX what about the thread ? */
2484                 /* XXX what about the memory allocated ? */
2485         }
2486         return 0;
2487 }
2488
2489 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "usb Console Channel Driver");
2490
2491 /*      end of file */
2492
2493