9ebfa44e80af0506a0fe17cefad9766a6eada7c7
[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                                 if (option_verbose > 1)
884                                         ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
885                                 o->duplex = M_FULL;
886                         };
887                         break;
888                 case O_WRONLY:
889                         o->duplex = M_WRITE;
890                         break;
891                 case O_RDONLY:
892                         o->duplex = M_READ;
893                         break;
894         }
895
896         fmt = 1;
897         res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
898         if (res < 0) {
899                 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
900                 return -1;
901         }
902         fmt = desired = 48000;                                                  /* 8000 Hz desired */
903         res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
904
905         if (res < 0) {
906                 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
907                 return -1;
908         }
909         if (fmt != desired) {
910                 if (!(o->warned & WARN_speed)) {
911                         ast_log(LOG_WARNING,
912                             "Requested %d Hz, got %d Hz -- sound may be choppy\n",
913                             desired, fmt);
914                         o->warned |= WARN_speed;
915                 }
916         }
917         /*
918          * on Freebsd, SETFRAGMENT does not work very well on some cards.
919          * Default to use 256 bytes, let the user override
920          */
921         if (o->frags) {
922                 fmt = o->frags;
923                 res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
924                 if (res < 0) {
925                         if (!(o->warned & WARN_frag)) {
926                                 ast_log(LOG_WARNING,
927                                         "Unable to set fragment size -- sound may be choppy\n");
928                                 o->warned |= WARN_frag;
929                         }
930                 }
931         }
932         /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
933         res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
934         res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
935         /* it may fail if we are in half duplex, never mind */
936         return 0;
937 }
938
939 /*
940  * some of the standard methods supported by channels.
941  */
942 static int usbradio_digit_begin(struct ast_channel *c, char digit)
943 {
944         return 0;
945 }
946
947 static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration)
948 {
949         /* no better use for received digits than print them */
950         ast_verbose(" << Console Received digit %c of duration %u ms >> \n", 
951                 digit, duration);
952         return 0;
953 }
954
955 static int usbradio_text(struct ast_channel *c, const char *text)
956 {
957         /* print received messages */
958         ast_verbose(" << Console Received text %s >> \n", text);
959         return 0;
960 }
961
962 /*
963  * handler for incoming calls. Either autoanswer, or start ringing
964  */
965 static int usbradio_call(struct ast_channel *c, char *dest, int timeout)
966 {
967         struct chan_usbradio_pvt *o = c->tech_pvt;
968
969         time(&o->lasthidtime);
970         ast_pthread_create_background(&o->hidthread, NULL, hidthread, o);
971         ast_setstate(c, AST_STATE_UP);
972         return 0;
973 }
974
975 /*
976  * remote side answered the phone
977  */
978 static int usbradio_answer(struct ast_channel *c)
979 {
980         ast_setstate(c, AST_STATE_UP);
981
982         return 0;
983 }
984
985 static int usbradio_hangup(struct ast_channel *c)
986 {
987         struct chan_usbradio_pvt *o = c->tech_pvt;
988
989         c->tech_pvt = NULL;
990         o->owner = NULL;
991         ast_module_unref(ast_module_info->self);
992         if (o->hookstate) {
993                 if (o->autoanswer || o->autohangup) {
994                         /* Assume auto-hangup too */
995                         o->hookstate = 0;
996                         setformat(o, O_CLOSE);
997                 }
998         }
999         o->stophid = 1;
1000         pthread_join(o->hidthread, NULL);
1001         return 0;
1002 }
1003
1004
1005 /* used for data coming from the network */
1006 static int usbradio_write(struct ast_channel *c, struct ast_frame *f)
1007 {
1008         int src,datalen;
1009         struct chan_usbradio_pvt *o = c->tech_pvt;
1010
1011         traceusb2("usbradio_write() o->nosound=%d\n", o->nosound);      /*sph maw asdf */
1012
1013         /*
1014          * we could receive a block which is not a multiple of our
1015          * FRAME_SIZE, so buffer it locally and write to the device
1016          * in FRAME_SIZE chunks.
1017          * Keep the residue stored for future use.
1018          */
1019
1020         if (o->txkeyed || o->txtestkey)
1021                 o->pmrChan->txPttIn = 1;
1022         else
1023                 o->pmrChan->txPttIn = 0;
1024
1025         #if DEBUG_CAPTURES == 1 /* to write input data to a file   datalen=320 */
1026         if (ftxcapraw && o->b.txcapraw) {
1027                 i16 i, tbuff[f->datalen];
1028                 for (i = 0; i < f->datalen; i += 2) {
1029                         tbuff[i] = ((i16 *)(f->data))[i / 2];
1030                         tbuff[i + 1] = o->txkeyed * M_Q13;
1031                 }
1032                 fwrite(tbuff, 2, f->datalen, ftxcapraw);
1033                 /*fwrite(f->data,1,f->datalen,ftxcapraw); */
1034         }
1035         #endif
1036
1037         PmrTx(o->pmrChan,(i16*)f->data,(i16*)o->usbradio_write_buf_1);
1038
1039         #if 0   /* to write 48KS/s stereo data to a file */
1040         if (!ftxoutraw) ftxoutraw = fopen(TX_CAP_OUT_FILE,"w");
1041         if (ftxoutraw) fwrite(o->usbradio_write_buf_1,1,f->datalen * 2 * 6,ftxoutraw);
1042         #endif
1043
1044         #if DEBUG_CAPTURES == 1
1045     if (o->b.txcap2 && ftxcaptrace)
1046                 fwrite((o->pmrChan->ptxDebug), 1, FRAME_SIZE * 2 * 16, ftxcaptrace);
1047         #endif
1048
1049         src = 0;                                        /* read position into f->data */
1050         datalen = f->datalen * 12;
1051         while (src < datalen) {
1052                 /* Compute spare room in the buffer */
1053                 int l = sizeof(o->usbradio_write_buf) - o->usbradio_write_dst;
1054
1055                 if (datalen - src >= l) {       /* enough to fill a frame */
1056                         memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
1057                         soundcard_writeframe(o, (short *) o->usbradio_write_buf);
1058                         src += l;
1059                         o->usbradio_write_dst = 0;
1060                 } else {                                /* copy residue */
1061                         l = datalen - src;
1062                         memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
1063                         src += l;                       /* but really, we are done */
1064                         o->usbradio_write_dst += l;
1065                 }
1066         }
1067         return 0;
1068 }
1069
1070 static struct ast_frame *usbradio_read(struct ast_channel *c)
1071 {
1072         int res;
1073         struct chan_usbradio_pvt *o = c->tech_pvt;
1074         struct ast_frame *f = &o->read_f, *f1;
1075         struct ast_frame wf = { AST_FRAME_CONTROL };
1076         time_t now;
1077
1078         traceusb2("usbradio_read()\n"); /* sph maw asdf */
1079
1080         if (o->lasthidtime) {
1081                 time(&now);
1082                 if ((now - o->lasthidtime) > 3) {
1083                         ast_log(LOG_ERROR, "HID process has died or something!!\n");
1084                         return NULL;
1085                 }
1086         }
1087         if (o->lastrx && (!o->rxkeyed)) {
1088                 o->lastrx = 0;
1089                 wf.subclass = AST_CONTROL_RADIO_UNKEY;
1090                 ast_queue_frame(o->owner, &wf);
1091         } else if ((!o->lastrx) && (o->rxkeyed)) {
1092                 o->lastrx = 1;
1093                 wf.subclass = AST_CONTROL_RADIO_KEY;
1094                 ast_queue_frame(o->owner, &wf);
1095         }
1096         /* XXX can be simplified returning &ast_null_frame */
1097         /* prepare a NULL frame in case we don't have enough data to return */
1098         memset(f, 0, sizeof(struct ast_frame));
1099         f->frametype = AST_FRAME_NULL;
1100         f->src = usbradio_tech.type;
1101
1102         res = read(o->sounddev, o->usbradio_read_buf + o->readpos, 
1103                 sizeof(o->usbradio_read_buf) - o->readpos);
1104         if (res < 0)                            /* audio data not ready, return a NULL frame */
1105                 return f;
1106
1107         o->readpos += res;
1108         if (o->readpos < sizeof(o->usbradio_read_buf))  /* not enough samples */
1109                 return f;
1110
1111         if (o->mute)
1112                 return f;
1113
1114         #if DEBUG_CAPTURES == 1
1115         if (o->b.rxcapraw && frxcapraw)
1116                 fwrite((o->usbradio_read_buf + AST_FRIENDLY_OFFSET), 1, FRAME_SIZE * 2 * 2 * 6, frxcapraw);
1117         #endif
1118
1119         #if 1
1120         PmrRx(         o->pmrChan,
1121                    (i16 *)(o->usbradio_read_buf + AST_FRIENDLY_OFFSET),
1122                    (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
1123
1124         #else
1125         static FILE *hInput;
1126         i16 iBuff[FRAME_SIZE * 2 * 6];
1127
1128         o->pmrChan->b.rxCapture = 1;
1129
1130         if(!hInput) {
1131                 hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm", "r");
1132                 if(!hInput) {
1133                         ast_log(LOG_ERROR, " Input Data File Not Found.\n");
1134                         return 0;
1135                 }
1136         }
1137
1138         if (0 == fread((void *)iBuff, 2, FRAME_SIZE * 2 * 6, hInput))
1139                 exit;
1140
1141         PmrRx(         o->pmrChan, 
1142                    (i16 *)iBuff,
1143                    (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
1144
1145         #endif
1146
1147         #if 0
1148         if (!frxoutraw) frxoutraw = fopen(RX_CAP_OUT_FILE, "w");
1149     if (frxoutraw) fwrite((o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET), 1, FRAME_SIZE * 2, frxoutraw);
1150         #endif
1151
1152         #if DEBUG_CAPTURES == 1
1153     if (frxcaptrace && o->b.rxcap2) fwrite((o->pmrChan->prxDebug), 1, FRAME_SIZE * 2 * 16, frxcaptrace);
1154         #endif
1155
1156         if (o->rxcdtype == CD_HID && (o->pmrChan->rxExtCarrierDetect != o->rxhidsq))
1157                 o->pmrChan->rxExtCarrierDetect = o->rxhidsq;
1158         if (o->rxcdtype == CD_HID_INVERT && (o->pmrChan->rxExtCarrierDetect == o->rxhidsq))
1159                 o->pmrChan->rxExtCarrierDetect = !o->rxhidsq;
1160                 
1161         if ( (o->rxcdtype == CD_HID && o->rxhidsq) ||
1162                  (o->rxcdtype == CD_HID_INVERT && !o->rxhidsq) ||
1163                  (o->rxcdtype == CD_XPMR_NOISE && o->pmrChan->rxCarrierDetect) ||
1164                  (o->rxcdtype == CD_XPMR_VOX && o->pmrChan->rxCarrierDetect) )
1165                 res = 1;
1166         else
1167                 res = 0;
1168
1169         if (res != o->rxcarrierdetect) {
1170                 o->rxcarrierdetect = res;
1171                 if (o->debuglevel)
1172                         ast_debug(4, "rxcarrierdetect = %d\n", res);
1173         }
1174
1175         if (o->pmrChan->rxCtcss->decode != o->rxctcssdecode) {
1176                 if (o->debuglevel)
1177                         ast_debug(4, "rxctcssdecode = %d\n", o->pmrChan->rxCtcss->decode);
1178                 o->rxctcssdecode = o->pmrChan->rxCtcss->decode;
1179         }
1180
1181         if ( (  o->rxctcssfreq && (o->rxctcssdecode == o->pmrChan->rxCtcssIndex)) || 
1182                  ( !o->rxctcssfreq && o->rxcarrierdetect) ) 
1183                 o->rxkeyed = 1;
1184         else
1185                 o->rxkeyed = 0;
1186
1187
1188         o->readpos = AST_FRIENDLY_OFFSET;       /* reset read pointer for next frame */
1189         if (c->_state != AST_STATE_UP)  /* drop data if frame is not up */
1190                 return f;
1191         /* ok we can build and deliver the frame to the caller */
1192         f->frametype = AST_FRAME_VOICE;
1193         f->subclass = AST_FORMAT_SLINEAR;
1194         f->samples = FRAME_SIZE;
1195         f->datalen = FRAME_SIZE * 2;
1196         f->data = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
1197         if (o->boost != BOOST_SCALE) {  /* scale and clip values */
1198                 int i, x;
1199                 int16_t *p = (int16_t *) f->data;
1200                 for (i = 0; i < f->samples; i++) {
1201                         x = (p[i] * o->boost) / BOOST_SCALE;
1202                         if (x > 32767)
1203                                 x = 32767;
1204                         else if (x < -32768)
1205                                 x = -32768;
1206                         p[i] = x;
1207                 }
1208         }
1209
1210         f->offset = AST_FRIENDLY_OFFSET;
1211         if (o->dsp) {
1212                 f1 = ast_dsp_process(c, o->dsp, f);
1213                 if ((f1->frametype == AST_FRAME_DTMF_END) || (f1->frametype == AST_FRAME_DTMF_BEGIN)) {
1214                         if ((f1->subclass == 'm') || (f1->subclass == 'u'))
1215                             f1->frametype = AST_FRAME_DTMF_BEGIN;
1216                         if (f1->frametype == AST_FRAME_DTMF_END)
1217                             ast_log(LOG_NOTICE,"Got DTMF char %c\n",f1->subclass);
1218                         return f1;
1219                 }
1220         }
1221         return f;
1222 }
1223
1224 static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1225 {
1226         struct chan_usbradio_pvt *o = newchan->tech_pvt;
1227         ast_log(LOG_WARNING,"usbradio_fixup()\n");
1228         o->owner = newchan;
1229         return 0;
1230 }
1231
1232 static int usbradio_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
1233 {
1234         struct chan_usbradio_pvt *o = c->tech_pvt;
1235         int res = 0;
1236
1237         switch (cond) {
1238         case AST_CONTROL_BUSY:
1239         case AST_CONTROL_CONGESTION:
1240         case AST_CONTROL_RINGING:
1241         case -1:
1242                 res = -1;
1243                 break;
1244         case AST_CONTROL_PROGRESS:
1245         case AST_CONTROL_PROCEEDING:
1246         case AST_CONTROL_VIDUPDATE:
1247                 break;
1248         case AST_CONTROL_HOLD:
1249                 ast_verbose(" << Console Has Been Placed on Hold >> \n");
1250                 ast_moh_start(c, data, o->mohinterpret);
1251                 break;
1252         case AST_CONTROL_UNHOLD:
1253                 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
1254                 ast_moh_stop(c);
1255                 break;
1256         case AST_CONTROL_RADIO_KEY:
1257                 o->txkeyed = 1;
1258                 if (o->debuglevel)
1259                         ast_verbose(" << Radio Transmit On. >> \n");
1260                 break;
1261         case AST_CONTROL_RADIO_UNKEY:
1262                 o->txkeyed = 0;
1263                 if (o->debuglevel)
1264                         ast_verbose(" << Radio Transmit Off. >> \n");
1265                 break;
1266         default:
1267                 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
1268                 return -1;
1269         }
1270
1271         return res;
1272 }
1273
1274 /*
1275  * allocate a new channel.
1276  */
1277 static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state)
1278 {
1279         struct ast_channel *c;
1280         char device[15] = "dsp";
1281
1282         if (o->devicenum)
1283                 snprintf(device + 3, sizeof(device) - 3, "%d", o->devicenum);
1284         c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "usbRadio/%s", device);
1285         if (c == NULL)
1286                 return NULL;
1287         c->tech = &usbradio_tech;
1288         if (o->sounddev < 0)
1289                 setformat(o, O_RDWR);
1290         c->fds[0] = o->sounddev;        /* -1 if device closed, override later */
1291         c->nativeformats = AST_FORMAT_SLINEAR;
1292         c->readformat = AST_FORMAT_SLINEAR;
1293         c->writeformat = AST_FORMAT_SLINEAR;
1294         c->tech_pvt = o;
1295
1296         if (!ast_strlen_zero(o->language))
1297                 ast_string_field_set(c, language, o->language);
1298         /* Don't use ast_set_callerid() here because it will
1299          * generate a needless NewCallerID event */
1300         c->cid.cid_num = ast_strdup(o->cid_num);
1301         c->cid.cid_ani = ast_strdup(o->cid_num);
1302         c->cid.cid_name = ast_strdup(o->cid_name);
1303         if (!ast_strlen_zero(ext))
1304                 c->cid.cid_dnid = ast_strdup(ext);
1305
1306         o->owner = c;
1307         ast_module_ref(ast_module_info->self);
1308         ast_jb_configure(c, &global_jbconf);
1309         if (state != AST_STATE_DOWN) {
1310                 if (ast_pbx_start(c)) {
1311                         ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
1312                         ast_hangup(c);
1313                         o->owner = c = NULL;
1314                         /* XXX what about the channel itself ? */
1315                         /* XXX what about usecnt ? */
1316                 }
1317         }
1318
1319         return c;
1320 }
1321
1322 static struct ast_channel *usbradio_request(const char *type, int format, void *data, int *cause)
1323 {
1324         struct ast_channel *c;
1325         struct chan_usbradio_pvt *o = find_desc(data);
1326
1327         ast_debug(4, "usbradio_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data);
1328         if (o == NULL) {
1329                 ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
1330                 /* XXX we could default to 'dsp' perhaps ? */
1331                 return NULL;
1332         }
1333         if ((format & AST_FORMAT_SLINEAR) == 0) {
1334                 ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
1335                 return NULL;
1336         }
1337         if (o->owner) {
1338                 ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
1339                 *cause = AST_CAUSE_BUSY;
1340                 return NULL;
1341         }
1342         c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
1343         if (c == NULL) {
1344                 ast_log(LOG_WARNING, "Unable to create new usb channel\n");
1345                 return NULL;
1346         }
1347         return c;
1348 }
1349
1350 static char *handle_cli_radio_key(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1351 {
1352         struct chan_usbradio_pvt *o = NULL;
1353
1354         switch (cmd) {
1355         case CLI_INIT:
1356                 e->command = "radio key";
1357                 e->usage =
1358                         "Usage: radio key\n"
1359                         "       Simulates COR active.\n";
1360                 return NULL;
1361         case CLI_GENERATE:
1362                 return NULL;
1363         }
1364
1365         if (a->argc != 2)
1366                 return CLI_SHOWUSAGE;
1367
1368         o = find_desc(usbradio_active);
1369         o->txtestkey = 1;
1370
1371         return CLI_SUCCESS;
1372 }
1373
1374 static char *handle_cli_radio_unkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1375 {
1376         struct chan_usbradio_pvt *o = NULL;
1377
1378         switch (cmd) {
1379         case CLI_INIT:
1380                 e->command = "radio unkey";
1381                 e->usage =
1382                         "Usage: radio unkey\n"
1383                         "       Simulates COR un-active.\n";
1384                 return NULL;
1385         case CLI_GENERATE:
1386                 return NULL;
1387         }
1388
1389         if (a->argc != 2)
1390                 return CLI_SHOWUSAGE;
1391
1392         o = find_desc(usbradio_active);
1393         o->txtestkey = 0;
1394
1395         return CLI_SUCCESS;
1396 }
1397
1398 static char *handle_cli_radio_tune(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1399 {
1400         struct chan_usbradio_pvt *o = NULL;
1401         int i = 0;
1402
1403         switch (cmd) {
1404         case CLI_INIT:
1405                 e->command = "radio tune [rxnoise|rxvoice|rxtone|rxsquelch|rxcap|rxtracecap|"
1406                         "txvoice|txtone|txcap|txtracecap|auxvoice|nocap|dump|save]";
1407                 /* radio tune 6 3000        measured tx value */
1408                 e->usage =
1409                         "Usage: radio tune <function>\n"
1410                         "       rxnoise\n"
1411                         "       rxvoice\n"
1412                         "       rxtone\n"
1413                         "       rxsquelch [newsetting]\n"
1414                         "       rxcap\n"
1415                         "       rxtracecap\n"
1416                         "       txvoice [newsetting]\n"
1417                         "       txtone [newsetting]\n"
1418                         "       txcap\n"
1419                         "       txtracecap\n"
1420                         "       auxvoice [newsetting]\n"
1421                         "       nocap\n"
1422                         "       dump\n"
1423                         "       save (settings to tuning file)\n"
1424                         "\n"
1425                         "       All [newsetting]s are values 0-999\n";
1426                 return NULL;
1427         case CLI_GENERATE:
1428                 return NULL;
1429         }
1430
1431         if ((a->argc < 2) || (a->argc > 4))
1432                 return CLI_SHOWUSAGE; 
1433
1434         if (a->argc == 2) { /* just show stuff */
1435                 ast_cli(a->fd, "Output A is currently set to %s.\n",
1436                         o->txmixa == TX_OUT_COMPOSITE ? "composite" :
1437                         o->txmixa == TX_OUT_VOICE ? "voice" :
1438                         o->txmixa == TX_OUT_LSD ? "tone" :
1439                         o->txmixa == TX_OUT_AUX ? "auxvoice" :
1440                         "off");
1441
1442                 ast_cli(a->fd, "Output B is currently set to %s.\n",
1443                         o->txmixb == TX_OUT_COMPOSITE ? "composite" :
1444                         o->txmixb == TX_OUT_VOICE ? "voice" :
1445                         o->txmixb == TX_OUT_LSD ? "tone" :
1446                         o->txmixb == TX_OUT_AUX ? "auxvoice" :
1447                         "off");
1448
1449                 ast_cli(a->fd, "Tx Voice Level currently set to %d\n", o->txmixaset);
1450                 ast_cli(a->fd, "Tx Tone Level currently set to %d\n", o->txctcssadj);
1451                 ast_cli(a->fd, "Rx Squelch currently set to %d\n", o->rxsquelchadj);
1452                 return CLI_SHOWUSAGE;
1453         }
1454
1455         o = find_desc(usbradio_active);
1456
1457         if (!strcasecmp(a->argv[2], "rxnoise"))
1458                 tune_rxinput(o);
1459         else if (!strcasecmp(a->argv[2], "rxvoice"))
1460                 tune_rxvoice(o);
1461         else if (!strcasecmp(a->argv[2], "rxtone"))
1462                 tune_rxctcss(o);
1463         else if (!strcasecmp(a->argv[2], "rxsquelch")) {
1464                 if (a->argc == 3) {
1465                     ast_cli(a->fd, "Current Signal Strength is %d\n", ((32767 - o->pmrChan->rxRssi) * 1000 / 32767));
1466                     ast_cli(a->fd, "Current Squelch setting is %d\n", o->rxsquelchadj);
1467 #if 0
1468                         ast_cli(a->fd,"Current Raw RSSI        is %d\n",o->pmrChan->rxRssi);
1469                     ast_cli(a->fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
1470 #endif
1471                 } else {
1472                         i = atoi(a->argv[3]);
1473                         if ((i < 0) || (i > 999))
1474                                 return CLI_SHOWUSAGE;
1475                         ast_cli(a->fd, "Changed Squelch setting to %d\n", i);
1476                         o->rxsquelchadj = i;
1477                         *(o->pmrChan->prxSquelchAdjust) = ((999 - i) * 32767) / 1000;
1478                 }
1479         } else if (!strcasecmp(a->argv[2], "txvoice")) {
1480                 i = 0;
1481
1482                 if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
1483                         (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE)) {
1484                         ast_log(LOG_ERROR, "No txvoice output configured.\n");
1485                 } else if (a->argc == 3) {
1486                         if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE))
1487                                 ast_cli(a->fd, "Current txvoice setting on Channel A is %d\n", o->txmixaset);
1488                         else
1489                                 ast_cli(a->fd, "Current txvoice setting on Channel B is %d\n", o->txmixbset);
1490                 } else {
1491                         i = atoi(a->argv[3]);
1492                         if ((i < 0) || (i > 999))
1493                                 return CLI_SHOWUSAGE;
1494
1495                         if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE)) {
1496                                 o->txmixaset = i;
1497                                 ast_cli(a->fd, "Changed txvoice setting on Channel A to %d\n", o->txmixaset);
1498                         } else {
1499                                 o->txmixbset = i;   
1500                                 ast_cli(a->fd, "Changed txvoice setting on Channel B to %d\n", o->txmixbset);
1501                         }
1502                         mixer_write(o);
1503                         mult_set(o);
1504                         ast_cli(a->fd, "Changed Tx Voice Output setting to %d\n", i);
1505                 }
1506                 tune_txoutput(o,i);
1507         } else if (!strcasecmp(a->argv[2], "auxvoice")) {
1508                 i = 0;
1509                 if ( (o->txmixa != TX_OUT_AUX) && (o->txmixb != TX_OUT_AUX))
1510                         ast_log(LOG_WARNING, "No auxvoice output configured.\n");
1511                 else if (a->argc == 3) {
1512                         if (o->txmixa == TX_OUT_AUX)
1513                                 ast_cli(a->fd, "Current auxvoice setting on Channel A is %d\n", o->txmixaset);
1514                         else
1515                                 ast_cli(a->fd, "Current auxvoice setting on Channel B is %d\n", o->txmixbset);
1516                 } else {
1517                         i = atoi(a->argv[3]);
1518                         if ((i < 0) || (i > 999))
1519                                 return CLI_SHOWUSAGE;
1520                         if (o->txmixa == TX_OUT_AUX) {
1521                                 o->txmixbset = i;
1522                                 ast_cli(a->fd, "Changed auxvoice setting on Channel A to %d\n", o->txmixaset);
1523                         } else {
1524                                 o->txmixbset = i;
1525                                 ast_cli(a->fd, "Changed auxvoice setting on Channel B to %d\n", o->txmixbset);
1526                         }
1527                         mixer_write(o);
1528                         mult_set(o);
1529                 }
1530                 /* tune_auxoutput(o,i); */
1531         } else if (!strcasecmp(a->argv[2], "txtone")) {
1532                 if (a->argc == 3)
1533                         ast_cli(a->fd, "Current Tx CTCSS modulation setting = %d\n", o->txctcssadj);
1534                 else {
1535                         i = atoi(a->argv[3]);
1536                         if ((i < 0) || (i > 999))
1537                                 return CLI_SHOWUSAGE;
1538                         o->txctcssadj = i;
1539                         set_txctcss_level(o);
1540                         ast_cli(a->fd, "Changed Tx CTCSS modulation setting to %i\n", i);
1541                 }
1542                 o->txtestkey = 1;
1543                 usleep(5000000);
1544                 o->txtestkey = 0;
1545         } else if (!strcasecmp(a->argv[2],"dump"))
1546                 pmrdump(o);
1547         else if (!strcasecmp(a->argv[2],"nocap")) {
1548                 ast_cli(a->fd, "File capture (trace) was rx=%d tx=%d and now off.\n", o->b.rxcap2, o->b.txcap2);
1549                 ast_cli(a->fd, "File capture (raw)   was rx=%d tx=%d and now off.\n", o->b.rxcapraw, o->b.txcapraw);
1550                 o->b.rxcapraw = o->b.txcapraw = o->b.rxcap2 = o->b.txcap2 = o->pmrChan->b.rxCapture = o->pmrChan->b.txCapture = 0;
1551                 if (frxcapraw) {
1552                         fclose(frxcapraw);
1553                         frxcapraw = NULL;
1554                 }
1555                 if (frxcaptrace) {
1556                         fclose(frxcaptrace);
1557                         frxcaptrace = NULL;
1558                 }
1559                 if (frxoutraw) {
1560                         fclose(frxoutraw);
1561                         frxoutraw = NULL;
1562                 }
1563                 if (ftxcapraw) {
1564                         fclose(ftxcapraw);
1565                         ftxcapraw = NULL;
1566                 }
1567                 if (ftxcaptrace) {
1568                         fclose(ftxcaptrace);
1569                         ftxcaptrace = NULL;
1570                 }
1571                 if (ftxoutraw) {
1572                         fclose(ftxoutraw);
1573                         ftxoutraw = NULL;
1574                 }
1575         } else if (!strcasecmp(a->argv[2], "rxtracecap")) {
1576                 if (!frxcaptrace)
1577                         frxcaptrace = fopen(RX_CAP_TRACE_FILE, "w");
1578                 ast_cli(a->fd, "Trace rx on.\n");
1579                 o->b.rxcap2 = o->pmrChan->b.rxCapture = 1;
1580         } else if (!strcasecmp(a->argv[2], "txtracecap")) {
1581                 if (!ftxcaptrace)
1582                         ftxcaptrace = fopen(TX_CAP_TRACE_FILE, "w");
1583                 ast_cli(a->fd, "Trace tx on.\n");
1584                 o->b.txcap2 = o->pmrChan->b.txCapture = 1;
1585         } else if (!strcasecmp(a->argv[2], "rxcap")) {
1586                 if (!frxcapraw)
1587                         frxcapraw = fopen(RX_CAP_RAW_FILE, "w");
1588                 ast_cli(a->fd, "cap rx raw on.\n");
1589                 o->b.rxcapraw = 1;
1590         } else if (!strcasecmp(a->argv[2], "txcap")) {
1591                 if (!ftxcapraw)
1592                         ftxcapraw = fopen(TX_CAP_RAW_FILE, "w");
1593                 ast_cli(a->fd, "cap tx raw on.\n");
1594                 o->b.txcapraw = 1;
1595         } else if (!strcasecmp(a->argv[2], "save")) {
1596                 tune_write(o);
1597                 ast_cli(a->fd, "Saved radio tuning settings to usbradio_tune.conf\n");
1598         } else
1599                 return CLI_SHOWUSAGE;
1600         return CLI_SUCCESS;
1601 }
1602
1603 /*
1604         set transmit ctcss modulation level
1605         adjust mixer output or internal gain depending on output type
1606         setting range is 0.0 to 0.9
1607 */
1608 static int set_txctcss_level(struct chan_usbradio_pvt *o)
1609 {                                                         
1610         if (o->txmixa == TX_OUT_LSD) {
1611                 o->txmixaset = (151 * o->txctcssadj) / 1000;
1612                 mixer_write(o);
1613                 mult_set(o);
1614         } else if (o->txmixb == TX_OUT_LSD) {
1615                 o->txmixbset = (151 * o->txctcssadj) / 1000;
1616                 mixer_write(o);
1617                 mult_set(o);
1618         } else {
1619                 *o->pmrChan->ptxCtcssAdjust = (o->txctcssadj * M_Q8) / 1000;
1620         }
1621         return 0;
1622 }
1623 /*
1624         CLI debugging on and off
1625 */
1626 static char *handle_cli_radio_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1627 {
1628         struct chan_usbradio_pvt *o = NULL;
1629
1630         switch (cmd) {
1631         case CLI_INIT:
1632                 e->command = "radio set debug [off]";
1633                 e->usage =
1634                         "Usage: radio set debug [off]\n"
1635                         "       Enable/Disable radio debugging.\n";
1636         case CLI_GENERATE:
1637                 return NULL;
1638         }
1639         if (a->argc < 3 || a->argc > 4)
1640                 return CLI_SHOWUSAGE;
1641         if (a->argc == 4 && strncasecmp(a->argv[3], "off", 3))
1642                 return CLI_SHOWUSAGE;
1643
1644         o = find_desc(usbradio_active);
1645
1646         if (a->argc == 3)
1647                 o->debuglevel = 1;
1648         else
1649                 o->debuglevel = 0;
1650
1651         ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
1652
1653         return CLI_SUCCESS;
1654 }
1655
1656 static struct ast_cli_entry cli_usbradio[] = {
1657         AST_CLI_DEFINE(handle_cli_radio_key,       "Simulate Rx Signal Present"),
1658         AST_CLI_DEFINE(handle_cli_radio_unkey,     "Simulate Rx Signal Lusb"),
1659         AST_CLI_DEFINE(handle_cli_radio_tune,      "Radio Tune"),
1660         AST_CLI_DEFINE(handle_cli_radio_set_debug, "Enable/Disable Radio Debugging"),
1661 };
1662
1663 /*
1664  * store the callerid components
1665  */
1666 #if 0
1667 static void store_callerid(struct chan_usbradio_pvt *o, const char *s)
1668 {
1669         ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
1670 }
1671 #endif
1672
1673 static void store_rxdemod(struct chan_usbradio_pvt *o, const char *s)
1674 {
1675         if (!strcasecmp(s, "no")) {
1676                 o->rxdemod = RX_AUDIO_NONE;
1677         } else if (!strcasecmp(s, "speaker")) {
1678                 o->rxdemod = RX_AUDIO_SPEAKER;
1679         } else if (!strcasecmp(s, "flat")) {
1680                         o->rxdemod = RX_AUDIO_FLAT;
1681         } else {
1682                 ast_log(LOG_WARNING, "Unrecognized rxdemod parameter: %s\n", s);
1683         }
1684
1685         ast_debug(4, "set rxdemod = %s\n", s);
1686 }
1687
1688                                            
1689 static void store_txmixa(struct chan_usbradio_pvt *o, const char *s)
1690 {
1691         if (!strcasecmp(s, "no"))
1692                 o->txmixa = TX_OUT_OFF;
1693
1694         else if (!strcasecmp(s, "voice"))
1695                 o->txmixa = TX_OUT_VOICE;
1696         else if (!strcasecmp(s, "tone"))
1697                         o->txmixa = TX_OUT_LSD;
1698         else if (!strcasecmp(s, "composite"))
1699                 o->txmixa = TX_OUT_COMPOSITE;
1700         else if (!strcasecmp(s, "auxvoice"))
1701                 o->txmixb = TX_OUT_AUX;
1702         else
1703                 ast_log(LOG_WARNING, "Unrecognized txmixa parameter: %s\n", s);
1704
1705         ast_debug(4, "set txmixa = %s\n", s);
1706 }
1707
1708 static void store_txmixb(struct chan_usbradio_pvt *o, const char *s)
1709 {
1710         if (!strcasecmp(s, "no"))
1711                 o->txmixb = TX_OUT_OFF;
1712         else if (!strcasecmp(s, "voice"))
1713                 o->txmixb = TX_OUT_VOICE;
1714         else if (!strcasecmp(s, "tone"))
1715                         o->txmixb = TX_OUT_LSD;
1716         else if (!strcasecmp(s, "composite"))
1717                 o->txmixb = TX_OUT_COMPOSITE;
1718         else if (!strcasecmp(s, "auxvoice"))
1719                 o->txmixb = TX_OUT_AUX;
1720         else
1721                 ast_log(LOG_WARNING, "Unrecognized txmixb parameter: %s\n", s);
1722
1723         ast_debug(4, "set txmixb = %s\n", s);
1724 }
1725
1726 static void store_rxcdtype(struct chan_usbradio_pvt *o, const char *s)
1727 {
1728         if (!strcasecmp(s, "no"))
1729                 o->rxcdtype = CD_IGNORE;
1730         else if (!strcasecmp(s, "usb"))
1731                 o->rxcdtype = CD_HID;
1732         else if (!strcasecmp(s, "dsp"))
1733                 o->rxcdtype = CD_XPMR_NOISE;
1734         else if (!strcasecmp(s, "vox"))
1735                 o->rxcdtype = CD_XPMR_VOX;
1736         else if (!strcasecmp(s, "usbinvert"))
1737                 o->rxcdtype = CD_HID_INVERT;
1738         else
1739                 ast_log(LOG_WARNING, "Unrecognized rxcdtype parameter: %s\n", s);
1740
1741         ast_debug(4, "set rxcdtype = %s\n", s);
1742 }
1743
1744 static void store_rxsdtype(struct chan_usbradio_pvt *o, const char *s)
1745 {
1746         if (!strcasecmp(s, "no") || !strcasecmp(s, "SD_IGNORE"))
1747                 o->rxsdtype = SD_IGNORE;
1748         else if (!strcasecmp(s, "usb") || !strcasecmp(s, "SD_HID"))
1749                 o->rxsdtype = SD_HID;
1750         else if (!strcasecmp(s, "usbinvert") || !strcasecmp(s, "SD_HID_INVERT"))
1751                 o->rxsdtype = SD_HID_INVERT;
1752         else if (!strcasecmp(s, "software") || !strcasecmp(s, "SD_XPMR"))
1753                 o->rxsdtype = SD_XPMR;
1754         else
1755                 ast_log(LOG_WARNING, "Unrecognized rxsdtype parameter: %s\n", s);
1756
1757         ast_debug(4, "set rxsdtype = %s\n", s);
1758 }
1759
1760 static void store_rxgain(struct chan_usbradio_pvt *o, const char *s)
1761 {
1762         float f;
1763         if (sscanf(s, "%f", &f) == 1)
1764                 o->rxgain = f;
1765         ast_debug(4, "set rxgain = %f\n", f);
1766 }
1767
1768 static void store_rxvoiceadj(struct chan_usbradio_pvt *o, const char *s)
1769 {
1770         float f;
1771         if (sscanf(s, "%f", &f) == 1)
1772                 o->rxvoiceadj = f;
1773         ast_debug(4, "set rxvoiceadj = %f\n", f);
1774 }
1775
1776 static void store_rxctcssadj(struct chan_usbradio_pvt *o, const char *s)
1777 {
1778         float f;
1779         if (sscanf(s, "%f", &f) == 1)
1780                 o->rxctcssadj = f;
1781         ast_debug(4, "set rxctcssadj = %f\n", f);
1782 }
1783
1784 static void store_txtoctype(struct chan_usbradio_pvt *o, const char *s)
1785 {
1786         if (!strcasecmp(s, "no") || !strcasecmp(s, "TOC_NONE"))
1787                 o->txtoctype = TOC_NONE;
1788         else if (!strcasecmp(s, "phase") || !strcasecmp(s, "TOC_PHASE"))
1789                 o->txtoctype = TOC_PHASE;
1790         else if (!strcasecmp(s, "notone") || !strcasecmp(s, "TOC_NOTONE"))
1791                 o->txtoctype = TOC_NOTONE;
1792         else
1793                 ast_log(LOG_WARNING, "Unrecognized txtoctype parameter: %s\n", s);
1794
1795         ast_debug(4, "set txtoctype = %s\n", s);
1796 }
1797
1798 static void store_rxctcssfreq(struct chan_usbradio_pvt *o, const char *s)
1799 {
1800         float f;
1801         if (sscanf(s, "%f", &f) == 1)
1802                 o->rxctcssfreq = f;
1803         ast_debug(4, "set rxctcss = %f\n", f);
1804 }
1805
1806 static void store_txctcssfreq(struct chan_usbradio_pvt *o, const char *s)
1807 {
1808         float f;
1809         if (sscanf(s, "%f", &f) == 1)
1810                 o->txctcssfreq = f;
1811         ast_debug(4, "set txctcss = %f\n", f);
1812 }
1813
1814 static void tune_txoutput(struct chan_usbradio_pvt *o, int value)
1815 {
1816         o->txtestkey = 1;
1817         o->pmrChan->txPttIn = 1;
1818
1819 #if 0
1820         /* generate 1KHz tone at 7200 peak */
1821         o->pmrChan->spsSigGen1->freq = 10000;
1822         o->pmrChan->spsSigGen1->outputGain = (float)(0.22 * M_Q8);
1823         o->pmrChan->b.startSpecialTone = 1;
1824 #endif
1825
1826         TxTestTone(o->pmrChan, 1);
1827
1828         usleep(5000000);
1829         /* o->pmrChan->b.stopSpecialTone = 1; */
1830         usleep(100000);
1831
1832         TxTestTone(o->pmrChan, 0);
1833
1834         o->pmrChan->txPttIn = 0;
1835         o->txtestkey = 0;
1836 }
1837
1838 static void tune_rxinput(struct chan_usbradio_pvt *o)
1839 {
1840         const int target = 23000;
1841         const int tolerance = 2000;
1842         const int settingmin = 1;
1843         const int settingstart = 2;
1844         const int maxtries = 12;
1845
1846         float settingmax;
1847         
1848         int setting = 0, tries = 0, tmpdiscfactor, meas;
1849         int tunetype = 0;
1850
1851         settingmax = o->micmax;
1852
1853         if (o->pmrChan->rxDemod)
1854                 tunetype = 1;
1855
1856         setting = settingstart;
1857
1858         while (tries < maxtries) {
1859                 setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL, setting, 0);
1860                 setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
1861                 usleep(100000);
1862                 if (o->rxcdtype == CD_XPMR_VOX || o->rxdemod == RX_AUDIO_SPEAKER) {
1863                         ast_debug(4, "Measure Direct Input\n");
1864                         o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
1865                         o->pmrChan->spsMeasure->discfactor = 1000;
1866                         o->pmrChan->spsMeasure->enabled = 1;
1867                         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
1868                         usleep(400000); 
1869                         meas = o->pmrChan->spsMeasure->apeak;
1870                         o->pmrChan->spsMeasure->enabled = 0;    
1871                 } else {
1872                         ast_debug(4, "Measure HF Noise\n");
1873                         tmpdiscfactor = o->pmrChan->spsRx->discfactor;
1874                         o->pmrChan->spsRx->discfactor = (i16)1000;
1875                         o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
1876                         o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
1877                         usleep(200000);
1878                         meas = o->pmrChan->rxRssi;
1879                         o->pmrChan->spsRx->discfactor = tmpdiscfactor;
1880                         o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
1881                         o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
1882                 }
1883         if (!meas)
1884                         meas++;
1885                 ast_log(LOG_NOTICE, "tries=%d, setting=%d, meas=%i\n", tries, setting, meas);
1886
1887                 if ( meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
1888                         setting = setting * target / meas;
1889                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance) )
1890                         break;
1891
1892                 if (setting < settingmin)
1893                         setting = settingmin;
1894                 else if (setting > settingmax)
1895                         setting = settingmax;
1896
1897                 tries++;
1898         }
1899         ast_log(LOG_NOTICE, "DONE tries=%d, setting=%d, meas=%i\n", tries,
1900                 (setting * 1000) / o->micmax, meas);
1901         if (meas < (target - tolerance) || meas > (target + tolerance))
1902                 ast_log(LOG_NOTICE, "ERROR: RX INPUT ADJUST FAILED.\n");
1903         else {
1904                 ast_log(LOG_NOTICE, "INFO: RX INPUT ADJUST SUCCESS.\n");        
1905                 o->rxmixerset = (setting * 1000) / o->micmax;
1906         }
1907 }
1908 /*
1909 */
1910 static void tune_rxvoice(struct chan_usbradio_pvt *o)
1911 {
1912         const int target = 7200;        /* peak */
1913         const int tolerance = 360;      /* peak to peak */
1914         const float settingmin = 0.1;
1915         const float settingmax = 4;
1916         const float settingstart = 1;
1917         const int maxtries = 12;
1918
1919         float setting;
1920
1921         int tries = 0, meas;
1922
1923         ast_log(LOG_NOTICE, "INFO: RX VOICE ADJUST START.\n");  
1924         ast_log(LOG_NOTICE, "target=%d tolerance=%d\n", target, tolerance);
1925
1926         if (!o->pmrChan->spsMeasure)
1927                 ast_log(LOG_ERROR, "NO MEASURE BLOCK.\n");
1928
1929         if (!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
1930                 ast_log(LOG_ERROR, "NO SOURCE OR MEASURE SETTING.\n");
1931
1932         o->pmrChan->spsMeasure->source = o->pmrChan->spsRxOut->sink;
1933         o->pmrChan->spsMeasure->enabled = 1;
1934         o->pmrChan->spsMeasure->discfactor = 1000;
1935
1936         setting=settingstart;
1937
1938         ast_debug(4, "ERROR: NO MEASURE BLOCK.\n");
1939
1940         while (tries < maxtries) {
1941                 *(o->pmrChan->prxVoiceAdjust) = setting * M_Q8;
1942                 usleep(10000);
1943         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
1944                 usleep(1000000);
1945                 meas = o->pmrChan->spsMeasure->apeak;
1946                 ast_log(LOG_NOTICE, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
1947
1948                 if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
1949                         setting = setting * target / meas;
1950                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
1951                         break;
1952                 if (setting < settingmin)
1953                         setting = settingmin;
1954                 else if (setting > settingmax)
1955                         setting = settingmax;
1956
1957                 tries++;
1958         }
1959
1960         o->pmrChan->spsMeasure->enabled = 0;
1961
1962         ast_log(LOG_NOTICE, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
1963         if (meas < (target - tolerance) || meas > (target + tolerance))
1964                 ast_log(LOG_ERROR, "RX VOICE GAIN ADJUST FAILED.\n");
1965         else {
1966                 ast_log(LOG_NOTICE, "RX VOICE GAIN ADJUST SUCCESS.\n");
1967                 o->rxvoiceadj = setting;
1968         }
1969 }
1970
1971 static void tune_rxctcss(struct chan_usbradio_pvt *o)
1972 {
1973         const int target = 4096;
1974         const int tolerance = 100;
1975         const float settingmin = 0.1;
1976         const float settingmax = 4;
1977         const float settingstart = 1;
1978         const int maxtries = 12;
1979
1980         float setting;
1981         int tries = 0, meas;
1982
1983         ast_log(LOG_NOTICE, "RX CTCSS ADJUST START.\n");        
1984         ast_log(LOG_NOTICE, "target=%d tolerance=%d \n", target, tolerance);
1985
1986         o->pmrChan->spsMeasure->source = o->pmrChan->prxCtcssMeasure;
1987         o->pmrChan->spsMeasure->discfactor = 400;
1988         o->pmrChan->spsMeasure->enabled = 1;
1989
1990         setting = settingstart;
1991
1992         while (tries < maxtries) {
1993                 *(o->pmrChan->prxCtcssAdjust) = setting * M_Q8;
1994                 usleep(10000);
1995         o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
1996                 usleep(500000);
1997                 meas = o->pmrChan->spsMeasure->apeak;
1998                 ast_debug(4, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
1999
2000                 if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
2001                         setting = setting * target / meas;
2002                 else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
2003                         break;
2004                 if (setting < settingmin)
2005                         setting = settingmin;
2006                 else if (setting > settingmax)
2007                         setting = settingmax;
2008
2009                 tries++;
2010         }
2011         o->pmrChan->spsMeasure->enabled = 0;
2012         ast_debug(4, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
2013         if (meas < (target - tolerance) || meas > (target + tolerance))
2014                 ast_log(LOG_ERROR, "RX CTCSS GAIN ADJUST FAILED.\n");
2015         else {
2016                 ast_log(LOG_NOTICE, "RX CTCSS GAIN ADJUST SUCCESS.\n");
2017                 o->rxctcssadj = setting;
2018         }
2019 }
2020 /*
2021         this file then is included in chan_usbradio.conf
2022         #include /etc/asterisk/usbradio_tune.conf 
2023 */
2024 static void tune_write(struct chan_usbradio_pvt *o)
2025 {
2026         FILE *fp;
2027         
2028         fp = fopen("/etc/asterisk/usbradio_tune.conf", "w");
2029  
2030         if (!strcmp(o->name, "dsp"))
2031                 fprintf(fp, "[general]\n");
2032         else
2033                 fprintf(fp, "[%s]\n", o->name);
2034
2035         fprintf(fp, "; name=%s\n", o->name);
2036         fprintf(fp, "; devicenum=%d\n", o->devicenum);
2037
2038         fprintf(fp, "rxmixerset=%d\n", o->rxmixerset);
2039         fprintf(fp, "rxboostset=%d\n", o->rxboostset);
2040         fprintf(fp, "txmixaset=%d\n", o->txmixaset);
2041         fprintf(fp, "txmixbset=%d\n", o->txmixbset);
2042
2043         fprintf(fp, "rxvoiceadj=%f\n", o->rxvoiceadj);
2044         fprintf(fp, "rxctcssadj=%f\n", o->rxctcssadj);
2045         fprintf(fp, "txctcssadj=%d\n", o->txctcssadj);
2046
2047         fprintf(fp, "rxsquelchadj=%d\n", o->rxsquelchadj);
2048         fclose(fp);
2049 }
2050
2051 static void mixer_write(struct chan_usbradio_pvt *o)
2052 {
2053         setamixer(o->devicenum, MIXER_PARAM_MIC_PLAYBACK_SW, 0, 0);
2054         setamixer(o->devicenum, MIXER_PARAM_MIC_PLAYBACK_VOL, 0, 0);
2055         setamixer(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_SW, 1, 0);
2056         setamixer(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL,
2057                 o->txmixaset * o->spkrmax / 1000,
2058                 o->txmixbset * o->spkrmax / 1000);
2059         setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL,
2060                 o->rxmixerset * o->micmax / 1000, 0);
2061         setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
2062         setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_SW, 1, 0);
2063 }
2064 /*
2065         adjust dsp multiplier to add resolution to tx level adjustment
2066 */
2067 static void mult_set(struct chan_usbradio_pvt *o)
2068 {
2069
2070         if (o->pmrChan->spsTxOutA) {
2071                 o->pmrChan->spsTxOutA->outputGain = 
2072                         mult_calc((o->txmixaset * 152) / 1000);
2073         }
2074         if (o->pmrChan->spsTxOutB) {
2075                 o->pmrChan->spsTxOutB->outputGain = 
2076                         mult_calc((o->txmixbset * 152) / 1000);
2077         }
2078 }
2079 /*
2080  * input 0 - 151 outputs are pot and multiplier
2081  */
2082 static int mult_calc(int value)
2083 {
2084         const int multx = M_Q8;
2085         int pot, mult;
2086
2087         pot= ((int)(value / 4) * 4) + 2;
2088         mult = multx - ((multx * (3 - (value % 4))) / (pot + 2));
2089         return mult;
2090 }
2091
2092 #define pd(x) ast_debug(4, #x" = %d\n", x)
2093 #define pp(x) ast_debug(4, #x" = %p\n", x)
2094 #define ps(x) ast_debug(4, #x" = %s\n", x)
2095 #define pf(x) ast_debug(4, #x" = %f\n", x)
2096 /*
2097 */
2098 static void pmrdump(struct chan_usbradio_pvt *o)
2099 {
2100         t_pmr_chan *p;
2101
2102         p = o->pmrChan;
2103
2104         ast_debug(4, "odump()\n");
2105
2106         pd(o->devicenum);
2107
2108         pd(o->rxdemod);
2109         pd(o->rxcdtype);
2110         pd(o->rxsdtype);
2111         pd(o->txtoctype);
2112
2113         pd(o->rxmixerset);
2114         pf(o->rxvoiceadj);
2115         pf(o->rxctcssadj);
2116         pd(o->rxsquelchadj);
2117          
2118         pd(o->txprelim);
2119         pd(o->txmixa);
2120         pd(o->txmixb);
2121         
2122         pd(o->txmixaset);
2123         pd(o->txmixbset);
2124         
2125         ast_debug(4, "pmrdump()\n");
2126  
2127         ast_debug(4, "prxSquelchAdjust=%d\n", *(o->pmrChan->prxSquelchAdjust));
2128
2129         pd(p->rxCarrierPoint);
2130         pd(p->rxCarrierHyst);
2131
2132         pd(p->rxCtcss->relax);
2133         pf(p->rxCtcssFreq);     
2134         pd(p->rxCtcssIndex);
2135         pf(p->txCtcssFreq);
2136
2137         pd(p->txMixA);
2138         pd(p->txMixB);
2139     
2140         pd(p->rxDeEmpEnable);
2141         pd(p->rxCenterSlicerEnable);
2142         pd(p->rxCtcssDecodeEnable);
2143         pd(p->rxDcsDecodeEnable);
2144
2145         pd(p->txHpfEnable);
2146         pd(p->txLimiterEnable);
2147         pd(p->txPreEmpEnable);
2148         pd(p->txLpfEnable);
2149
2150         if (p->spsTxOutA)
2151                 pd(p->spsTxOutA->outputGain);
2152         if (p->spsTxOutB)
2153                 pd(p->spsTxOutB->outputGain);
2154
2155         return;
2156 }
2157
2158
2159 /*
2160  * grab fields from the config file, init the descriptor and open the device.
2161  */
2162 static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
2163 {
2164         struct ast_variable *v;
2165         struct chan_usbradio_pvt *o;
2166         struct ast_config *cfg1;
2167         struct ast_flags config_flags = { 0 };
2168
2169         if (ctg == NULL) {
2170                 traceusb1(" store_config() ctg == NULL\n");
2171                 o = &usbradio_default;
2172                 ctg = "general";
2173         } else {
2174                 if (!(o = ast_calloc(1, sizeof(*o)))){
2175                         return NULL;
2176                 }
2177                 *o = usbradio_default;
2178                 /* "general" is also the default thing */
2179                 if (strcmp(ctg, "general") == 0) {
2180                         o->name = ast_strdup("dsp");
2181                         usbradio_active = o->name;
2182                 } else
2183                         o->name = ast_strdup(ctg);
2184         }
2185
2186         strcpy(o->mohinterpret, "default");
2187         o->micmax = amixer_max(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL);
2188         o->spkrmax = amixer_max(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL);
2189         /* fill other fields from configuration */
2190         for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
2191
2192                 /* handle jb conf */
2193                 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
2194                         continue;
2195                 CV_START(v->name, v->value);
2196
2197                 CV_UINT("frags", o->frags);
2198                 CV_UINT("queuesize", o->queuesize);
2199                 CV_UINT("devicenum", o->devicenum);
2200                 CV_UINT("debug", usbradio_debug);
2201                 CV_BOOL("rxcpusaver", o->rxcpusaver);
2202                 CV_BOOL("txcpusaver", o->txcpusaver);
2203                 CV_BOOL("invertptt", o->invertptt);
2204                 CV_F("rxdemod", store_rxdemod(o, v->value));
2205                 CV_BOOL("txprelim", o->txprelim);;
2206                 CV_F("txmixa", store_txmixa(o, v->value));
2207                 CV_F("txmixb", store_txmixb(o, v->value));
2208                 CV_F("carrierfrom", store_rxcdtype(o, v->value));
2209                 CV_F("rxsdtype", store_rxsdtype(o, v->value));
2210                 CV_F("rxctcssfreq", store_rxctcssfreq(o, v->value));
2211                 CV_F("txctcssfreq", store_txctcssfreq(o, v->value));
2212                 CV_F("rxgain", store_rxgain(o, v->value));
2213                 CV_BOOL("rxboostset", o->rxboostset);
2214                 CV_UINT("rxctcssrelax", o->rxctcssrelax);
2215                 CV_F("txtoctype", store_txtoctype(o, v->value));
2216                 CV_UINT("hdwtype", o->hdwtype);
2217                 CV_UINT("duplex", o->radioduplex);
2218
2219                 CV_END;
2220         }
2221         
2222         cfg1 = ast_config_load(config1, config_flags);
2223         if (!cfg1) {
2224                 o->rxmixerset = 500;
2225                 o->txmixaset = 500;
2226                 o->txmixbset = 500;
2227                 o->rxvoiceadj = 0.5;
2228                 o->rxctcssadj = 0.5;
2229                 o->txctcssadj = 200;
2230                 o->rxsquelchadj = 500;
2231                 ast_log(LOG_WARNING, "File %s not found, using default parameters.\n", config1);
2232         } else  {
2233                 for (v = ast_variable_browse(cfg1, ctg); v; v = v->next) {
2234         
2235                         CV_START(v->name, v->value);
2236                         CV_UINT("rxmixerset", o->rxmixerset);
2237                         CV_UINT("txmixaset", o->txmixaset);
2238                         CV_UINT("txmixbset", o->txmixbset);
2239                         CV_F("rxvoiceadj", store_rxvoiceadj(o, v->value));
2240                         CV_F("rxctcssadj", store_rxctcssadj(o, v->value));
2241                         CV_UINT("txctcssadj", o->txctcssadj);
2242                         CV_UINT("rxsquelchadj", o->rxsquelchadj);
2243                         CV_END;
2244                 }
2245                 ast_config_destroy(cfg1);
2246         }
2247
2248         o->debuglevel = 0;
2249
2250         if (o == &usbradio_default)             /* we are done with the default */
2251                 return NULL;
2252
2253         o->lastopen = ast_tvnow();      /* don't leave it 0 or tvdiff may wrap */
2254         o->dsp = ast_dsp_new();
2255         if (o->dsp) {
2256                 ast_dsp_set_features(o->dsp, DSP_FEATURE_DTMF_DETECT);
2257                 ast_dsp_digitmode(o->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
2258         }
2259
2260         if (o->rxctcssfreq != 0 && o->rxdemod == RX_AUDIO_SPEAKER)
2261                 ast_log(LOG_ERROR, "Incompatable Options  o->rxctcssfreq=%f and o->rxdemod=speaker\n", o->rxctcssfreq); 
2262
2263         if (o->pmrChan == NULL) {
2264                 t_pmr_chan tChan;
2265
2266                 memset(&tChan, 0, sizeof(tChan));
2267
2268                 tChan.rxDemod = o->rxdemod;
2269                 tChan.rxCdType = o->rxcdtype;
2270
2271                 tChan.txMod = o->txprelim;
2272
2273                 tChan.txMixA = o->txmixa;
2274                 tChan.txMixB = o->txmixb;
2275
2276                 tChan.rxCpuSaver = o->rxcpusaver;
2277                 tChan.txCpuSaver = o->txcpusaver;
2278
2279                 tChan.rxCtcssFreq = o->rxctcssfreq;
2280                 tChan.txCtcssFreq = o->txctcssfreq;
2281
2282                 o->pmrChan = createPmrChannel(&tChan, FRAME_SIZE);
2283
2284                 o->pmrChan->radioDuplex = o->radioduplex;
2285
2286                 o->pmrChan->rxCpuSaver = o->rxcpusaver;
2287                 o->pmrChan->txCpuSaver = o->txcpusaver;
2288
2289                 *(o->pmrChan->prxSquelchAdjust) = 
2290                         ((999 - o->rxsquelchadj) * 32767) / 1000;
2291
2292                 o->pmrChan->spsRx->outputGain = o->rxvoiceadj*M_Q8;
2293
2294                 o->pmrChan->txTocType = o->txtoctype;
2295
2296                 if ((o->txmixa == TX_OUT_LSD) ||
2297                         (o->txmixa == TX_OUT_COMPOSITE) ||
2298                         (o->txmixb == TX_OUT_LSD) ||
2299                         (o->txmixb == TX_OUT_COMPOSITE)) {
2300                         *(o->pmrChan->prxCtcssAdjust) = o->rxctcssadj * M_Q8;
2301                         set_txctcss_level(o);
2302                 }
2303
2304                 o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
2305
2306         }
2307
2308         if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
2309                 (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE))
2310                 ast_log(LOG_ERROR, "No txvoice output configured.\n");
2311
2312         if (o->txctcssfreq && 
2313             o->txmixa != TX_OUT_LSD && o->txmixa != TX_OUT_COMPOSITE  &&
2314                 o->txmixb != TX_OUT_LSD && o->txmixb != TX_OUT_COMPOSITE)
2315                 ast_log(LOG_ERROR, "No txtone output configured.\n");
2316
2317         if (o->rxctcssfreq && o->pmrChan->rxCtcssIndex < 0)
2318                 ast_log(LOG_ERROR, "Invalid CTCSS Frequency.\n");
2319
2320         /* RxTestIt(o); */
2321
2322         mixer_write(o);
2323         mult_set(o);    
2324         hidhdwconfig(o);
2325
2326         /* pmrdump(o); */
2327
2328         /* link into list of devices */
2329         if (o != &usbradio_default) {
2330                 o->next = usbradio_default.next;
2331                 usbradio_default.next = o;
2332         }
2333         return o;
2334 }
2335
2336 #if     DEBUG_FILETEST == 1
2337 /*
2338         Test It on a File
2339 */
2340 int RxTestIt(struct chan_usbradio_pvt *o)
2341 {
2342         const int numSamples = SAMPLES_PER_BLOCK;
2343         const int numChannels = 16;
2344
2345         i16 sample, i, ii;
2346         
2347         i32 txHangTime;
2348
2349         i16 txEnable;
2350
2351         t_pmr_chan tChan;
2352         t_pmr_chan *pChan;
2353
2354         FILE *hInput = NULL, *hOutput = NULL, *hOutputTx = NULL;
2355  
2356         i16 iBuff[numSamples * 2 * 6], oBuff[numSamples];
2357
2358         ast_debug(4, "RxTestIt()\n");
2359
2360         pChan = o->pmrChan;
2361         pChan->b.txCapture = 1;
2362         pChan->b.rxCapture = 1;
2363
2364         txEnable = 0;
2365
2366         hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm", "r");
2367         if (!hInput){
2368                 ast_debug(4, " RxTestIt() File Not Found.\n");
2369                 return 0;
2370         }
2371         hOutput = fopen("/usr/src/xpmr/testdata/rx_debug.pcm", "w");
2372
2373         ast_debug(4, " RxTestIt() Working...\n");
2374                                 
2375         while (!feof(hInput)) {
2376                 fread((void *)iBuff, 2, numSamples * 2 * 6, hInput);
2377                  
2378                 if (txHangTime)
2379                         txHangTime -= numSamples;
2380                 if (txHangTime < 0)
2381                         txHangTime = 0;
2382                 
2383                 if (pChan->rxCtcss->decode)
2384                         txHangTime = (8000 / 1000 * 2000);
2385
2386                 if (pChan->rxCtcss->decode && !txEnable) {
2387                         txEnable = 1;
2388                         /* pChan->inputBlanking = (8000 / 1000 * 200); */
2389                 } else if (!pChan->rxCtcss->decode && txEnable) {
2390                         txEnable = 0;
2391                 }
2392
2393                 PmrRx(pChan, iBuff, oBuff);
2394
2395                 fwrite((void *)pChan->prxDebug, 2, numSamples * numChannels, hOutput);
2396         }
2397         pChan->b.txCapture = 0;
2398         pChan->b.rxCapture = 0;
2399
2400         if (hInput)
2401                 fclose(hInput);
2402         if (hOutput)
2403                 fclose(hOutput);
2404
2405         ast_debug(4, " RxTestIt() Complete.\n");
2406
2407         return 0;
2408 }
2409 #endif
2410
2411 #include "./xpmr/xpmr.c"
2412 /*
2413 */
2414 static int load_module(void)
2415 {
2416         struct ast_config *cfg = NULL;
2417         char *ctg = NULL;
2418         struct ast_flags config_flags = { 0 };
2419
2420         /* Copy the default jb config over global_jbconf */
2421         memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2422
2423         /* load config file */
2424         if (!(cfg = ast_config_load(config, config_flags))) {
2425                 ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
2426                 return AST_MODULE_LOAD_DECLINE;
2427         }
2428
2429         do {
2430                 store_config(cfg, ctg);
2431         } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
2432
2433         ast_config_destroy(cfg);
2434
2435         if (find_desc(usbradio_active) == NULL) {
2436                 ast_log(LOG_NOTICE, "Device %s not found\n", usbradio_active);
2437                 /* XXX we could default to 'dsp' perhaps ? */
2438                 /* XXX should cleanup allocated memory etc. */
2439                 return AST_MODULE_LOAD_FAILURE;
2440         }
2441
2442         if (ast_channel_register(&usbradio_tech)) {
2443                 ast_log(LOG_ERROR, "Unable to register channel type 'usb'\n");
2444                 return AST_MODULE_LOAD_FAILURE;
2445         }
2446
2447         ast_cli_register_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
2448
2449         return AST_MODULE_LOAD_SUCCESS;
2450 }
2451 /*
2452 */
2453 static int unload_module(void)
2454 {
2455         struct chan_usbradio_pvt *o;
2456
2457         ast_log(LOG_WARNING, "unload_module() called\n");
2458
2459         ast_channel_unregister(&usbradio_tech);
2460         ast_cli_unregister_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
2461
2462         for (o = usbradio_default.next; o; o = o->next) {
2463
2464                 ast_log(LOG_WARNING, "destroyPmrChannel() called\n");
2465                 if (o->pmrChan)
2466                         destroyPmrChannel(o->pmrChan);
2467                 
2468                 #if DEBUG_CAPTURES == 1
2469                 if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
2470                 if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
2471                 if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
2472                 if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
2473                 if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
2474                 if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
2475                 #endif
2476
2477                 close(o->sounddev);
2478                 if (o->dsp)
2479                         ast_dsp_free(o->dsp);
2480                 if (o->owner)
2481                         ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
2482                 if (o->owner)                   /* XXX how ??? */
2483                         return -1;
2484                 /* XXX what about the thread ? */
2485                 /* XXX what about the memory allocated ? */
2486         }
2487         return 0;
2488 }
2489
2490 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "usb Console Channel Driver");
2491
2492 /*      end of file */
2493
2494