00001 #define NEW_ASTERISK
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include "asterisk.h"
00058
00059 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 238497 $")
00060
00061 #include <stdio.h>
00062 #include <ctype.h>
00063 #include <math.h>
00064 #include <string.h>
00065 #include <unistd.h>
00066 #ifdef HAVE_SYS_IO_H
00067 #include <sys/io.h>
00068 #endif
00069 #include <sys/ioctl.h>
00070 #include <fcntl.h>
00071 #include <sys/time.h>
00072 #include <stdlib.h>
00073 #include <errno.h>
00074 #include <usb.h>
00075 #include <alsa/asoundlib.h>
00076
00077
00078 #ifdef RADIO_XPMRX
00079 #define HAVE_XPMRX 1
00080 #endif
00081
00082 #define CHAN_USBRADIO 1
00083 #define DEBUG_USBRADIO 0
00084 #define DEBUG_CAPTURES 1
00085 #define DEBUG_CAP_RX_OUT 0
00086 #define DEBUG_CAP_TX_OUT 0
00087 #define DEBUG_FILETEST 0
00088
00089 #define RX_CAP_RAW_FILE "/tmp/rx_cap_in.pcm"
00090 #define RX_CAP_TRACE_FILE "/tmp/rx_trace.pcm"
00091 #define RX_CAP_OUT_FILE "/tmp/rx_cap_out.pcm"
00092
00093 #define TX_CAP_RAW_FILE "/tmp/tx_cap_in.pcm"
00094 #define TX_CAP_TRACE_FILE "/tmp/tx_trace.pcm"
00095 #define TX_CAP_OUT_FILE "/tmp/tx_cap_out.pcm"
00096
00097 #define MIXER_PARAM_MIC_PLAYBACK_SW "Mic Playback Switch"
00098 #define MIXER_PARAM_MIC_PLAYBACK_VOL "Mic Playback Volume"
00099 #define MIXER_PARAM_MIC_CAPTURE_SW "Mic Capture Switch"
00100 #define MIXER_PARAM_MIC_CAPTURE_VOL "Mic Capture Volume"
00101 #define MIXER_PARAM_MIC_BOOST "Auto Gain Control"
00102 #define MIXER_PARAM_SPKR_PLAYBACK_SW "Speaker Playback Switch"
00103 #define MIXER_PARAM_SPKR_PLAYBACK_VOL "Speaker Playback Volume"
00104
00105 #define DELIMCHR ','
00106 #define QUOTECHR 34
00107
00108 #define READERR_THRESHOLD 50
00109
00110 #include "./xpmr/xpmr.h"
00111 #ifdef HAVE_XPMRX
00112 #include "./xpmrx/xpmrx.h"
00113 #include "./xpmrx/bitweight.h"
00114 #endif
00115
00116 #if 0
00117 #define traceusb1(a) {printf a;}
00118 #else
00119 #define traceusb1(a)
00120 #endif
00121
00122 #if 0
00123 #define traceusb2(a) {printf a;}
00124 #else
00125 #define traceusb2(a)
00126 #endif
00127
00128 #ifdef __linux
00129 #include <linux/soundcard.h>
00130 #elif defined(__FreeBSD__)
00131 #include <sys/soundcard.h>
00132 #else
00133 #include <soundcard.h>
00134 #endif
00135
00136 #include "asterisk/lock.h"
00137 #include "asterisk/frame.h"
00138 #include "asterisk/logger.h"
00139 #include "asterisk/callerid.h"
00140 #include "asterisk/channel.h"
00141 #include "asterisk/module.h"
00142 #include "asterisk/options.h"
00143 #include "asterisk/pbx.h"
00144 #include "asterisk/config.h"
00145 #include "asterisk/cli.h"
00146 #include "asterisk/utils.h"
00147 #include "asterisk/causes.h"
00148 #include "asterisk/endian.h"
00149 #include "asterisk/stringfields.h"
00150 #include "asterisk/abstract_jb.h"
00151 #include "asterisk/musiconhold.h"
00152 #include "asterisk/dsp.h"
00153
00154 #ifndef NEW_ASTERISK
00155
00156
00157 #include "busy.h"
00158 #include "ringtone.h"
00159 #include "ring10.h"
00160 #include "answer.h"
00161
00162 #endif
00163
00164 #define C108_VENDOR_ID 0x0d8c
00165 #define C108_PRODUCT_ID 0x000c
00166 #define C108_HID_INTERFACE 3
00167
00168 #define HID_REPORT_GET 0x01
00169 #define HID_REPORT_SET 0x09
00170
00171 #define HID_RT_INPUT 0x01
00172 #define HID_RT_OUTPUT 0x02
00173
00174 #define EEPROM_START_ADDR 6
00175 #define EEPROM_END_ADDR 63
00176 #define EEPROM_PHYSICAL_LEN 64
00177 #define EEPROM_TEST_ADDR EEPROM_END_ADDR
00178 #define EEPROM_MAGIC_ADDR 6
00179 #define EEPROM_MAGIC 34329
00180 #define EEPROM_CS_ADDR 62
00181 #define EEPROM_RXMIXERSET 8
00182 #define EEPROM_TXMIXASET 9
00183 #define EEPROM_TXMIXBSET 10
00184 #define EEPROM_RXVOICEADJ 11
00185 #define EEPROM_RXCTCSSADJ 13
00186 #define EEPROM_TXCTCSSADJ 15
00187 #define EEPROM_RXSQUELCHADJ 16
00188
00189
00190 static struct ast_jb_conf default_jbconf =
00191 {
00192 .flags = 0,
00193 .max_size = -1,
00194 .resync_threshold = -1,
00195 .impl = "",
00196 };
00197 static struct ast_jb_conf global_jbconf;
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 #define M_START(var, val) \
00291 char *__s = var; char *__val = val;
00292 #define M_END(x) x;
00293 #define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
00294 #define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
00295 #define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
00296 #define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 #define FRAME_SIZE 160
00329 #define QUEUE_SIZE 2
00330
00331 #if defined(__FreeBSD__)
00332 #define FRAGS 0x8
00333 #else
00334 #define FRAGS ( ( (6 * 5) << 16 ) | 0xc )
00335 #endif
00336
00337
00338
00339
00340
00341 #define TEXT_SIZE 256
00342
00343 #if 0
00344 #define TRYOPEN 1
00345 #endif
00346 #define O_CLOSE 0x444
00347
00348 #if defined( __OpenBSD__ ) || defined( __NetBSD__ )
00349 #define DEV_DSP "/dev/audio"
00350 #else
00351 #define DEV_DSP "/dev/dsp"
00352 #endif
00353
00354 static const char *config = "usbradio.conf";
00355 #define config1 "usbradio_tune_%s.conf"
00356
00357 static FILE *frxcapraw = NULL, *frxcaptrace = NULL, *frxoutraw = NULL;
00358 static FILE *ftxcapraw = NULL, *ftxcaptrace = NULL, *ftxoutraw = NULL;
00359
00360 static char *usb_device_list = NULL;
00361 static int usb_device_list_size = 0;
00362
00363 static int usbradio_debug;
00364 #if 0 //maw asdf sph
00365 static int usbradio_debug_level = 0;
00366 #endif
00367
00368 enum {RX_AUDIO_NONE,RX_AUDIO_SPEAKER,RX_AUDIO_FLAT};
00369 enum {CD_IGNORE,CD_XPMR_NOISE,CD_XPMR_VOX,CD_HID,CD_HID_INVERT};
00370 enum {SD_IGNORE,SD_HID,SD_HID_INVERT,SD_XPMR};
00371 enum {RX_KEY_CARRIER,RX_KEY_CARRIER_CODE};
00372 enum {TX_OUT_OFF,TX_OUT_VOICE,TX_OUT_LSD,TX_OUT_COMPOSITE,TX_OUT_AUX};
00373 enum {TOC_NONE,TOC_PHASE,TOC_NOTONE};
00374
00375
00376
00377
00378
00379
00380
00381
00382 struct sound {
00383 int ind;
00384 char *desc;
00385 short *data;
00386 int datalen;
00387 int samplen;
00388 int silencelen;
00389 int repeat;
00390 };
00391
00392 #ifndef NEW_ASTERISK
00393
00394 static struct sound sounds[] = {
00395 { AST_CONTROL_RINGING, "RINGING", ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
00396 { AST_CONTROL_BUSY, "BUSY", busy, sizeof(busy)/2, 4000, 4000, 1 },
00397 { AST_CONTROL_CONGESTION, "CONGESTION", busy, sizeof(busy)/2, 2000, 2000, 1 },
00398 { AST_CONTROL_RING, "RING10", ring10, sizeof(ring10)/2, 16000, 32000, 1 },
00399 { AST_CONTROL_ANSWER, "ANSWER", answer, sizeof(answer)/2, 2200, 0, 0 },
00400 { -1, NULL, 0, 0, 0, 0 },
00401 };
00402
00403 #endif
00404
00405
00406
00407
00408
00409
00410
00411
00412 struct chan_usbradio_pvt {
00413 struct chan_usbradio_pvt *next;
00414
00415 char *name;
00416 #ifndef NEW_ASTERISK
00417
00418
00419
00420
00421
00422
00423
00424 int sndcmd[2];
00425 int cursound;
00426 int sampsent;
00427 int nosound;
00428 #endif
00429
00430 int pttkick[2];
00431 int total_blocks;
00432 int sounddev;
00433 enum { M_UNSET, M_FULL, M_READ, M_WRITE } duplex;
00434 i16 cdMethod;
00435 int autoanswer;
00436 int autohangup;
00437 int hookstate;
00438 unsigned int queuesize;
00439 unsigned int frags;
00440
00441 int warned;
00442 #define WARN_used_blocks 1
00443 #define WARN_speed 2
00444 #define WARN_frag 4
00445 int w_errors;
00446 struct timeval lastopen;
00447
00448 int overridecontext;
00449 int mute;
00450
00451
00452
00453
00454 #define BOOST_SCALE (1<<9)
00455 #define BOOST_MAX 40
00456 int boost;
00457 char devicenum;
00458 char devstr[128];
00459 int spkrmax;
00460 int micmax;
00461
00462 #ifndef NEW_ASTERISK
00463 pthread_t sthread;
00464 #endif
00465 pthread_t hidthread;
00466
00467 int stophid;
00468 FILE *hkickhid;
00469
00470 struct ast_channel *owner;
00471 char ext[AST_MAX_EXTENSION];
00472 char ctx[AST_MAX_CONTEXT];
00473 char language[MAX_LANGUAGE];
00474 char cid_name[256];
00475 char cid_num[256];
00476 char mohinterpret[MAX_MUSICCLASS];
00477
00478
00479 char usbradio_write_buf[FRAME_SIZE * 2 * 2 * 6];
00480 char usbradio_write_buf_1[FRAME_SIZE * 2 * 2* 6];
00481
00482 int usbradio_write_dst;
00483
00484
00485
00486 char usbradio_read_buf[FRAME_SIZE * (2 * 12) + AST_FRIENDLY_OFFSET];
00487 char usbradio_read_buf_8k[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
00488 int readpos;
00489 struct ast_frame read_f;
00490
00491 char debuglevel;
00492 char radioduplex;
00493 char wanteeprom;
00494
00495 int tracetype;
00496 int tracelevel;
00497 char area;
00498 char rptnum;
00499 int idleinterval;
00500 int turnoffs;
00501 int txsettletime;
00502 char ukey[48];
00503
00504 char lastrx;
00505 char rxhidsq;
00506 char rxcarrierdetect;
00507 char rxctcssdecode;
00508
00509 int rxdcsdecode;
00510 int rxlsddecode;
00511
00512 char rxkeytype;
00513 char rxkeyed;
00514
00515 char lasttx;
00516 char txkeyed;
00517 char txchankey;
00518 char txtestkey;
00519
00520 time_t lasthidtime;
00521 struct ast_dsp *dsp;
00522
00523 t_pmr_chan *pmrChan;
00524
00525 char rxcpusaver;
00526 char txcpusaver;
00527
00528 char rxdemod;
00529 float rxgain;
00530 char rxcdtype;
00531 char rxsdtype;
00532 int rxsquelchadj;
00533 int rxsqvoxadj;
00534 char txtoctype;
00535
00536 char txprelim;
00537 float txctcssgain;
00538 char txmixa;
00539 char txmixb;
00540
00541 char invertptt;
00542
00543 char rxctcssrelax;
00544 float rxctcssgain;
00545
00546 char txctcssdefault[16];
00547 char rxctcssfreqs[512];
00548 char txctcssfreqs[512];
00549
00550 char txctcssfreq[32];
00551 char rxctcssfreq[32];
00552
00553 char numrxctcssfreqs;
00554 char numtxctcssfreqs;
00555
00556 char *rxctcss[CTCSS_NUM_CODES];
00557 char *txctcss[CTCSS_NUM_CODES];
00558
00559 int txfreq;
00560 int rxfreq;
00561
00562
00563 char set_txctcssdefault[16];
00564 char set_txctcssfreq[16];
00565 char set_rxctcssfreq[16];
00566
00567 char set_numrxctcssfreqs;
00568 char set_numtxctcssfreqs;
00569
00570 char set_rxctcssfreqs[16];
00571 char set_txctcssfreqs[16];
00572
00573 char *set_rxctcss;
00574 char *set_txctcss;
00575
00576 int set_txfreq;
00577 int set_rxfreq;
00578
00579
00580 int rxmixerset;
00581 int rxboostset;
00582 float rxvoiceadj;
00583 float rxctcssadj;
00584 int txmixaset;
00585 int txmixbset;
00586 int txctcssadj;
00587
00588 int hdwtype;
00589 int hid_gpio_ctl;
00590 int hid_gpio_ctl_loc;
00591 int hid_io_cor;
00592 int hid_io_cor_loc;
00593 int hid_io_ctcss;
00594 int hid_io_ctcss_loc;
00595 int hid_io_ptt;
00596 int hid_gpio_loc;
00597
00598 struct {
00599 unsigned rxcapraw:1;
00600 unsigned txcapraw:1;
00601 unsigned txcap2:1;
00602 unsigned rxcap2:1;
00603 unsigned rxplmon:1;
00604 unsigned remoted:1;
00605 unsigned txpolarity:1;
00606 unsigned rxpolarity:1;
00607 unsigned dcstxpolarity:1;
00608 unsigned dcsrxpolarity:1;
00609 unsigned lsdtxpolarity:1;
00610 unsigned lsdrxpolarity:1;
00611 unsigned loopback:1;
00612 unsigned radioactive:1;
00613 }b;
00614 unsigned short eeprom[EEPROM_PHYSICAL_LEN];
00615 char eepromctl;
00616 ast_mutex_t eepromlock;
00617
00618 struct usb_dev_handle *usb_handle;
00619 int readerrs;
00620 };
00621
00622
00623 static struct chan_usbradio_pvt usbradio_default = {
00624 #ifndef NEW_ASTERISK
00625 .cursound = -1,
00626 #endif
00627 .sounddev = -1,
00628 .duplex = M_UNSET,
00629 .autoanswer = 1,
00630 .autohangup = 1,
00631 .queuesize = QUEUE_SIZE,
00632 .frags = FRAGS,
00633 .ext = "s",
00634 .ctx = "default",
00635 .readpos = AST_FRIENDLY_OFFSET,
00636 .lastopen = { 0, 0 },
00637 .boost = BOOST_SCALE,
00638 .wanteeprom = 1,
00639 .area = 0,
00640 .rptnum = 0,
00641 };
00642
00643
00644
00645 static void store_txtoctype(struct chan_usbradio_pvt *o, char *s);
00646 static int hidhdwconfig(struct chan_usbradio_pvt *o);
00647 static int set_txctcss_level(struct chan_usbradio_pvt *o);
00648 static void pmrdump(struct chan_usbradio_pvt *o);
00649 static void mult_set(struct chan_usbradio_pvt *o);
00650 static int mult_calc(int value);
00651 static void mixer_write(struct chan_usbradio_pvt *o);
00652 static void tune_rxinput(int fd, struct chan_usbradio_pvt *o);
00653 static void tune_rxvoice(int fd, struct chan_usbradio_pvt *o);
00654 static void tune_rxctcss(int fd, struct chan_usbradio_pvt *o);
00655 static void tune_txoutput(struct chan_usbradio_pvt *o, int value, int fd);
00656 static void tune_write(struct chan_usbradio_pvt *o);
00657
00658 static char *usbradio_active;
00659
00660 static int setformat(struct chan_usbradio_pvt *o, int mode);
00661
00662 static struct ast_channel *usbradio_request(const char *type, int format, void *data
00663 , int *cause);
00664 static int usbradio_digit_begin(struct ast_channel *c, char digit);
00665 static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00666 static int usbradio_text(struct ast_channel *c, const char *text);
00667 static int usbradio_hangup(struct ast_channel *c);
00668 static int usbradio_answer(struct ast_channel *c);
00669 static struct ast_frame *usbradio_read(struct ast_channel *chan);
00670 static int usbradio_call(struct ast_channel *c, char *dest, int timeout);
00671 static int usbradio_write(struct ast_channel *chan, struct ast_frame *f);
00672 static int usbradio_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
00673 static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00674 static int xpmr_config(struct chan_usbradio_pvt *o);
00675
00676 #if DEBUG_FILETEST == 1
00677 static int RxTestIt(struct chan_usbradio_pvt *o);
00678 #endif
00679
00680 static char tdesc[] = "USB (CM108) Radio Channel Driver";
00681
00682 static const struct ast_channel_tech usbradio_tech = {
00683 .type = "Radio",
00684 .description = tdesc,
00685 .capabilities = AST_FORMAT_SLINEAR,
00686 .requester = usbradio_request,
00687 .send_digit_begin = usbradio_digit_begin,
00688 .send_digit_end = usbradio_digit_end,
00689 .send_text = usbradio_text,
00690 .hangup = usbradio_hangup,
00691 .answer = usbradio_answer,
00692 .read = usbradio_read,
00693 .call = usbradio_call,
00694 .write = usbradio_write,
00695 .indicate = usbradio_indicate,
00696 .fixup = usbradio_fixup,
00697 };
00698
00699
00700
00701
00702
00703
00704
00705 static int amixer_max(int devnum,char *param)
00706 {
00707 int rv,type;
00708 char str[100];
00709 snd_hctl_t *hctl;
00710 snd_ctl_elem_id_t *id;
00711 snd_hctl_elem_t *elem;
00712 snd_ctl_elem_info_t *info;
00713
00714 sprintf(str,"hw:%d",devnum);
00715 if (snd_hctl_open(&hctl, str, 0)) return(-1);
00716 snd_hctl_load(hctl);
00717 snd_ctl_elem_id_alloca(&id);
00718 snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
00719 snd_ctl_elem_id_set_name(id, param);
00720 elem = snd_hctl_find_elem(hctl, id);
00721 if (!elem)
00722 {
00723 snd_hctl_close(hctl);
00724 return(-1);
00725 }
00726 snd_ctl_elem_info_alloca(&info);
00727 snd_hctl_elem_info(elem,info);
00728 type = snd_ctl_elem_info_get_type(info);
00729 rv = 0;
00730 switch(type)
00731 {
00732 case SND_CTL_ELEM_TYPE_INTEGER:
00733 rv = snd_ctl_elem_info_get_max(info);
00734 break;
00735 case SND_CTL_ELEM_TYPE_BOOLEAN:
00736 rv = 1;
00737 break;
00738 }
00739 snd_hctl_close(hctl);
00740 return(rv);
00741 }
00742
00743
00744
00745
00746
00747
00748
00749 static int setamixer(int devnum,char *param, int v1, int v2)
00750 {
00751 int type;
00752 char str[100];
00753 snd_hctl_t *hctl;
00754 snd_ctl_elem_id_t *id;
00755 snd_ctl_elem_value_t *control;
00756 snd_hctl_elem_t *elem;
00757 snd_ctl_elem_info_t *info;
00758
00759 sprintf(str,"hw:%d",devnum);
00760 if (snd_hctl_open(&hctl, str, 0)) return(-1);
00761 snd_hctl_load(hctl);
00762 snd_ctl_elem_id_alloca(&id);
00763 snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
00764 snd_ctl_elem_id_set_name(id, param);
00765 elem = snd_hctl_find_elem(hctl, id);
00766 if (!elem)
00767 {
00768 snd_hctl_close(hctl);
00769 return(-1);
00770 }
00771 snd_ctl_elem_info_alloca(&info);
00772 snd_hctl_elem_info(elem,info);
00773 type = snd_ctl_elem_info_get_type(info);
00774 snd_ctl_elem_value_alloca(&control);
00775 snd_ctl_elem_value_set_id(control, id);
00776 switch(type)
00777 {
00778 case SND_CTL_ELEM_TYPE_INTEGER:
00779 snd_ctl_elem_value_set_integer(control, 0, v1);
00780 if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2);
00781 break;
00782 case SND_CTL_ELEM_TYPE_BOOLEAN:
00783 snd_ctl_elem_value_set_integer(control, 0, (v1 != 0));
00784 break;
00785 }
00786 if (snd_hctl_elem_write(elem, control))
00787 {
00788 snd_hctl_close(hctl);
00789 return(-1);
00790 }
00791 snd_hctl_close(hctl);
00792 return(0);
00793 }
00794
00795 static void hid_set_outputs(struct usb_dev_handle *handle,
00796 unsigned char *outputs)
00797 {
00798 usleep(1500);
00799 usb_control_msg(handle,
00800 USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00801 HID_REPORT_SET,
00802 0 + (HID_RT_OUTPUT << 8),
00803 C108_HID_INTERFACE,
00804 (char*)outputs, 4, 5000);
00805 }
00806
00807 static void hid_get_inputs(struct usb_dev_handle *handle,
00808 unsigned char *inputs)
00809 {
00810 usleep(1500);
00811 usb_control_msg(handle,
00812 USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00813 HID_REPORT_GET,
00814 0 + (HID_RT_INPUT << 8),
00815 C108_HID_INTERFACE,
00816 (char*)inputs, 4, 5000);
00817 }
00818
00819 static unsigned short read_eeprom(struct usb_dev_handle *handle, int addr)
00820 {
00821 unsigned char buf[4];
00822
00823 buf[0] = 0x80;
00824 buf[1] = 0;
00825 buf[2] = 0;
00826 buf[3] = 0x80 | (addr & 0x3f);
00827 hid_set_outputs(handle,buf);
00828 memset(buf,0,sizeof(buf));
00829 hid_get_inputs(handle,buf);
00830 return(buf[1] + (buf[2] << 8));
00831 }
00832
00833 static void write_eeprom(struct usb_dev_handle *handle, int addr,
00834 unsigned short data)
00835 {
00836
00837 unsigned char buf[4];
00838
00839 buf[0] = 0x80;
00840 buf[1] = data & 0xff;
00841 buf[2] = data >> 8;
00842 buf[3] = 0xc0 | (addr & 0x3f);
00843 hid_set_outputs(handle,buf);
00844 }
00845
00846 static unsigned short get_eeprom(struct usb_dev_handle *handle,
00847 unsigned short *buf)
00848 {
00849 int i;
00850 unsigned short cs;
00851
00852 cs = 0xffff;
00853 for(i = EEPROM_START_ADDR; i < EEPROM_END_ADDR; i++)
00854 {
00855 cs += buf[i] = read_eeprom(handle,i);
00856 }
00857 return(cs);
00858 }
00859
00860 static void put_eeprom(struct usb_dev_handle *handle,unsigned short *buf)
00861 {
00862 int i;
00863 unsigned short cs;
00864
00865 cs = 0xffff;
00866 buf[EEPROM_MAGIC_ADDR] = EEPROM_MAGIC;
00867 for(i = EEPROM_START_ADDR; i < EEPROM_CS_ADDR; i++)
00868 {
00869 write_eeprom(handle,i,buf[i]);
00870 cs += buf[i];
00871 }
00872 buf[EEPROM_CS_ADDR] = (65535 - cs) + 1;
00873 write_eeprom(handle,i,buf[EEPROM_CS_ADDR]);
00874 }
00875
00876 static struct usb_device *hid_device_init(char *desired_device)
00877 {
00878 struct usb_bus *usb_bus;
00879 struct usb_device *dev;
00880 char devstr[200],str[200],desdev[200],*cp;
00881 int i;
00882 FILE *fp;
00883
00884 usb_init();
00885 usb_find_busses();
00886 usb_find_devices();
00887 for (usb_bus = usb_busses;
00888 usb_bus;
00889 usb_bus = usb_bus->next) {
00890 for (dev = usb_bus->devices;
00891 dev;
00892 dev = dev->next) {
00893 if ((dev->descriptor.idVendor
00894 == C108_VENDOR_ID) &&
00895 (dev->descriptor.idProduct
00896 == C108_PRODUCT_ID))
00897 {
00898 sprintf(devstr,"%s/%s", usb_bus->dirname,dev->filename);
00899 for(i = 0; i < 32; i++)
00900 {
00901 sprintf(str,"/proc/asound/card%d/usbbus",i);
00902 fp = fopen(str,"r");
00903 if (!fp) continue;
00904 if ((!fgets(desdev,sizeof(desdev) - 1,fp)) || (!desdev[0]))
00905 {
00906 fclose(fp);
00907 continue;
00908 }
00909 fclose(fp);
00910 if (desdev[strlen(desdev) - 1] == '\n')
00911 desdev[strlen(desdev) -1 ] = 0;
00912 if (strcasecmp(desdev,devstr)) continue;
00913 if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
00914 else strcpy(str,"/sys/class/sound/dsp/device");
00915 memset(desdev,0,sizeof(desdev));
00916 if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
00917 {
00918 sprintf(str,"/sys/class/sound/controlC%d/device",i);
00919 memset(desdev,0,sizeof(desdev));
00920 if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
00921 }
00922 cp = strrchr(desdev,'/');
00923 if (cp) *cp = 0; else continue;
00924 cp = strrchr(desdev,'/');
00925 if (!cp) continue;
00926 cp++;
00927 break;
00928 }
00929 if (i >= 32) continue;
00930 if (!strcmp(cp,desired_device)) return dev;
00931 }
00932
00933 }
00934 }
00935 return NULL;
00936 }
00937
00938 static int hid_device_mklist(void)
00939 {
00940 struct usb_bus *usb_bus;
00941 struct usb_device *dev;
00942 char devstr[200],str[200],desdev[200],*cp;
00943 int i;
00944 FILE *fp;
00945
00946 usb_device_list = ast_malloc(2);
00947 if (!usb_device_list) return -1;
00948 memset(usb_device_list,0,2);
00949
00950 usb_init();
00951 usb_find_busses();
00952 usb_find_devices();
00953 for (usb_bus = usb_busses;
00954 usb_bus;
00955 usb_bus = usb_bus->next) {
00956 for (dev = usb_bus->devices;
00957 dev;
00958 dev = dev->next) {
00959 if ((dev->descriptor.idVendor
00960 == C108_VENDOR_ID) &&
00961 (dev->descriptor.idProduct
00962 == C108_PRODUCT_ID))
00963 {
00964 sprintf(devstr,"%s/%s", usb_bus->dirname,dev->filename);
00965 for(i = 0;i < 32; i++)
00966 {
00967 sprintf(str,"/proc/asound/card%d/usbbus",i);
00968 fp = fopen(str,"r");
00969 if (!fp) continue;
00970 if ((!fgets(desdev,sizeof(desdev) - 1,fp)) || (!desdev[0]))
00971 {
00972 fclose(fp);
00973 continue;
00974 }
00975 fclose(fp);
00976 if (desdev[strlen(desdev) - 1] == '\n')
00977 desdev[strlen(desdev) -1 ] = 0;
00978 if (strcasecmp(desdev,devstr)) continue;
00979 if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
00980 else strcpy(str,"/sys/class/sound/dsp/device");
00981 memset(desdev,0,sizeof(desdev));
00982 if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
00983 {
00984 sprintf(str,"/sys/class/sound/controlC%d/device",i);
00985 memset(desdev,0,sizeof(desdev));
00986 if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
00987 }
00988 cp = strrchr(desdev,'/');
00989 if (cp) *cp = 0; else continue;
00990 cp = strrchr(desdev,'/');
00991 if (!cp) continue;
00992 cp++;
00993 break;
00994 }
00995 if (i >= 32) return -1;
00996 usb_device_list = ast_realloc(usb_device_list,
00997 usb_device_list_size + 2 +
00998 strlen(cp));
00999 if (!usb_device_list) return -1;
01000 usb_device_list_size += strlen(cp) + 2;
01001 i = 0;
01002 while(usb_device_list[i])
01003 {
01004 i += strlen(usb_device_list + i) + 1;
01005 }
01006 strcat(usb_device_list + i,cp);
01007 usb_device_list[strlen(cp) + i + 1] = 0;
01008 }
01009
01010 }
01011 }
01012 return 0;
01013 }
01014
01015
01016 static int usb_get_usbdev(char *devstr)
01017 {
01018 int i;
01019 char str[200],desdev[200],*cp;
01020
01021 for(i = 0;i < 32; i++)
01022 {
01023 if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
01024 else strcpy(str,"/sys/class/sound/dsp/device");
01025 memset(desdev,0,sizeof(desdev));
01026 if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
01027 {
01028 sprintf(str,"/sys/class/sound/controlC%d/device",i);
01029 memset(desdev,0,sizeof(desdev));
01030 if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
01031 }
01032 cp = strrchr(desdev,'/');
01033 if (cp) *cp = 0; else continue;
01034 cp = strrchr(desdev,'/');
01035 if (!cp) continue;
01036 cp++;
01037 if (!strcasecmp(cp,devstr)) break;
01038 }
01039 if (i >= 32) return -1;
01040 return i;
01041
01042 }
01043
01044 static int usb_list_check(char *devstr)
01045 {
01046
01047 char *s = usb_device_list;
01048
01049 if (!s) return(0);
01050 while(*s)
01051 {
01052 if (!strcasecmp(s,devstr)) return(1);
01053 s += strlen(s) + 1;
01054 }
01055 return(0);
01056 }
01057
01058
01059 static int hidhdwconfig(struct chan_usbradio_pvt *o)
01060 {
01061 if(o->hdwtype==1)
01062 {
01063 o->hid_gpio_ctl = 0x08;
01064 o->hid_gpio_ctl_loc = 2;
01065 o->hid_io_cor = 4;
01066 o->hid_io_cor_loc = 1;
01067 o->hid_io_ctcss = 2;
01068 o->hid_io_ctcss_loc = 1;
01069 o->hid_io_ptt = 8;
01070 o->hid_gpio_loc = 1;
01071 }
01072 else if(o->hdwtype==0)
01073 {
01074 o->hid_gpio_ctl = 0x0c;
01075 o->hid_gpio_ctl_loc = 2;
01076 o->hid_io_cor = 2;
01077 o->hid_io_cor_loc = 0;
01078 o->hid_io_ctcss = 2;
01079 o->hid_io_ctcss_loc = 1;
01080 o->hid_io_ptt = 4;
01081 o->hid_gpio_loc = 1;
01082 }
01083 else if(o->hdwtype==3)
01084 {
01085 o->hid_gpio_ctl = 0x0c;
01086 o->hid_gpio_ctl_loc = 2;
01087 o->hid_io_cor = 2;
01088 o->hid_io_cor_loc = 0;
01089 o->hid_io_ctcss = 2;
01090 o->hid_io_ctcss_loc = 1;
01091 o->hid_io_ptt = 4;
01092 o->hid_gpio_loc = 1;
01093 }
01094
01095 return 0;
01096 }
01097
01098
01099 static void kickptt(struct chan_usbradio_pvt *o)
01100 {
01101 char c = 0;
01102
01103 if (!o) return;
01104 if (!o->pttkick) return;
01105 if (write(o->pttkick[1],&c,1) < 0) {
01106 ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
01107 }
01108 }
01109
01110
01111 static void *hidthread(void *arg)
01112 {
01113 unsigned char buf[4],bufsave[4],keyed;
01114 char lastrx, txtmp;
01115 int res;
01116 struct usb_device *usb_dev;
01117 struct usb_dev_handle *usb_handle;
01118 struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
01119 struct timeval to;
01120 fd_set rfds;
01121
01122 usb_dev = hid_device_init(o->devstr);
01123 if (usb_dev == NULL) {
01124 ast_log(LOG_ERROR,"USB HID device not found\n");
01125 pthread_exit(NULL);
01126 }
01127 usb_handle = usb_open(usb_dev);
01128 if (usb_handle == NULL) {
01129 ast_log(LOG_ERROR,"Not able to open USB device\n");
01130 pthread_exit(NULL);
01131 }
01132 if (usb_claim_interface(usb_handle,C108_HID_INTERFACE) < 0)
01133 {
01134 if (usb_detach_kernel_driver_np(usb_handle,C108_HID_INTERFACE) < 0) {
01135 ast_log(LOG_ERROR,"Not able to detach the USB device\n");
01136 pthread_exit(NULL);
01137 }
01138 if (usb_claim_interface(usb_handle,C108_HID_INTERFACE) < 0) {
01139 ast_log(LOG_ERROR,"Not able to claim the USB device\n");
01140 pthread_exit(NULL);
01141 }
01142 }
01143 memset(buf,0,sizeof(buf));
01144 buf[2] = o->hid_gpio_ctl;
01145 buf[1] = 0;
01146 hid_set_outputs(usb_handle,buf);
01147 memcpy(bufsave,buf,sizeof(buf));
01148 if (pipe(o->pttkick) == -1)
01149 {
01150 ast_log(LOG_ERROR,"Not able to create pipe\n");
01151 pthread_exit(NULL);
01152 }
01153 traceusb1(("hidthread: Starting normally on %s!!\n",o->name));
01154 lastrx = 0;
01155
01156 while(!o->stophid)
01157 {
01158 to.tv_sec = 0;
01159 to.tv_usec = 50000;
01160
01161 FD_ZERO(&rfds);
01162 FD_SET(o->pttkick[0],&rfds);
01163
01164 res = ast_select(o->pttkick[0] + 1, &rfds, NULL, NULL, &to);
01165 if (res < 0) {
01166 ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
01167 usleep(10000);
01168 continue;
01169 }
01170 if (FD_ISSET(o->pttkick[0],&rfds))
01171 {
01172 char c;
01173
01174 if (read(o->pttkick[0],&c,1) < 0) {
01175 ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
01176 }
01177 }
01178 if(o->wanteeprom)
01179 {
01180 ast_mutex_lock(&o->eepromlock);
01181 if (o->eepromctl == 1)
01182 {
01183
01184 if (!get_eeprom(usb_handle,o->eeprom))
01185 {
01186 if (o->eeprom[EEPROM_MAGIC_ADDR] != EEPROM_MAGIC)
01187 {
01188 ast_log(LOG_NOTICE,"UNSUCCESSFUL: EEPROM MAGIC NUMBER BAD on channel %s\n",o->name);
01189 }
01190 else
01191 {
01192 o->rxmixerset = o->eeprom[EEPROM_RXMIXERSET];
01193 o->txmixaset = o->eeprom[EEPROM_TXMIXASET];
01194 o->txmixbset = o->eeprom[EEPROM_TXMIXBSET];
01195 memcpy(&o->rxvoiceadj,&o->eeprom[EEPROM_RXVOICEADJ],sizeof(float));
01196 memcpy(&o->rxctcssadj,&o->eeprom[EEPROM_RXCTCSSADJ],sizeof(float));
01197 o->txctcssadj = o->eeprom[EEPROM_TXCTCSSADJ];
01198 o->rxsquelchadj = o->eeprom[EEPROM_RXSQUELCHADJ];
01199 ast_log(LOG_NOTICE,"EEPROM Loaded on channel %s\n",o->name);
01200 }
01201 }
01202 else
01203 {
01204 ast_log(LOG_NOTICE,"USB Adapter has no EEPROM installed or Checksum BAD on channel %s\n",o->name);
01205 }
01206 hid_set_outputs(usb_handle,bufsave);
01207 }
01208 if (o->eepromctl == 2)
01209 {
01210 put_eeprom(usb_handle,o->eeprom);
01211 hid_set_outputs(usb_handle,bufsave);
01212 ast_log(LOG_NOTICE,"USB Parameters written to EEPROM on %s\n",o->name);
01213 }
01214 o->eepromctl = 0;
01215 ast_mutex_unlock(&o->eepromlock);
01216 }
01217 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
01218 hid_get_inputs(usb_handle,buf);
01219 keyed = !(buf[o->hid_io_cor_loc] & o->hid_io_cor);
01220 if (keyed != o->rxhidsq)
01221 {
01222 if(o->debuglevel)printf("chan_usbradio() hidthread: update rxhidsq = %d\n",keyed);
01223 o->rxhidsq=keyed;
01224 }
01225
01226
01227 txtmp=o->pmrChan->txPttOut;
01228
01229 if (o->lasttx != txtmp)
01230 {
01231 o->pmrChan->txPttHid=o->lasttx = txtmp;
01232 if(o->debuglevel)printf("hidthread: tx set to %d\n",txtmp);
01233 buf[o->hid_gpio_loc] = 0;
01234 if (!o->invertptt)
01235 {
01236 if (txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
01237 }
01238 else
01239 {
01240 if (!txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
01241 }
01242 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
01243 memcpy(bufsave,buf,sizeof(buf));
01244 hid_set_outputs(usb_handle,buf);
01245 }
01246 time(&o->lasthidtime);
01247 }
01248 buf[o->hid_gpio_loc] = 0;
01249 if (o->invertptt) buf[o->hid_gpio_loc] = o->hid_io_ptt;
01250 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
01251 hid_set_outputs(usb_handle,buf);
01252 pthread_exit(0);
01253 }
01254
01255
01256
01257
01258 static struct chan_usbradio_pvt *find_desc(char *dev)
01259 {
01260 struct chan_usbradio_pvt *o = NULL;
01261
01262 if (!dev)
01263 ast_log(LOG_WARNING, "null dev\n");
01264
01265 for (o = usbradio_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
01266 if (!o)
01267 {
01268 ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
01269 pthread_exit(0);
01270 }
01271
01272 return o;
01273 }
01274
01275 static struct chan_usbradio_pvt *find_desc_usb(char *devstr)
01276 {
01277 struct chan_usbradio_pvt *o = NULL;
01278
01279 if (!devstr)
01280 ast_log(LOG_WARNING, "null dev\n");
01281
01282 for (o = usbradio_default.next; o && devstr && strcmp(o->devstr, devstr) != 0; o = o->next);
01283
01284 return o;
01285 }
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 #if 0
01297 static char *ast_ext_ctx(const char *src, char **ext, char **ctx)
01298 {
01299 struct chan_usbradio_pvt *o = find_desc(usbradio_active);
01300
01301 if (ext == NULL || ctx == NULL)
01302 return NULL;
01303
01304 *ext = *ctx = NULL;
01305
01306 if (src && *src != '\0')
01307 *ext = ast_strdup(src);
01308
01309 if (*ext == NULL)
01310 return NULL;
01311
01312 if (!o->overridecontext) {
01313
01314 *ctx = strrchr(*ext, '@');
01315 if (*ctx)
01316 *(*ctx)++ = '\0';
01317 }
01318
01319 return *ext;
01320 }
01321 #endif
01322
01323
01324
01325
01326 static int used_blocks(struct chan_usbradio_pvt *o)
01327 {
01328 struct audio_buf_info info;
01329
01330 if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
01331 if (!(o->warned & WARN_used_blocks)) {
01332 ast_log(LOG_WARNING, "Error reading output space\n");
01333 o->warned |= WARN_used_blocks;
01334 }
01335 return 1;
01336 }
01337
01338 if (o->total_blocks == 0) {
01339 if (0)
01340 ast_log(LOG_WARNING, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
01341 o->total_blocks = info.fragments;
01342 }
01343
01344 return o->total_blocks - info.fragments;
01345 }
01346
01347
01348 static int soundcard_writeframe(struct chan_usbradio_pvt *o, short *data)
01349 {
01350 int res;
01351
01352 if (o->sounddev < 0)
01353 setformat(o, O_RDWR);
01354 if (o->sounddev < 0)
01355 return 0;
01356
01357
01358
01359 if(!o->pmrChan->txPttIn && !o->pmrChan->txPttOut)
01360 {
01361
01362 }
01363
01364
01365
01366
01367
01368
01369 res = used_blocks(o);
01370 if (res > o->queuesize) {
01371
01372 if (o->w_errors++ == 0 && (usbradio_debug & 0x4))
01373 ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
01374 return 0;
01375 }
01376 o->w_errors = 0;
01377
01378 return write(o->sounddev, ((void *) data), FRAME_SIZE * 2 * 12);
01379 }
01380
01381 #ifndef NEW_ASTERISK
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393 static void send_sound(struct chan_usbradio_pvt *o)
01394 {
01395 short myframe[FRAME_SIZE];
01396 int ofs, l, start;
01397 int l_sampsent = o->sampsent;
01398 struct sound *s;
01399
01400 if (o->cursound < 0)
01401 return;
01402
01403 s = &sounds[o->cursound];
01404
01405 for (ofs = 0; ofs < FRAME_SIZE; ofs += l) {
01406 l = s->samplen - l_sampsent;
01407 if (l > 0) {
01408 start = l_sampsent % s->datalen;
01409 if (l > FRAME_SIZE - ofs)
01410 l = FRAME_SIZE - ofs;
01411 if (l > s->datalen - start)
01412 l = s->datalen - start;
01413 memmove(myframe + ofs, s->data + start, l * 2);
01414 if (0)
01415 ast_log(LOG_WARNING, "send_sound sound %d/%d of %d into %d\n", l_sampsent, l, s->samplen, ofs);
01416 l_sampsent += l;
01417 } else {
01418 static const short silence[FRAME_SIZE] = { 0, };
01419
01420 l += s->silencelen;
01421 if (l > 0) {
01422 if (l > FRAME_SIZE - ofs)
01423 l = FRAME_SIZE - ofs;
01424 memmove(myframe + ofs, silence, l * 2);
01425 l_sampsent += l;
01426 } else {
01427 if (s->repeat == 0) {
01428 o->cursound = -1;
01429 o->nosound = 0;
01430 if (ofs < FRAME_SIZE)
01431 memmove(myframe + ofs, silence, (FRAME_SIZE - ofs) * 2);
01432 }
01433 l_sampsent = 0;
01434 }
01435 }
01436 }
01437 l = soundcard_writeframe(o, myframe);
01438 if (l > 0)
01439 o->sampsent = l_sampsent;
01440 }
01441
01442 static void *sound_thread(void *arg)
01443 {
01444 char ign[4096];
01445 struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
01446
01447
01448
01449
01450
01451 read(o->sounddev, ign, sizeof(ign));
01452 for (;;) {
01453 fd_set rfds, wfds;
01454 int maxfd, res;
01455
01456 FD_ZERO(&rfds);
01457 FD_ZERO(&wfds);
01458 FD_SET(o->sndcmd[0], &rfds);
01459 maxfd = o->sndcmd[0];
01460 if (o->cursound > -1 && o->sounddev < 0)
01461 setformat(o, O_RDWR);
01462 else if (o->cursound == -1 && o->owner == NULL)
01463 {
01464 setformat(o, O_CLOSE);
01465 }
01466 if (o->sounddev > -1) {
01467 if (!o->owner) {
01468 FD_SET(o->sounddev, &rfds);
01469 maxfd = MAX(o->sounddev, maxfd);
01470 }
01471 if (o->cursound > -1) {
01472 FD_SET(o->sounddev, &wfds);
01473 maxfd = MAX(o->sounddev, maxfd);
01474 }
01475 }
01476
01477 res = ast_select(maxfd + 1, &rfds, &wfds, NULL, NULL);
01478 if (res < 1) {
01479 ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
01480 sleep(1);
01481 continue;
01482 }
01483 if (FD_ISSET(o->sndcmd[0], &rfds)) {
01484
01485 int i, what = -1;
01486
01487 read(o->sndcmd[0], &what, sizeof(what));
01488 for (i = 0; sounds[i].ind != -1; i++) {
01489 if (sounds[i].ind == what) {
01490 o->cursound = i;
01491 o->sampsent = 0;
01492 o->nosound = 1;
01493 break;
01494 }
01495 }
01496 if (sounds[i].ind == -1)
01497 ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
01498 }
01499 if (o->sounddev > -1) {
01500 if (FD_ISSET(o->sounddev, &rfds))
01501 read(o->sounddev, ign, sizeof(ign));
01502 if (FD_ISSET(o->sounddev, &wfds))
01503 send_sound(o);
01504 }
01505 }
01506 return NULL;
01507 }
01508
01509 #endif
01510
01511
01512
01513
01514
01515
01516 static int setformat(struct chan_usbradio_pvt *o, int mode)
01517 {
01518 int fmt, desired, res, fd;
01519 char device[100];
01520
01521 if (o->sounddev >= 0) {
01522 ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
01523 close(o->sounddev);
01524 o->duplex = M_UNSET;
01525 o->sounddev = -1;
01526 }
01527 if (mode == O_CLOSE)
01528 return 0;
01529 o->lastopen = ast_tvnow();
01530 strcpy(device,"/dev/dsp");
01531 if (o->devicenum)
01532 sprintf(device,"/dev/dsp%d",o->devicenum);
01533 fd = o->sounddev = open(device, mode | O_NONBLOCK);
01534 if (fd < 0) {
01535 ast_log(LOG_WARNING, "Unable to re-open DSP device %d: %s\n", o->devicenum, strerror(errno));
01536 return -1;
01537 }
01538 if (o->owner)
01539 o->owner->fds[0] = fd;
01540
01541 #if __BYTE_ORDER == __LITTLE_ENDIAN
01542 fmt = AFMT_S16_LE;
01543 #else
01544 fmt = AFMT_S16_BE;
01545 #endif
01546 res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
01547 if (res < 0) {
01548 ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
01549 return -1;
01550 }
01551 switch (mode) {
01552 case O_RDWR:
01553 res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
01554
01555 res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
01556 if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
01557 if (option_verbose > 1)
01558 ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
01559 o->duplex = M_FULL;
01560 };
01561 break;
01562 case O_WRONLY:
01563 o->duplex = M_WRITE;
01564 break;
01565 case O_RDONLY:
01566 o->duplex = M_READ;
01567 break;
01568 }
01569
01570 fmt = 1;
01571 res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
01572 if (res < 0) {
01573 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
01574 return -1;
01575 }
01576 fmt = desired = 48000;
01577 res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
01578
01579 if (res < 0) {
01580 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
01581 return -1;
01582 }
01583 if (fmt != desired) {
01584 if (!(o->warned & WARN_speed)) {
01585 ast_log(LOG_WARNING,
01586 "Requested %d Hz, got %d Hz -- sound may be choppy\n",
01587 desired, fmt);
01588 o->warned |= WARN_speed;
01589 }
01590 }
01591
01592
01593
01594
01595 if (o->frags) {
01596 fmt = o->frags;
01597 res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
01598 if (res < 0) {
01599 if (!(o->warned & WARN_frag)) {
01600 ast_log(LOG_WARNING,
01601 "Unable to set fragment size -- sound may be choppy\n");
01602 o->warned |= WARN_frag;
01603 }
01604 }
01605 }
01606
01607 res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
01608 res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
01609
01610 return 0;
01611 }
01612
01613
01614
01615
01616 static int usbradio_digit_begin(struct ast_channel *c, char digit)
01617 {
01618 return 0;
01619 }
01620
01621 static int usbradio_digit_end(struct ast_channel *c, char digit, unsigned int duration)
01622 {
01623
01624 ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
01625 digit, duration);
01626 return 0;
01627 }
01628
01629
01630
01631
01632 static int usbradio_text(struct ast_channel *c, const char *text)
01633 {
01634 struct chan_usbradio_pvt *o = find_desc(usbradio_active);
01635 double tx,rx;
01636 char cnt,rxs[16],txs[16],txpl[16],rxpl[16];
01637 char pwr,*cmd;
01638
01639 cmd = alloca(strlen(text) + 10);
01640
01641
01642 if(o->debuglevel)ast_verbose(" << Console Received usbradio text %s >> \n", text);
01643
01644 cnt=sscanf(text,"%s %s %s %s %s %c",cmd,rxs,txs,rxpl,txpl,&pwr);
01645
01646 if (strcmp(cmd,"SETCHAN")==0)
01647 {
01648 u8 chan;
01649 chan=strtod(rxs,NULL);
01650 ppbinout(chan);
01651 if(o->debuglevel)ast_log(LOG_NOTICE,"parse usbradio SETCHAN cmd: %s chan: %i\n",text,chan);
01652 return 0;
01653 }
01654
01655 if (cnt < 6)
01656 {
01657 ast_log(LOG_ERROR,"Cannot parse usbradio text: %s\n",text);
01658 return 0;
01659 }
01660 else
01661 {
01662 if(o->debuglevel)ast_verbose(" << %s %s %s %s %s %c >> \n", cmd,rxs,txs,rxpl,txpl,pwr);
01663 }
01664
01665 if (strcmp(cmd,"SETFREQ")==0)
01666 {
01667 if(o->debuglevel)ast_log(LOG_NOTICE,"parse usbradio SETFREQ cmd: %s\n",text);
01668 tx=strtod(txs,NULL);
01669 rx=strtod(rxs,NULL);
01670 o->set_txfreq = round(tx * (double)1000000);
01671 o->set_rxfreq = round(rx * (double)1000000);
01672 o->pmrChan->txpower = (pwr == 'H');
01673 strcpy(o->set_rxctcssfreqs,rxpl);
01674 strcpy(o->set_txctcssfreqs,txpl);
01675
01676 o->b.remoted=1;
01677 xpmr_config(o);
01678 return 0;
01679 }
01680 ast_log(LOG_ERROR,"Cannot parse usbradio cmd: %s\n",text);
01681 return 0;
01682 }
01683
01684
01685 static void ring(struct chan_usbradio_pvt *o, int x)
01686 {
01687 #ifndef NEW_ASTERISK
01688 write(o->sndcmd[1], &x, sizeof(x));
01689 #endif
01690 }
01691
01692
01693
01694
01695 static int usbradio_call(struct ast_channel *c, char *dest, int timeout)
01696 {
01697 struct chan_usbradio_pvt *o = c->tech_pvt;
01698
01699 o->stophid = 0;
01700 time(&o->lasthidtime);
01701 ast_pthread_create_background(&o->hidthread, NULL, hidthread, o);
01702 ast_setstate(c, AST_STATE_UP);
01703 return 0;
01704 }
01705
01706
01707
01708
01709 static int usbradio_answer(struct ast_channel *c)
01710 {
01711 #ifndef NEW_ASTERISK
01712 struct chan_usbradio_pvt *o = c->tech_pvt;
01713 #endif
01714
01715 ast_setstate(c, AST_STATE_UP);
01716 #ifndef NEW_ASTERISK
01717 o->cursound = -1;
01718 o->nosound = 0;
01719 #endif
01720 return 0;
01721 }
01722
01723 static int usbradio_hangup(struct ast_channel *c)
01724 {
01725 struct chan_usbradio_pvt *o = c->tech_pvt;
01726
01727
01728 #ifndef NEW_ASTERISK
01729 o->cursound = -1;
01730 o->nosound = 0;
01731 #endif
01732 c->tech_pvt = NULL;
01733 o->owner = NULL;
01734 ast_module_unref(ast_module_info->self);
01735 if (o->hookstate) {
01736 if (o->autoanswer || o->autohangup) {
01737
01738 o->hookstate = 0;
01739 setformat(o, O_CLOSE);
01740 } else {
01741
01742 ring(o, AST_CONTROL_CONGESTION);
01743 }
01744 }
01745 o->stophid = 1;
01746 pthread_join(o->hidthread,NULL);
01747 return 0;
01748 }
01749
01750
01751
01752 static int usbradio_write(struct ast_channel *c, struct ast_frame *f)
01753 {
01754 struct chan_usbradio_pvt *o = c->tech_pvt;
01755
01756 traceusb2(("usbradio_write() o->nosound= %i\n",o->nosound));
01757
01758 #ifndef NEW_ASTERISK
01759
01760 if (o->nosound)
01761 return 0;
01762
01763 o->cursound = -1;
01764 #endif
01765
01766
01767
01768
01769
01770
01771
01772 #if DEBUG_CAPTURES == 1 // to write input data to a file datalen=320
01773 if (ftxcapraw && o->b.txcapraw)
01774 {
01775 i16 i, tbuff[f->datalen];
01776 for(i=0;i<f->datalen;i+=2)
01777 {
01778 tbuff[i]= ((i16*)(f->data.ptr))[i/2];
01779 tbuff[i+1]= o->txkeyed*M_Q13;
01780 }
01781 if (fwrite(tbuff,2,f->datalen,ftxcapraw) != f->datalen) {
01782 ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
01783 }
01784
01785 }
01786 #endif
01787
01788
01789
01790 PmrTx(o->pmrChan,(i16*)f->data.ptr);
01791
01792 return 0;
01793 }
01794
01795 static struct ast_frame *usbradio_read(struct ast_channel *c)
01796 {
01797 int res, src, datalen, oldpttout;
01798 int cd,sd;
01799 struct chan_usbradio_pvt *o = c->tech_pvt;
01800 struct ast_frame *f = &o->read_f,*f1;
01801 struct ast_frame wf = { AST_FRAME_CONTROL };
01802 time_t now;
01803
01804 traceusb2(("usbradio_read()\n"));
01805
01806 if (o->lasthidtime)
01807 {
01808 time(&now);
01809 if ((now - o->lasthidtime) > 3)
01810 {
01811 ast_log(LOG_ERROR,"HID process has died or something!!\n");
01812 return NULL;
01813 }
01814 }
01815
01816
01817 memset(f, '\0', sizeof(struct ast_frame));
01818 f->frametype = AST_FRAME_NULL;
01819 f->src = usbradio_tech.type;
01820
01821 res = read(o->sounddev, o->usbradio_read_buf + o->readpos,
01822 sizeof(o->usbradio_read_buf) - o->readpos);
01823 if (res < 0)
01824 {
01825 if (errno != EAGAIN) return NULL;
01826 if (o->readerrs++ > READERR_THRESHOLD)
01827 {
01828 ast_log(LOG_ERROR,"Stuck USB read channel [%s], un-sticking it!\n",o->name);
01829 o->readerrs = 0;
01830 return NULL;
01831 }
01832 if (o->readerrs == 1)
01833 ast_log(LOG_WARNING,"Possibly stuck USB read channel. [%s]\n",o->name);
01834 return f;
01835 }
01836 if (o->readerrs) ast_log(LOG_WARNING,"Nope, USB read channel [%s] wasn't stuck after all.\n",o->name);
01837 o->readerrs = 0;
01838 o->readpos += res;
01839 if (o->readpos < sizeof(o->usbradio_read_buf))
01840 return f;
01841
01842 if (o->mute)
01843 return f;
01844
01845 #if DEBUG_CAPTURES == 1
01846 if ((o->b.rxcapraw && frxcapraw) && (fwrite((o->usbradio_read_buf + AST_FRIENDLY_OFFSET),1,FRAME_SIZE * 2 * 2 * 6,frxcapraw) != FRAME_SIZE * 2 * 2 * 6)) {
01847 ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
01848 }
01849 #endif
01850
01851 #if 1
01852 if(o->txkeyed||o->txtestkey)
01853 {
01854 if(!o->pmrChan->txPttIn)
01855 {
01856 o->pmrChan->txPttIn=1;
01857 if(o->debuglevel) ast_log(LOG_NOTICE,"txPttIn = %i, chan %s\n",o->pmrChan->txPttIn,o->owner->name);
01858 }
01859 }
01860 else if(o->pmrChan->txPttIn)
01861 {
01862 o->pmrChan->txPttIn=0;
01863 if(o->debuglevel) ast_log(LOG_NOTICE,"txPttIn = %i, chan %s\n",o->pmrChan->txPttIn,o->owner->name);
01864 }
01865 oldpttout = o->pmrChan->txPttOut;
01866
01867 PmrRx( o->pmrChan,
01868 (i16 *)(o->usbradio_read_buf + AST_FRIENDLY_OFFSET),
01869 (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET),
01870 (i16 *)(o->usbradio_write_buf_1));
01871
01872 if (oldpttout != o->pmrChan->txPttOut)
01873 {
01874 if(o->debuglevel) ast_log(LOG_NOTICE,"txPttOut = %i, chan %s\n",o->pmrChan->txPttOut,o->owner->name);
01875 kickptt(o);
01876 }
01877
01878 #if 0 // to write 48KS/s stereo tx data to a file
01879 if (!ftxoutraw) ftxoutraw = fopen(TX_CAP_OUT_FILE,"w");
01880 if (ftxoutraw) fwrite(o->usbradio_write_buf_1,1,FRAME_SIZE * 2 * 6,ftxoutraw);
01881 #endif
01882
01883 #if DEBUG_CAPTURES == 1 && XPMR_DEBUG0 == 1
01884 if ((o->b.txcap2 && ftxcaptrace) && (fwrite((o->pmrChan->ptxDebug),1,FRAME_SIZE * 2 * 16,ftxcaptrace) != FRAME_SIZE * 2 * 16)) {
01885 ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
01886 }
01887 #endif
01888
01889
01890 datalen = FRAME_SIZE * 24;
01891 src = 0;
01892 while (src < datalen)
01893 {
01894
01895 int l = sizeof(o->usbradio_write_buf) - o->usbradio_write_dst;
01896
01897 if (datalen - src >= l)
01898 {
01899
01900 memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
01901 soundcard_writeframe(o, (short *) o->usbradio_write_buf);
01902 src += l;
01903 o->usbradio_write_dst = 0;
01904 }
01905 else
01906 {
01907
01908 l = datalen - src;
01909 memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
01910 src += l;
01911 o->usbradio_write_dst += l;
01912 }
01913 }
01914 #else
01915 static FILE *hInput;
01916 i16 iBuff[FRAME_SIZE*2*6];
01917
01918 o->pmrChan->b.rxCapture=1;
01919
01920 if(!hInput)
01921 {
01922 hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm","r");
01923 if(!hInput)
01924 {
01925 printf(" Input Data File Not Found.\n");
01926 return 0;
01927 }
01928 }
01929
01930 if(0==fread((void *)iBuff,2,FRAME_SIZE*2*6,hInput))exit;
01931
01932 PmrRx( o->pmrChan,
01933 (i16 *)iBuff,
01934 (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
01935
01936 #endif
01937
01938 #if 0
01939 if (!frxoutraw) frxoutraw = fopen(RX_CAP_OUT_FILE,"w");
01940 if (frxoutraw) fwrite((o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET),1,FRAME_SIZE * 2,frxoutraw);
01941 #endif
01942
01943 #if DEBUG_CAPTURES == 1 && XPMR_DEBUG0 == 1
01944 if ((frxcaptrace && o->b.rxcap2 && o->pmrChan->b.radioactive) && (fwrite((o->pmrChan->prxDebug),1,FRAME_SIZE * 2 * 16,frxcaptrace) != FRAME_SIZE * 2 * 16 )) {
01945 ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
01946 }
01947 #endif
01948
01949 cd = 0;
01950 if(o->rxcdtype==CD_HID && (o->pmrChan->rxExtCarrierDetect!=o->rxhidsq))
01951 o->pmrChan->rxExtCarrierDetect=o->rxhidsq;
01952
01953 if(o->rxcdtype==CD_HID_INVERT && (o->pmrChan->rxExtCarrierDetect==o->rxhidsq))
01954 o->pmrChan->rxExtCarrierDetect=!o->rxhidsq;
01955
01956 if( (o->rxcdtype==CD_HID && o->rxhidsq) ||
01957 (o->rxcdtype==CD_HID_INVERT && !o->rxhidsq) ||
01958 (o->rxcdtype==CD_XPMR_NOISE && o->pmrChan->rxCarrierDetect) ||
01959 (o->rxcdtype==CD_XPMR_VOX && o->pmrChan->rxCarrierDetect)
01960 )
01961 {
01962 if (!o->pmrChan->txPttOut || o->radioduplex)cd=1;
01963 }
01964 else
01965 {
01966 cd=0;
01967 }
01968
01969 if(cd!=o->rxcarrierdetect)
01970 {
01971 o->rxcarrierdetect=cd;
01972 if(o->debuglevel) ast_log(LOG_NOTICE,"rxcarrierdetect = %i, chan %s\n",cd,o->owner->name);
01973
01974 }
01975
01976 if(o->pmrChan->b.ctcssRxEnable && o->pmrChan->rxCtcss->decode!=o->rxctcssdecode)
01977 {
01978 if(o->debuglevel)ast_log(LOG_NOTICE,"rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
01979
01980 o->rxctcssdecode=o->pmrChan->rxCtcss->decode;
01981 strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
01982 }
01983
01984 #ifndef HAVE_XPMRX
01985 if( !o->pmrChan->b.ctcssRxEnable ||
01986 ( o->pmrChan->b.ctcssRxEnable &&
01987 o->pmrChan->rxCtcss->decode>CTCSS_NULL &&
01988 o->pmrChan->smode==SMODE_CTCSS )
01989 )
01990 {
01991 sd=1;
01992 }
01993 else
01994 {
01995 sd=0;
01996 }
01997 #else
01998 if( (!o->pmrChan->b.ctcssRxEnable && !o->pmrChan->b.dcsRxEnable && !o->pmrChan->b.lmrRxEnable) ||
01999 ( o->pmrChan->b.ctcssRxEnable &&
02000 o->pmrChan->rxCtcss->decode>CTCSS_NULL &&
02001 o->pmrChan->smode==SMODE_CTCSS ) ||
02002 ( o->pmrChan->b.dcsRxEnable &&
02003 o->pmrChan->decDcs->decode > 0 &&
02004 o->pmrChan->smode==SMODE_DCS )
02005 )
02006 {
02007 sd=1;
02008 }
02009 else
02010 {
02011 sd=0;
02012 }
02013
02014 if(o->pmrChan->decDcs->decode!=o->rxdcsdecode)
02015 {
02016 if(o->debuglevel)ast_log(LOG_NOTICE,"rxdcsdecode = %s, chan %s\n",o->pmrChan->rxctcssfreq,o->owner->name);
02017
02018 o->rxdcsdecode=o->pmrChan->decDcs->decode;
02019 strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
02020 }
02021
02022 if(o->pmrChan->rptnum && (o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed != o->rxlsddecode))
02023 {
02024 if(o->debuglevel)ast_log(LOG_NOTICE,"rxLSDecode = %s, chan %s\n",o->pmrChan->rxctcssfreq,o->owner->name);
02025 o->rxlsddecode=o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed;
02026 strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
02027 }
02028
02029 if( (o->pmrChan->rptnum>0 && o->pmrChan->smode==SMODE_LSD && o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed)||
02030 (o->pmrChan->smode==SMODE_DCS && o->pmrChan->decDcs->decode>0) )
02031 {
02032 sd=1;
02033 }
02034 #endif
02035
02036 if ( cd && sd )
02037 {
02038
02039 if(!o->rxkeyed && o->debuglevel)ast_log(LOG_NOTICE,"o->rxkeyed = 1, chan %s\n", o->owner->name);
02040 o->rxkeyed = 1;
02041 }
02042 else
02043 {
02044
02045 if(o->rxkeyed && o->debuglevel)ast_log(LOG_NOTICE,"o->rxkeyed = 0, chan %s\n",o->owner->name);
02046 o->rxkeyed = 0;
02047 }
02048
02049
02050 if (o->lastrx && (!o->rxkeyed))
02051 {
02052 o->lastrx = 0;
02053
02054 wf.subclass = AST_CONTROL_RADIO_UNKEY;
02055 ast_queue_frame(o->owner, &wf);
02056 }
02057 else if ((!o->lastrx) && (o->rxkeyed))
02058 {
02059 o->lastrx = 1;
02060
02061 wf.subclass = AST_CONTROL_RADIO_KEY;
02062 if(o->rxctcssdecode)
02063 {
02064 wf.data.ptr = o->rxctcssfreq;
02065 wf.datalen = strlen(o->rxctcssfreq) + 1;
02066 TRACEO(1,("AST_CONTROL_RADIO_KEY text=%s\n",o->rxctcssfreq));
02067 }
02068 ast_queue_frame(o->owner, &wf);
02069 }
02070
02071 o->readpos = AST_FRIENDLY_OFFSET;
02072 if (c->_state != AST_STATE_UP)
02073 return f;
02074
02075 f->frametype = AST_FRAME_VOICE;
02076 f->subclass = AST_FORMAT_SLINEAR;
02077 f->samples = FRAME_SIZE;
02078 f->datalen = FRAME_SIZE * 2;
02079 f->data.ptr = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
02080 if (o->boost != BOOST_SCALE) {
02081 int i, x;
02082 int16_t *p = (int16_t *) f->data.ptr;
02083 for (i = 0; i < f->samples; i++) {
02084 x = (p[i] * o->boost) / BOOST_SCALE;
02085 if (x > 32767)
02086 x = 32767;
02087 else if (x < -32768)
02088 x = -32768;
02089 p[i] = x;
02090 }
02091 }
02092
02093 f->offset = AST_FRIENDLY_OFFSET;
02094 if (o->dsp)
02095 {
02096 f1 = ast_dsp_process(c,o->dsp,f);
02097 if ((f1->frametype == AST_FRAME_DTMF_END) ||
02098 (f1->frametype == AST_FRAME_DTMF_BEGIN))
02099 {
02100 if ((f1->subclass == 'm') || (f1->subclass == 'u'))
02101 {
02102 f1->frametype = AST_FRAME_NULL;
02103 f1->subclass = 0;
02104 return(f1);
02105 }
02106 if (f1->frametype == AST_FRAME_DTMF_END)
02107 ast_log(LOG_NOTICE,"Got DTMF char %c\n",f1->subclass);
02108 return(f1);
02109 }
02110 }
02111 return f;
02112 }
02113
02114 static int usbradio_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
02115 {
02116 struct chan_usbradio_pvt *o = newchan->tech_pvt;
02117 ast_log(LOG_WARNING,"usbradio_fixup()\n");
02118 o->owner = newchan;
02119 return 0;
02120 }
02121
02122 static int usbradio_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
02123 {
02124 struct chan_usbradio_pvt *o = c->tech_pvt;
02125 int res = -1;
02126
02127 switch (cond) {
02128 case AST_CONTROL_BUSY:
02129 case AST_CONTROL_CONGESTION:
02130 case AST_CONTROL_RINGING:
02131 res = cond;
02132 break;
02133
02134 case -1:
02135 #ifndef NEW_ASTERISK
02136 o->cursound = -1;
02137 o->nosound = 0;
02138 #endif
02139 return 0;
02140
02141 case AST_CONTROL_VIDUPDATE:
02142 res = -1;
02143 break;
02144 case AST_CONTROL_HOLD:
02145 ast_verbose(" << Console Has Been Placed on Hold >> \n");
02146 ast_moh_start(c, data, o->mohinterpret);
02147 break;
02148 case AST_CONTROL_UNHOLD:
02149 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
02150 ast_moh_stop(c);
02151 break;
02152 case AST_CONTROL_PROCEEDING:
02153 ast_verbose(" << Call Proceeding... >> \n");
02154 ast_moh_stop(c);
02155 break;
02156 case AST_CONTROL_PROGRESS:
02157 ast_verbose(" << Call Progress... >> \n");
02158 ast_moh_stop(c);
02159 break;
02160 case AST_CONTROL_RADIO_KEY:
02161 o->txkeyed = 1;
02162 if(o->debuglevel)ast_verbose(" << AST_CONTROL_RADIO_KEY Radio Transmit On. >> \n");
02163 break;
02164 case AST_CONTROL_RADIO_UNKEY:
02165 o->txkeyed = 0;
02166 if(o->debuglevel)ast_verbose(" << AST_CONTROL_RADIO_UNKEY Radio Transmit Off. >> \n");
02167 break;
02168 default:
02169 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
02170 return -1;
02171 }
02172
02173 if (res > -1)
02174 ring(o, res);
02175
02176 return 0;
02177 }
02178
02179
02180
02181
02182 static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext, char *ctx, int state)
02183 {
02184 struct ast_channel *c;
02185
02186 c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "Radio/%s", o->name);
02187 if (c == NULL)
02188 return NULL;
02189 c->tech = &usbradio_tech;
02190 if (o->sounddev < 0)
02191 setformat(o, O_RDWR);
02192 c->fds[0] = o->sounddev;
02193 c->nativeformats = AST_FORMAT_SLINEAR;
02194 c->readformat = AST_FORMAT_SLINEAR;
02195 c->writeformat = AST_FORMAT_SLINEAR;
02196 c->tech_pvt = o;
02197
02198 if (!ast_strlen_zero(o->language))
02199 ast_string_field_set(c, language, o->language);
02200
02201
02202 c->cid.cid_num = ast_strdup(o->cid_num);
02203 c->cid.cid_ani = ast_strdup(o->cid_num);
02204 c->cid.cid_name = ast_strdup(o->cid_name);
02205 if (!ast_strlen_zero(ext))
02206 c->cid.cid_dnid = ast_strdup(ext);
02207
02208 o->owner = c;
02209 ast_module_ref(ast_module_info->self);
02210 ast_jb_configure(c, &global_jbconf);
02211 if (state != AST_STATE_DOWN) {
02212 if (ast_pbx_start(c)) {
02213 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
02214 ast_hangup(c);
02215 o->owner = c = NULL;
02216
02217
02218 }
02219 }
02220
02221 return c;
02222 }
02223
02224
02225 static struct ast_channel *usbradio_request(const char *type, int format, void *data, int *cause)
02226 {
02227 struct ast_channel *c;
02228 struct chan_usbradio_pvt *o = find_desc(data);
02229
02230 TRACEO(1,("usbradio_request()\n"));
02231
02232 if (0)
02233 {
02234 ast_log(LOG_WARNING, "usbradio_request type <%s> data 0x%p <%s>\n", type, data, (char *) data);
02235 }
02236 if (o == NULL) {
02237 ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
02238
02239 return NULL;
02240 }
02241 if ((format & AST_FORMAT_SLINEAR) == 0) {
02242 ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
02243 return NULL;
02244 }
02245 if (o->owner) {
02246 ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
02247 *cause = AST_CAUSE_BUSY;
02248 return NULL;
02249 }
02250 c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
02251 if (c == NULL) {
02252 ast_log(LOG_WARNING, "Unable to create new usb channel\n");
02253 return NULL;
02254 }
02255
02256 o->b.remoted=0;
02257 xpmr_config(o);
02258
02259 return c;
02260 }
02261
02262
02263 static int console_key(int fd, int argc, char *argv[])
02264 {
02265 struct chan_usbradio_pvt *o = find_desc(usbradio_active);
02266
02267 if (argc != 2)
02268 return RESULT_SHOWUSAGE;
02269 o->txtestkey = 1;
02270 return RESULT_SUCCESS;
02271 }
02272
02273
02274 static int console_unkey(int fd, int argc, char *argv[])
02275 {
02276 struct chan_usbradio_pvt *o = find_desc(usbradio_active);
02277
02278 if (argc != 2)
02279 return RESULT_SHOWUSAGE;
02280 o->txtestkey = 0;
02281 return RESULT_SUCCESS;
02282 }
02283
02284 static int radio_tune(int fd, int argc, char *argv[])
02285 {
02286 struct chan_usbradio_pvt *o = find_desc(usbradio_active);
02287 int i=0;
02288
02289 if ((argc < 2) || (argc > 4))
02290 return RESULT_SHOWUSAGE;
02291
02292 if (argc == 2)
02293 {
02294 ast_cli(fd,"Active radio interface is [%s]\n",usbradio_active);
02295 ast_cli(fd,"Output A is currently set to ");
02296 if(o->txmixa==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
02297 else if (o->txmixa==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
02298 else if (o->txmixa==TX_OUT_LSD)ast_cli(fd,"tone.\n");
02299 else if (o->txmixa==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
02300 else ast_cli(fd,"off.\n");
02301
02302 ast_cli(fd,"Output B is currently set to ");
02303 if(o->txmixb==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
02304 else if (o->txmixb==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
02305 else if (o->txmixb==TX_OUT_LSD)ast_cli(fd,"tone.\n");
02306 else if (o->txmixb==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
02307 else ast_cli(fd,"off.\n");
02308
02309 ast_cli(fd,"Tx Voice Level currently set to %d\n",o->txmixaset);
02310 ast_cli(fd,"Tx Tone Level currently set to %d\n",o->txctcssadj);
02311 ast_cli(fd,"Rx Squelch currently set to %d\n",o->rxsquelchadj);
02312 ast_cli(fd,"Device String is %s\n",o->devstr);
02313 return RESULT_SHOWUSAGE;
02314 }
02315
02316 o->pmrChan->b.tuning=1;
02317
02318 if (!strcasecmp(argv[2],"rxnoise")) tune_rxinput(fd,o);
02319 else if (!strcasecmp(argv[2],"rxvoice")) tune_rxvoice(fd,o);
02320 else if (!strcasecmp(argv[2],"rxtone")) tune_rxctcss(fd,o);
02321 else if (!strcasecmp(argv[2],"rxsquelch"))
02322 {
02323 if (argc == 3)
02324 {
02325 ast_cli(fd,"Current Signal Strength is %d\n",((32767-o->pmrChan->rxRssi)*1000/32767));
02326 ast_cli(fd,"Current Squelch setting is %d\n",o->rxsquelchadj);
02327
02328
02329 } else {
02330 i = atoi(argv[3]);
02331 if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
02332 ast_cli(fd,"Changed Squelch setting to %d\n",i);
02333 o->rxsquelchadj = i;
02334 *(o->pmrChan->prxSquelchAdjust)= ((999 - i) * 32767) / 1000;
02335 }
02336 }
02337 else if (!strcasecmp(argv[2],"txvoice")) {
02338 i = 0;
02339
02340 if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
02341 (o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
02342 )
02343 {
02344 ast_log(LOG_ERROR,"No txvoice output configured.\n");
02345 }
02346 else if (argc == 3)
02347 {
02348 if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
02349 ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
02350 else
02351 ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
02352 }
02353 else
02354 {
02355 i = atoi(argv[3]);
02356 if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
02357
02358 if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
02359 {
02360 o->txmixaset=i;
02361 ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
02362 }
02363 else
02364 {
02365 o->txmixbset=i;
02366 ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
02367 }
02368 mixer_write(o);
02369 mult_set(o);
02370 ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
02371 }
02372 o->pmrChan->b.txCtcssInhibit=1;
02373 tune_txoutput(o,i,fd);
02374 o->pmrChan->b.txCtcssInhibit=0;
02375 }
02376 else if (!strcasecmp(argv[2],"txall")) {
02377 i = 0;
02378
02379 if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
02380 (o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
02381 )
02382 {
02383 ast_log(LOG_ERROR,"No txvoice output configured.\n");
02384 }
02385 else if (argc == 3)
02386 {
02387 if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
02388 ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
02389 else
02390 ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
02391 }
02392 else
02393 {
02394 i = atoi(argv[3]);
02395 if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
02396
02397 if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
02398 {
02399 o->txmixaset=i;
02400 ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
02401 }
02402 else
02403 {
02404 o->txmixbset=i;
02405 ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
02406 }
02407 mixer_write(o);
02408 mult_set(o);
02409 ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
02410 }
02411 tune_txoutput(o,i,fd);
02412 }
02413 else if (!strcasecmp(argv[2],"auxvoice")) {
02414 i = 0;
02415 if( (o->txmixa!=TX_OUT_AUX) && (o->txmixb!=TX_OUT_AUX))
02416 {
02417 ast_log(LOG_WARNING,"No auxvoice output configured.\n");
02418 }
02419 else if (argc == 3)
02420 {
02421 if(o->txmixa==TX_OUT_AUX)
02422 ast_cli(fd,"Current auxvoice setting on Channel A is %d\n",o->txmixaset);
02423 else
02424 ast_cli(fd,"Current auxvoice setting on Channel B is %d\n",o->txmixbset);
02425 }
02426 else
02427 {
02428 i = atoi(argv[3]);
02429 if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
02430 if(o->txmixa==TX_OUT_AUX)
02431 {
02432 o->txmixbset=i;
02433 ast_cli(fd,"Changed auxvoice setting on Channel A to %d\n",o->txmixaset);
02434 }
02435 else
02436 {
02437 o->txmixbset=i;
02438 ast_cli(fd,"Changed auxvoice setting on Channel B to %d\n",o->txmixbset);
02439 }
02440 mixer_write(o);
02441 mult_set(o);
02442 }
02443
02444 }
02445 else if (!strcasecmp(argv[2],"txtone"))
02446 {
02447 if (argc == 3)
02448 ast_cli(fd,"Current Tx CTCSS modulation setting = %d\n",o->txctcssadj);
02449 else
02450 {
02451 i = atoi(argv[3]);
02452 if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
02453 o->txctcssadj = i;
02454 set_txctcss_level(o);
02455 ast_cli(fd,"Changed Tx CTCSS modulation setting to %i\n",i);
02456 }
02457 o->txtestkey=1;
02458 usleep(5000000);
02459 o->txtestkey=0;
02460 }
02461 else if (!strcasecmp(argv[2],"dump")) pmrdump(o);
02462 else if (!strcasecmp(argv[2],"nocap"))
02463 {
02464 ast_cli(fd,"File capture (trace) was rx=%d tx=%d and now off.\n",o->b.rxcap2,o->b.txcap2);
02465 ast_cli(fd,"File capture (raw) was rx=%d tx=%d and now off.\n",o->b.rxcapraw,o->b.txcapraw);
02466 o->b.rxcapraw=o->b.txcapraw=o->b.rxcap2=o->b.txcap2=o->pmrChan->b.rxCapture=o->pmrChan->b.txCapture=0;
02467 if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
02468 if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
02469 if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
02470 if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
02471 if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
02472 if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
02473 }
02474 else if (!strcasecmp(argv[2],"rxtracecap"))
02475 {
02476 if (!frxcaptrace) frxcaptrace= fopen(RX_CAP_TRACE_FILE,"w");
02477 ast_cli(fd,"Trace rx on.\n");
02478 o->b.rxcap2=o->pmrChan->b.rxCapture=1;
02479 }
02480 else if (!strcasecmp(argv[2],"txtracecap"))
02481 {
02482 if (!ftxcaptrace) ftxcaptrace= fopen(TX_CAP_TRACE_FILE,"w");
02483 ast_cli(fd,"Trace tx on.\n");
02484 o->b.txcap2=o->pmrChan->b.txCapture=1;
02485 }
02486 else if (!strcasecmp(argv[2],"rxcap"))
02487 {
02488 if (!frxcapraw) frxcapraw = fopen(RX_CAP_RAW_FILE,"w");
02489 ast_cli(fd,"cap rx raw on.\n");
02490 o->b.rxcapraw=1;
02491 }
02492 else if (!strcasecmp(argv[2],"txcap"))
02493 {
02494 if (!ftxcapraw) ftxcapraw = fopen(TX_CAP_RAW_FILE,"w");
02495 ast_cli(fd,"cap tx raw on.\n");
02496 o->b.txcapraw=1;
02497 }
02498 else if (!strcasecmp(argv[2],"save"))
02499 {
02500 tune_write(o);
02501 ast_cli(fd,"Saved radio tuning settings to usbradio_tune_%s.conf\n",o->name);
02502 }
02503 else if (!strcasecmp(argv[2],"load"))
02504 {
02505 ast_mutex_lock(&o->eepromlock);
02506 while(o->eepromctl)
02507 {
02508 ast_mutex_unlock(&o->eepromlock);
02509 usleep(10000);
02510 ast_mutex_lock(&o->eepromlock);
02511 }
02512 o->eepromctl = 1;
02513 ast_mutex_unlock(&o->eepromlock);
02514
02515 ast_cli(fd,"Requesting loading of tuning settings from EEPROM for channel %s\n",o->name);
02516 }
02517 else
02518 {
02519 o->pmrChan->b.tuning=0;
02520 return RESULT_SHOWUSAGE;
02521 }
02522 o->pmrChan->b.tuning=0;
02523 return RESULT_SUCCESS;
02524 }
02525
02526
02527
02528
02529
02530
02531 static int set_txctcss_level(struct chan_usbradio_pvt *o)
02532 {
02533 if (o->txmixa == TX_OUT_LSD)
02534 {
02535
02536 o->txmixaset=o->txctcssadj;
02537 mixer_write(o);
02538 mult_set(o);
02539 }
02540 else if (o->txmixb == TX_OUT_LSD)
02541 {
02542
02543 o->txmixbset=o->txctcssadj;
02544 mixer_write(o);
02545 mult_set(o);
02546 }
02547 else
02548 {
02549 *o->pmrChan->ptxCtcssAdjust=(o->txctcssadj * M_Q8) / 1000;
02550 }
02551 return 0;
02552 }
02553
02554
02555
02556 static int radio_set_debug(int fd, int argc, char *argv[])
02557 {
02558 struct chan_usbradio_pvt *o = find_desc(usbradio_active);
02559
02560 o->debuglevel=1;
02561 ast_cli(fd,"usbradio debug on.\n");
02562 return RESULT_SUCCESS;
02563 }
02564
02565 static int radio_set_debug_off(int fd, int argc, char *argv[])
02566 {
02567 struct chan_usbradio_pvt *o = find_desc(usbradio_active);
02568
02569 o->debuglevel=0;
02570 ast_cli(fd,"usbradio debug off.\n");
02571 return RESULT_SUCCESS;
02572 }
02573
02574 static int radio_active(int fd, int argc, char *argv[])
02575 {
02576 if (argc == 2)
02577 ast_cli(fd, "active (command) USB Radio device is [%s]\n", usbradio_active);
02578 else if (argc != 3)
02579 return RESULT_SHOWUSAGE;
02580 else {
02581 struct chan_usbradio_pvt *o;
02582 if (strcmp(argv[2], "show") == 0) {
02583 for (o = usbradio_default.next; o; o = o->next)
02584 ast_cli(fd, "device [%s] exists\n", o->name);
02585 return RESULT_SUCCESS;
02586 }
02587 o = find_desc(argv[2]);
02588 if (o == NULL)
02589 ast_cli(fd, "No device [%s] exists\n", argv[2]);
02590 else
02591 {
02592 struct chan_usbradio_pvt *ao;
02593 for (ao = usbradio_default.next; ao && ao->name ; ao = ao->next)ao->pmrChan->b.radioactive=0;
02594 usbradio_active = o->name;
02595 o->pmrChan->b.radioactive=1;
02596 }
02597 }
02598 return RESULT_SUCCESS;
02599 }
02600
02601
02602
02603 static int radio_set_xpmr_debug(int fd, int argc, char *argv[])
02604 {
02605 struct chan_usbradio_pvt *o = find_desc(usbradio_active);
02606
02607 if (argc == 4)
02608 {
02609 int i;
02610 i = atoi(argv[3]);
02611 if ((i >= 0) && (i <= 100))
02612 {
02613 o->pmrChan->tracelevel=i;
02614 }
02615 }
02616
02617 ast_cli(fd,"usbradio xdebug on tracelevel %i\n",o->pmrChan->tracelevel);
02618
02619 return RESULT_SUCCESS;
02620 }
02621
02622
02623 static char key_usage[] =
02624 "Usage: radio key\n"
02625 " Simulates COR active.\n";
02626
02627 static char unkey_usage[] =
02628 "Usage: radio unkey\n"
02629 " Simulates COR un-active.\n";
02630
02631 static char active_usage[] =
02632 "Usage: radio active [device-name]\n"
02633 " If used without a parameter, displays which device is the current\n"
02634 "one being commanded. If a device is specified, the commanded radio device is changed\n"
02635 "to the device specified.\n";
02636
02637
02638
02639 static char radio_tune_usage[] =
02640 "Usage: radio tune <function>\n"
02641 " rxnoise\n"
02642 " rxvoice\n"
02643 " rxtone\n"
02644 " rxsquelch [newsetting]\n"
02645 " txvoice [newsetting]\n"
02646 " txtone [newsetting]\n"
02647 " auxvoice [newsetting]\n"
02648 " save (settings to tuning file)\n"
02649 " load (tuning settings from EEPROM)\n"
02650 "\n All [newsetting]'s are values 0-999\n\n";
02651
02652 #ifndef NEW_ASTERISK
02653
02654 static struct ast_cli_entry cli_usbradio[] = {
02655 { { "radio", "key", NULL },
02656 console_key, "Simulate Rx Signal Present",
02657 key_usage, NULL, NULL},
02658
02659 { { "radio", "unkey", NULL },
02660 console_unkey, "Simulate Rx Signal Lusb",
02661 unkey_usage, NULL, NULL },
02662
02663 { { "radio", "tune", NULL },
02664 radio_tune, "Radio Tune",
02665 radio_tune_usage, NULL, NULL },
02666
02667 { { "radio", "set", "debug", NULL },
02668 radio_set_debug, "Radio Debug",
02669 radio_tune_usage, NULL, NULL },
02670
02671 { { "radio", "set", "debug", "off", NULL },
02672 radio_set_debug_off, "Radio Debug",
02673 radio_tune_usage, NULL, NULL },
02674
02675 { { "radio", "active", NULL },
02676 radio_active, "Change commanded device",
02677 active_usage, NULL, NULL },
02678
02679 { { "radio", "set", "xdebug", NULL },
02680 radio_set_xpmr_debug, "Radio set xpmr debug level",
02681 active_usage, NULL, NULL },
02682
02683 };
02684 #endif
02685
02686
02687
02688
02689 #if 0
02690 static void store_callerid(struct chan_usbradio_pvt *o, char *s)
02691 {
02692 ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
02693 }
02694 #endif
02695
02696 static void store_rxdemod(struct chan_usbradio_pvt *o, char *s)
02697 {
02698 if (!strcasecmp(s,"no")){
02699 o->rxdemod = RX_AUDIO_NONE;
02700 }
02701 else if (!strcasecmp(s,"speaker")){
02702 o->rxdemod = RX_AUDIO_SPEAKER;
02703 }
02704 else if (!strcasecmp(s,"flat")){
02705 o->rxdemod = RX_AUDIO_FLAT;
02706 }
02707 else {
02708 ast_log(LOG_WARNING,"Unrecognized rxdemod parameter: %s\n",s);
02709 }
02710
02711
02712 }
02713
02714
02715 static void store_txmixa(struct chan_usbradio_pvt *o, char *s)
02716 {
02717 if (!strcasecmp(s,"no")){
02718 o->txmixa = TX_OUT_OFF;
02719 }
02720 else if (!strcasecmp(s,"voice")){
02721 o->txmixa = TX_OUT_VOICE;
02722 }
02723 else if (!strcasecmp(s,"tone")){
02724 o->txmixa = TX_OUT_LSD;
02725 }
02726 else if (!strcasecmp(s,"composite")){
02727 o->txmixa = TX_OUT_COMPOSITE;
02728 }
02729 else if (!strcasecmp(s,"auxvoice")){
02730 o->txmixa = TX_OUT_AUX;
02731 }
02732 else {
02733 ast_log(LOG_WARNING,"Unrecognized txmixa parameter: %s\n",s);
02734 }
02735
02736
02737 }
02738
02739 static void store_txmixb(struct chan_usbradio_pvt *o, char *s)
02740 {
02741 if (!strcasecmp(s,"no")){
02742 o->txmixb = TX_OUT_OFF;
02743 }
02744 else if (!strcasecmp(s,"voice")){
02745 o->txmixb = TX_OUT_VOICE;
02746 }
02747 else if (!strcasecmp(s,"tone")){
02748 o->txmixb = TX_OUT_LSD;
02749 }
02750 else if (!strcasecmp(s,"composite")){
02751 o->txmixb = TX_OUT_COMPOSITE;
02752 }
02753 else if (!strcasecmp(s,"auxvoice")){
02754 o->txmixb = TX_OUT_AUX;
02755 }
02756 else {
02757 ast_log(LOG_WARNING,"Unrecognized txmixb parameter: %s\n",s);
02758 }
02759
02760
02761 }
02762
02763
02764 static void store_rxcdtype(struct chan_usbradio_pvt *o, char *s)
02765 {
02766 if (!strcasecmp(s,"no")){
02767 o->rxcdtype = CD_IGNORE;
02768 }
02769 else if (!strcasecmp(s,"usb")){
02770 o->rxcdtype = CD_HID;
02771 }
02772 else if (!strcasecmp(s,"dsp")){
02773 o->rxcdtype = CD_XPMR_NOISE;
02774 }
02775 else if (!strcasecmp(s,"vox")){
02776 o->rxcdtype = CD_XPMR_VOX;
02777 }
02778 else if (!strcasecmp(s,"usbinvert")){
02779 o->rxcdtype = CD_HID_INVERT;
02780 }
02781 else {
02782 ast_log(LOG_WARNING,"Unrecognized rxcdtype parameter: %s\n",s);
02783 }
02784
02785
02786 }
02787
02788
02789 static void store_rxsdtype(struct chan_usbradio_pvt *o, char *s)
02790 {
02791 if (!strcasecmp(s,"no") || !strcasecmp(s,"SD_IGNORE")){
02792 o->rxsdtype = SD_IGNORE;
02793 }
02794 else if (!strcasecmp(s,"usb") || !strcasecmp(s,"SD_HID")){
02795 o->rxsdtype = SD_HID;
02796 }
02797 else if (!strcasecmp(s,"usbinvert") || !strcasecmp(s,"SD_HID_INVERT")){
02798 o->rxsdtype = SD_HID_INVERT;
02799 }
02800 else if (!strcasecmp(s,"software") || !strcasecmp(s,"SD_XPMR")){
02801 o->rxsdtype = SD_XPMR;
02802 }
02803 else {
02804 ast_log(LOG_WARNING,"Unrecognized rxsdtype parameter: %s\n",s);
02805 }
02806
02807
02808 }
02809
02810
02811 static void store_rxgain(struct chan_usbradio_pvt *o, char *s)
02812 {
02813 float f;
02814 if (sscanf(s, "%30f", &f) == 1)
02815 o->rxgain = f;
02816 ast_debug(4, "set rxgain = %f\n", f);
02817 }
02818
02819
02820 static void store_rxvoiceadj(struct chan_usbradio_pvt *o, char *s)
02821 {
02822 float f;
02823 if (sscanf(s, "%30f", &f) == 1)
02824 o->rxvoiceadj = f;
02825 ast_debug(4, "set rxvoiceadj = %f\n", f);
02826 }
02827
02828
02829 static void store_rxctcssadj(struct chan_usbradio_pvt *o, char *s)
02830 {
02831 float f;
02832 if (sscanf(s, "%30f", &f) == 1)
02833 o->rxctcssadj = f;
02834 ast_debug(4, "set rxctcssadj = %f\n", f);
02835 }
02836
02837
02838 static void store_txtoctype(struct chan_usbradio_pvt *o, char *s)
02839 {
02840 if (!strcasecmp(s,"no") || !strcasecmp(s,"TOC_NONE")){
02841 o->txtoctype = TOC_NONE;
02842 }
02843 else if (!strcasecmp(s,"phase") || !strcasecmp(s,"TOC_PHASE")){
02844 o->txtoctype = TOC_PHASE;
02845 }
02846 else if (!strcasecmp(s,"notone") || !strcasecmp(s,"TOC_NOTONE")){
02847 o->txtoctype = TOC_NOTONE;
02848 }
02849 else {
02850 ast_log(LOG_WARNING,"Unrecognized txtoctype parameter: %s\n",s);
02851 }
02852 }
02853
02854
02855 static void tune_txoutput(struct chan_usbradio_pvt *o, int value, int fd)
02856 {
02857 o->txtestkey=1;
02858 o->pmrChan->txPttIn=1;
02859 TxTestTone(o->pmrChan, 1);
02860 if (fd > 0) ast_cli(fd,"Tone output starting on channel %s...\n",o->name);
02861 usleep(5000000);
02862 TxTestTone(o->pmrChan, 0);
02863 if (fd > 0) ast_cli(fd,"Tone output ending on channel %s...\n",o->name);
02864 o->pmrChan->txPttIn=0;
02865 o->txtestkey=0;
02866 }
02867
02868
02869 static void tune_rxinput(int fd, struct chan_usbradio_pvt *o)
02870 {
02871 const int target=23000;
02872 const int tolerance=2000;
02873 const int settingmin=1;
02874 const int settingstart=2;
02875 const int maxtries=12;
02876
02877 float settingmax;
02878
02879 int setting=0, tries=0, tmpdiscfactor, meas;
02880 int tunetype=0;
02881
02882 settingmax = o->micmax;
02883
02884 if(o->pmrChan->rxDemod)tunetype=1;
02885 o->pmrChan->b.tuning=1;
02886
02887 setting = settingstart;
02888
02889 ast_cli(fd,"tune rxnoise maxtries=%i, target=%i, tolerance=%i\n",maxtries,target,tolerance);
02890
02891 while(tries<maxtries)
02892 {
02893 setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL,setting,0);
02894 setamixer(o->devicenum,MIXER_PARAM_MIC_BOOST,o->rxboostset,0);
02895
02896 usleep(100000);
02897 if(o->rxcdtype!=CD_XPMR_NOISE || o->rxdemod==RX_AUDIO_SPEAKER)
02898 {
02899
02900 o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
02901 o->pmrChan->spsMeasure->discfactor=2000;
02902 o->pmrChan->spsMeasure->enabled=1;
02903 o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
02904 usleep(400000);
02905 meas=o->pmrChan->spsMeasure->apeak;
02906 o->pmrChan->spsMeasure->enabled=0;
02907 }
02908 else
02909 {
02910
02911 tmpdiscfactor=o->pmrChan->spsRx->discfactor;
02912 o->pmrChan->spsRx->discfactor=(i16)2000;
02913 o->pmrChan->spsRx->discounteru=o->pmrChan->spsRx->discounterl=0;
02914 o->pmrChan->spsRx->amax=o->pmrChan->spsRx->amin=0;
02915 usleep(200000);
02916 meas=o->pmrChan->rxRssi;
02917 o->pmrChan->spsRx->discfactor=tmpdiscfactor;
02918 o->pmrChan->spsRx->discounteru=o->pmrChan->spsRx->discounterl=0;
02919 o->pmrChan->spsRx->amax=o->pmrChan->spsRx->amin=0;
02920 }
02921 if(!meas)meas++;
02922 ast_cli(fd,"tries=%i, setting=%i, meas=%i\n",tries,setting,meas);
02923
02924 if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
02925 setting=setting*target/meas;
02926 }
02927 else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
02928 {
02929 break;
02930 }
02931
02932 if(setting<settingmin)setting=settingmin;
02933 else if(setting>settingmax)setting=settingmax;
02934
02935 tries++;
02936 }
02937 ast_cli(fd,"DONE tries=%i, setting=%i, meas=%i\n",tries,
02938 (setting * 1000) / o->micmax,meas);
02939 if( meas<(target-tolerance) || meas>(target+tolerance) ){
02940 ast_cli(fd,"ERROR: RX INPUT ADJUST FAILED.\n");
02941 }else{
02942 ast_cli(fd,"INFO: RX INPUT ADJUST SUCCESS.\n");
02943 o->rxmixerset=(setting * 1000) / o->micmax;
02944 }
02945 o->pmrChan->b.tuning=0;
02946 }
02947
02948
02949 static void tune_rxvoice(int fd, struct chan_usbradio_pvt *o)
02950 {
02951 const int target=7200;
02952 const int tolerance=360;
02953 const float settingmin=0.1;
02954 const float settingmax=4;
02955 const float settingstart=1;
02956 const int maxtries=12;
02957
02958 float setting;
02959
02960 int tries=0, meas;
02961
02962 ast_cli(fd,"INFO: RX VOICE ADJUST START.\n");
02963 ast_cli(fd,"target=%i tolerance=%i \n",target,tolerance);
02964
02965 o->pmrChan->b.tuning=1;
02966 if(!o->pmrChan->spsMeasure)
02967 ast_cli(fd,"ERROR: NO MEASURE BLOCK.\n");
02968
02969 if(!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
02970 ast_cli(fd,"ERROR: NO SOURCE OR MEASURE SETTING.\n");
02971
02972 o->pmrChan->spsMeasure->source=o->pmrChan->spsRxOut->sink;
02973 o->pmrChan->spsMeasure->enabled=1;
02974 o->pmrChan->spsMeasure->discfactor=1000;
02975
02976 setting=settingstart;
02977
02978
02979
02980 while(tries<maxtries)
02981 {
02982 *(o->pmrChan->prxVoiceAdjust)=setting*M_Q8;
02983 usleep(10000);
02984 o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
02985 usleep(1000000);
02986 meas = o->pmrChan->spsMeasure->apeak;
02987 ast_cli(fd,"tries=%i, setting=%f, meas=%i\n",tries,setting,meas);
02988
02989 if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
02990 setting=setting*target/meas;
02991 }
02992 else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
02993 {
02994 break;
02995 }
02996 if(setting<settingmin)setting=settingmin;
02997 else if(setting>settingmax)setting=settingmax;
02998
02999 tries++;
03000 }
03001
03002 o->pmrChan->spsMeasure->enabled=0;
03003
03004 ast_cli(fd,"DONE tries=%i, setting=%f, meas=%f\n",tries,setting,(float)meas);
03005 if( meas<(target-tolerance) || meas>(target+tolerance) ){
03006 ast_cli(fd,"ERROR: RX VOICE GAIN ADJUST FAILED.\n");
03007 }else{
03008 ast_cli(fd,"INFO: RX VOICE GAIN ADJUST SUCCESS.\n");
03009 o->rxvoiceadj=setting;
03010 }
03011 o->pmrChan->b.tuning=0;
03012 }
03013
03014
03015 static void tune_rxctcss(int fd, struct chan_usbradio_pvt *o)
03016 {
03017 const int target=2400;
03018 const int tolerance=100;
03019 const float settingmin=0.1;
03020 const float settingmax=8;
03021 const float settingstart=1;
03022 const int maxtries=12;
03023
03024 float setting;
03025 int tries=0, meas;
03026
03027 ast_cli(fd,"INFO: RX CTCSS ADJUST START.\n");
03028 ast_cli(fd,"target=%i tolerance=%i \n",target,tolerance);
03029
03030 o->pmrChan->b.tuning=1;
03031 o->pmrChan->spsMeasure->source=o->pmrChan->prxCtcssMeasure;
03032 o->pmrChan->spsMeasure->discfactor=400;
03033 o->pmrChan->spsMeasure->enabled=1;
03034
03035 setting=settingstart;
03036
03037 while(tries<maxtries)
03038 {
03039 *(o->pmrChan->prxCtcssAdjust)=setting*M_Q8;
03040 usleep(10000);
03041 o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
03042 usleep(500000);
03043 meas = o->pmrChan->spsMeasure->apeak;
03044 ast_cli(fd,"tries=%i, setting=%f, meas=%i\n",tries,setting,meas);
03045
03046 if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
03047 setting=setting*target/meas;
03048 }
03049 else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
03050 {
03051 break;
03052 }
03053 if(setting<settingmin)setting=settingmin;
03054 else if(setting>settingmax)setting=settingmax;
03055
03056 tries++;
03057 }
03058 o->pmrChan->spsMeasure->enabled=0;
03059 ast_cli(fd,"DONE tries=%i, setting=%f, meas=%f\n",tries,setting,(float)meas);
03060 if( meas<(target-tolerance) || meas>(target+tolerance) ){
03061 ast_cli(fd,"ERROR: RX CTCSS GAIN ADJUST FAILED.\n");
03062 }else{
03063 ast_cli(fd,"INFO: RX CTCSS GAIN ADJUST SUCCESS.\n");
03064 o->rxctcssadj=setting;
03065 }
03066 o->pmrChan->b.tuning=0;
03067 }
03068
03069
03070
03071 static void tune_write(struct chan_usbradio_pvt *o)
03072 {
03073 FILE *fp;
03074 char fname[200];
03075
03076 snprintf(fname,sizeof(fname) - 1,"/etc/asterisk/usbradio_tune_%s.conf",o->name);
03077 fp = fopen(fname,"w");
03078
03079 fprintf(fp,"[%s]\n",o->name);
03080
03081 fprintf(fp,"; name=%s\n",o->name);
03082 fprintf(fp,"; devicenum=%i\n",o->devicenum);
03083 fprintf(fp,"devstr=%s\n",o->devstr);
03084 fprintf(fp,"rxmixerset=%i\n",o->rxmixerset);
03085 fprintf(fp,"txmixaset=%i\n",o->txmixaset);
03086 fprintf(fp,"txmixbset=%i\n",o->txmixbset);
03087 fprintf(fp,"rxvoiceadj=%f\n",o->rxvoiceadj);
03088 fprintf(fp,"rxctcssadj=%f\n",o->rxctcssadj);
03089 fprintf(fp,"txctcssadj=%i\n",o->txctcssadj);
03090 fprintf(fp,"rxsquelchadj=%i\n",o->rxsquelchadj);
03091 fclose(fp);
03092
03093 if(o->wanteeprom)
03094 {
03095 ast_mutex_lock(&o->eepromlock);
03096 while(o->eepromctl)
03097 {
03098 ast_mutex_unlock(&o->eepromlock);
03099 usleep(10000);
03100 ast_mutex_lock(&o->eepromlock);
03101 }
03102 o->eeprom[EEPROM_RXMIXERSET] = o->rxmixerset;
03103 o->eeprom[EEPROM_TXMIXASET] = o->txmixaset;
03104 o->eeprom[EEPROM_TXMIXBSET] = o->txmixbset;
03105 memcpy(&o->eeprom[EEPROM_RXVOICEADJ],&o->rxvoiceadj,sizeof(float));
03106 memcpy(&o->eeprom[EEPROM_RXCTCSSADJ],&o->rxctcssadj,sizeof(float));
03107 o->eeprom[EEPROM_TXCTCSSADJ] = o->txctcssadj;
03108 o->eeprom[EEPROM_RXSQUELCHADJ] = o->rxsquelchadj;
03109 o->eepromctl = 2;
03110 ast_mutex_unlock(&o->eepromlock);
03111 }
03112 }
03113
03114 static void mixer_write(struct chan_usbradio_pvt *o)
03115 {
03116 setamixer(o->devicenum,MIXER_PARAM_MIC_PLAYBACK_SW,0,0);
03117 setamixer(o->devicenum,MIXER_PARAM_MIC_PLAYBACK_VOL,0,0);
03118 setamixer(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_SW,1,0);
03119 setamixer(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_VOL,
03120 o->txmixaset * o->spkrmax / 1000,
03121 o->txmixbset * o->spkrmax / 1000);
03122 setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL,
03123 o->rxmixerset * o->micmax / 1000,0);
03124 setamixer(o->devicenum,MIXER_PARAM_MIC_BOOST,o->rxboostset,0);
03125 setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_SW,1,0);
03126 }
03127
03128
03129
03130 static void mult_set(struct chan_usbradio_pvt *o)
03131 {
03132
03133 if(o->pmrChan->spsTxOutA) {
03134 o->pmrChan->spsTxOutA->outputGain =
03135 mult_calc((o->txmixaset * 152) / 1000);
03136 }
03137 if(o->pmrChan->spsTxOutB){
03138 o->pmrChan->spsTxOutB->outputGain =
03139 mult_calc((o->txmixbset * 152) / 1000);
03140 }
03141 }
03142
03143
03144
03145 static int mult_calc(int value)
03146 {
03147 const int multx=M_Q8;
03148 int pot,mult;
03149
03150 pot=((int)(value/4)*4)+2;
03151 mult = multx-( ( multx * (3-(value%4)) ) / (pot+2) );
03152 return(mult);
03153 }
03154
03155 #define pd(x) {printf(#x" = %d\n",x);}
03156 #define pp(x) {printf(#x" = %p\n",x);}
03157 #define ps(x) {printf(#x" = %s\n",x);}
03158 #define pf(x) {printf(#x" = %f\n",x);}
03159
03160
03161 #if 0
03162
03163
03164
03165
03166
03167
03168 static int usbhider(struct chan_usbradio_pvt *o, int opt)
03169 {
03170 unsigned char buf[4];
03171 char lastrx, txtmp;
03172
03173 if(opt)
03174 {
03175 struct usb_device *usb_dev;
03176
03177 usb_dev = hid_device_init(o->devstr);
03178 if (usb_dev == NULL) {
03179 ast_log(LOG_ERROR,"USB HID device not found\n");
03180 return -1;
03181 }
03182 o->usb_handle = usb_open(usb_dev);
03183 if (o->usb_handle == NULL) {
03184 ast_log(LOG_ERROR,"Not able to open USB device\n");
03185 return -1;
03186 }
03187 if (usb_claim_interface(o->usb_handle,C108_HID_INTERFACE) < 0)
03188 {
03189 if (usb_detach_kernel_driver_np(o->usb_handle,C108_HID_INTERFACE) < 0) {
03190 ast_log(LOG_ERROR,"Not able to detach the USB device\n");
03191 return -1;
03192 }
03193 if (usb_claim_interface(o->usb_handle,C108_HID_INTERFACE) < 0) {
03194 ast_log(LOG_ERROR,"Not able to claim the USB device\n");
03195 return -1;
03196 }
03197 }
03198
03199 memset(buf,0,sizeof(buf));
03200 buf[2] = o->hid_gpio_ctl;
03201 buf[1] = 0;
03202 hid_set_outputs(o->usb_handle,buf);
03203 memcpy(bufsave,buf,sizeof(buf));
03204
03205 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
03206 o->lasttx=0;
03207 }
03208
03209
03210 txtmp=o->pmrChan->txPttOut;
03211
03212 if (o->lasttx != txtmp)
03213 {
03214 o->pmrChan->txPttHid=o->lasttx = txtmp;
03215 if(o->debuglevel)printf("usbhid: tx set to %d\n",txtmp);
03216 buf[o->hid_gpio_loc] = 0;
03217 if (!o->invertptt)
03218 {
03219 if (txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
03220 }
03221 else
03222 {
03223 if (!txtmp) buf[o->hid_gpio_loc] = o->hid_io_ptt;
03224 }
03225 buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
03226 hid_set_outputs(o->usb_handle,buf);
03227 }
03228
03229 return(0);
03230 }
03231 #endif
03232
03233
03234 static void pmrdump(struct chan_usbradio_pvt *o)
03235 {
03236 t_pmr_chan *p;
03237 int i;
03238
03239 p=o->pmrChan;
03240
03241 printf("\nodump()\n");
03242
03243 pd(o->devicenum);
03244 ps(o->devstr);
03245
03246 pd(o->micmax);
03247 pd(o->spkrmax);
03248
03249 pd(o->rxdemod);
03250 pd(o->rxcdtype);
03251 pd(o->rxsdtype);
03252 pd(o->txtoctype);
03253
03254 pd(o->rxmixerset);
03255 pd(o->rxboostset);
03256
03257 pf(o->rxvoiceadj);
03258 pf(o->rxctcssadj);
03259 pd(o->rxsquelchadj);
03260
03261 ps(o->txctcssdefault);
03262 ps(o->txctcssfreq);
03263
03264 pd(o->numrxctcssfreqs);
03265 if(o->numrxctcssfreqs>0)
03266 {
03267 for(i=0;i<o->numrxctcssfreqs;i++)
03268 {
03269 printf(" %i = %s %s\n",i,o->rxctcss[i],o->txctcss[i]);
03270 }
03271 }
03272
03273 pd(o->b.rxpolarity);
03274 pd(o->b.txpolarity);
03275
03276 pd(o->txprelim);
03277 pd(o->txmixa);
03278 pd(o->txmixb);
03279
03280 pd(o->txmixaset);
03281 pd(o->txmixbset);
03282
03283 printf("\npmrdump()\n");
03284
03285 pd(p->devicenum);
03286
03287 printf("prxSquelchAdjust=%i\n",*(o->pmrChan->prxSquelchAdjust));
03288
03289 pd(p->rxCarrierPoint);
03290 pd(p->rxCarrierHyst);
03291
03292 pd(*p->prxVoiceAdjust);
03293 pd(*p->prxCtcssAdjust);
03294
03295 pd(p->rxfreq);
03296 pd(p->txfreq);
03297
03298 pd(p->rxCtcss->relax);
03299
03300 pd(p->numrxcodes);
03301 if(o->pmrChan->numrxcodes>0)
03302 {
03303 for(i=0;i<o->pmrChan->numrxcodes;i++)
03304 {
03305 printf(" %i = %s\n",i,o->pmrChan->pRxCode[i]);
03306 }
03307 }
03308
03309 pd(p->txTocType);
03310 ps(p->pTxCodeDefault);
03311 pd(p->txcodedefaultsmode);
03312 pd(p->numtxcodes);
03313 if(o->pmrChan->numtxcodes>0)
03314 {
03315 for(i=0;i<o->pmrChan->numtxcodes;i++)
03316 {
03317 printf(" %i = %s\n",i,o->pmrChan->pTxCode[i]);
03318 }
03319 }
03320
03321 pd(p->b.rxpolarity);
03322 pd(p->b.txpolarity);
03323 pd(p->b.dcsrxpolarity);
03324 pd(p->b.dcstxpolarity);
03325 pd(p->b.lsdrxpolarity);
03326 pd(p->b.lsdtxpolarity);
03327
03328 pd(p->txMixA);
03329 pd(p->txMixB);
03330
03331 pd(p->rxDeEmpEnable);
03332 pd(p->rxCenterSlicerEnable);
03333 pd(p->rxCtcssDecodeEnable);
03334 pd(p->rxDcsDecodeEnable);
03335 pd(p->b.ctcssRxEnable);
03336 pd(p->b.dcsRxEnable);
03337 pd(p->b.lmrRxEnable);
03338 pd(p->b.dstRxEnable);
03339 pd(p->smode);
03340
03341 pd(p->txHpfEnable);
03342 pd(p->txLimiterEnable);
03343 pd(p->txPreEmpEnable);
03344 pd(p->txLpfEnable);
03345
03346 if(p->spsTxOutA)pd(p->spsTxOutA->outputGain);
03347 if(p->spsTxOutB)pd(p->spsTxOutB->outputGain);
03348 pd(p->txPttIn);
03349 pd(p->txPttOut);
03350
03351 pd(p->tracetype);
03352
03353 return;
03354 }
03355
03356
03357
03358
03359 static int xpmr_config(struct chan_usbradio_pvt *o)
03360 {
03361
03362
03363 TRACEO(1,("xpmr_config()\n"));
03364
03365 if(o->pmrChan==NULL)
03366 {
03367 ast_log(LOG_ERROR,"pmr channel structure NULL\n");
03368 return 1;
03369 }
03370
03371 o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
03372 o->pmrChan->txpower=0;
03373
03374 if(o->b.remoted)
03375 {
03376 o->pmrChan->pTxCodeDefault = o->set_txctcssdefault;
03377 o->pmrChan->pRxCodeSrc=o->set_rxctcssfreqs;
03378 o->pmrChan->pTxCodeSrc=o->set_txctcssfreqs;
03379
03380 o->pmrChan->rxfreq=o->set_rxfreq;
03381 o->pmrChan->txfreq=o->set_txfreq;
03382
03383
03384 }
03385 else
03386 {
03387
03388
03389 o->pmrChan->pTxCodeDefault = o->txctcssdefault;
03390 o->pmrChan->pRxCodeSrc = o->rxctcssfreqs;
03391 o->pmrChan->pTxCodeSrc = o->txctcssfreqs;
03392
03393 o->pmrChan->rxfreq = o->rxfreq;
03394 o->pmrChan->txfreq = o->txfreq;
03395 }
03396
03397 code_string_parse(o->pmrChan);
03398 if(o->pmrChan->rxfreq) o->pmrChan->b.reprog=1;
03399
03400 return 0;
03401 }
03402
03403
03404
03405 static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
03406 {
03407 struct ast_variable *v;
03408 struct chan_usbradio_pvt *o;
03409 struct ast_config *cfg1;
03410 int i;
03411 char fname[200];
03412 #ifdef NEW_ASTERISK
03413 struct ast_flags zeroflag = {0};
03414 #endif
03415 if (ctg == NULL) {
03416 traceusb1((" store_config() ctg == NULL\n"));
03417 o = &usbradio_default;
03418 ctg = "general";
03419 } else {
03420
03421 if (strcmp(ctg, "general") == 0) {
03422 o = &usbradio_default;
03423 } else {
03424
03425 if (!(o = ast_calloc(1, sizeof(*o))))
03426 return NULL;
03427 *o = usbradio_default;
03428 o->name = ast_strdup(ctg);
03429 if (!usbradio_active)
03430 usbradio_active = o->name;
03431 }
03432 }
03433 ast_mutex_init(&o->eepromlock);
03434 strcpy(o->mohinterpret, "default");
03435
03436 for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
03437 M_START((char *)v->name, (char *)v->value);
03438
03439
03440 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
03441 continue;
03442
03443 #if 0
03444 M_BOOL("autoanswer", o->autoanswer)
03445 M_BOOL("autohangup", o->autohangup)
03446 M_BOOL("overridecontext", o->overridecontext)
03447 M_STR("context", o->ctx)
03448 M_STR("language", o->language)
03449 M_STR("mohinterpret", o->mohinterpret)
03450 M_STR("extension", o->ext)
03451 M_F("callerid", store_callerid(o, v->value))
03452 #endif
03453 M_UINT("frags", o->frags)
03454 M_UINT("queuesize",o->queuesize)
03455 #if 0
03456 M_UINT("devicenum",o->devicenum)
03457 #endif
03458 M_UINT("debug", usbradio_debug)
03459 M_BOOL("rxcpusaver",o->rxcpusaver)
03460 M_BOOL("txcpusaver",o->txcpusaver)
03461 M_BOOL("invertptt",o->invertptt)
03462 M_F("rxdemod",store_rxdemod(o,(char *)v->value))
03463 M_BOOL("txprelim",o->txprelim);
03464 M_F("txmixa",store_txmixa(o,(char *)v->value))
03465 M_F("txmixb",store_txmixb(o,(char *)v->value))
03466 M_F("carrierfrom",store_rxcdtype(o,(char *)v->value))
03467 M_F("rxsdtype",store_rxsdtype(o,(char *)v->value))
03468 M_UINT("rxsqvox",o->rxsqvoxadj)
03469 M_STR("txctcssdefault",o->txctcssdefault)
03470 M_STR("rxctcssfreqs",o->rxctcssfreqs)
03471 M_STR("txctcssfreqs",o->txctcssfreqs)
03472 M_UINT("rxfreq",o->rxfreq)
03473 M_UINT("txfreq",o->txfreq)
03474 M_F("rxgain",store_rxgain(o,(char *)v->value))
03475 M_BOOL("rxboost",o->rxboostset)
03476 M_UINT("rxctcssrelax",o->rxctcssrelax)
03477 M_F("txtoctype",store_txtoctype(o,(char *)v->value))
03478 M_UINT("hdwtype",o->hdwtype)
03479 M_UINT("eeprom",o->wanteeprom)
03480 M_UINT("duplex",o->radioduplex)
03481 M_UINT("txsettletime",o->txsettletime)
03482 M_BOOL("rxpolarity",o->b.rxpolarity)
03483 M_BOOL("txpolarity",o->b.txpolarity)
03484 M_BOOL("dcsrxpolarity",o->b.dcsrxpolarity)
03485 M_BOOL("dcstxpolarity",o->b.dcstxpolarity)
03486 M_BOOL("lsdrxpolarity",o->b.lsdrxpolarity)
03487 M_BOOL("lsdtxpolarity",o->b.lsdtxpolarity)
03488 M_BOOL("loopback",o->b.loopback)
03489 M_BOOL("radioactive",o->b.radioactive)
03490 M_UINT("rptnum",o->rptnum)
03491 M_UINT("idleinterval",o->idleinterval)
03492 M_UINT("turnoffs",o->turnoffs)
03493 M_UINT("tracetype",o->tracetype)
03494 M_UINT("tracelevel",o->tracelevel)
03495 M_UINT("area",o->area)
03496 M_STR("ukey",o->ukey)
03497 M_END(;
03498 );
03499 }
03500
03501 o->debuglevel=0;
03502
03503 if (o == &usbradio_default)
03504 return NULL;
03505
03506 snprintf(fname,sizeof(fname) - 1,config1,o->name);
03507 #ifdef NEW_ASTERISK
03508 cfg1 = ast_config_load(fname,zeroflag);
03509 #else
03510 cfg1 = ast_config_load(fname);
03511 #endif
03512 o->rxmixerset = 500;
03513 o->txmixaset = 500;
03514 o->txmixbset = 500;
03515 o->rxvoiceadj = 0.5;
03516 o->rxctcssadj = 0.5;
03517 o->txctcssadj = 200;
03518 o->rxsquelchadj = 500;
03519 o->devstr[0] = 0;
03520 if (cfg1) {
03521 for (v = ast_variable_browse(cfg1, o->name); v; v = v->next) {
03522
03523 M_START((char *)v->name, (char *)v->value);
03524 M_UINT("rxmixerset", o->rxmixerset)
03525 M_UINT("txmixaset", o->txmixaset)
03526 M_UINT("txmixbset", o->txmixbset)
03527 M_F("rxvoiceadj",store_rxvoiceadj(o,(char *)v->value))
03528 M_F("rxctcssadj",store_rxctcssadj(o,(char *)v->value))
03529 M_UINT("txctcssadj",o->txctcssadj);
03530 M_UINT("rxsquelchadj", o->rxsquelchadj)
03531 M_STR("devstr", o->devstr)
03532 M_END(;
03533 );
03534 }
03535 ast_config_destroy(cfg1);
03536 } else ast_log(LOG_WARNING,"File %s not found, using default parameters.\n",fname);
03537
03538 if(o->wanteeprom)
03539 {
03540 ast_mutex_lock(&o->eepromlock);
03541 while(o->eepromctl)
03542 {
03543 ast_mutex_unlock(&o->eepromlock);
03544 usleep(10000);
03545 ast_mutex_lock(&o->eepromlock);
03546 }
03547 o->eepromctl = 1;
03548 ast_mutex_unlock(&o->eepromlock);
03549 }
03550
03551 if ((!usb_list_check(o->devstr)) || find_desc_usb(o->devstr))
03552 {
03553 char *s;
03554
03555 for(s = usb_device_list; *s; s += strlen(s) + 1)
03556 {
03557 if (!find_desc_usb(s)) break;
03558 }
03559 if (!*s)
03560 {
03561 ast_log(LOG_WARNING,"Unable to assign USB device for channel %s\n",o->name);
03562 goto error;
03563 }
03564 ast_log(LOG_NOTICE,"Assigned USB device %s to usbradio channel %s\n",s,o->name);
03565 strcpy(o->devstr,s);
03566 }
03567
03568 i = usb_get_usbdev(o->devstr);
03569 if (i < 0)
03570 {
03571 ast_log(LOG_ERROR,"Not able to find alsa USB device\n");
03572 goto error;
03573 }
03574 o->devicenum = i;
03575
03576 o->micmax = amixer_max(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL);
03577 o->spkrmax = amixer_max(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_VOL);
03578 o->lastopen = ast_tvnow();
03579 o->dsp = ast_dsp_new();
03580 if (o->dsp)
03581 {
03582 #ifdef NEW_ASTERISK
03583 ast_dsp_set_features(o->dsp,DSP_FEATURE_DIGIT_DETECT);
03584 ast_dsp_set_digitmode(o->dsp,DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
03585 #else
03586 ast_dsp_set_features(o->dsp,DSP_FEATURE_DTMF_DETECT);
03587 ast_dsp_digitmode(o->dsp,DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
03588 #endif
03589 }
03590
03591 if(o->pmrChan==NULL)
03592 {
03593 t_pmr_chan tChan;
03594
03595
03596 memset(&tChan,0,sizeof(t_pmr_chan));
03597
03598 tChan.pTxCodeDefault = o->txctcssdefault;
03599 tChan.pRxCodeSrc = o->rxctcssfreqs;
03600 tChan.pTxCodeSrc = o->txctcssfreqs;
03601
03602 tChan.rxDemod=o->rxdemod;
03603 tChan.rxCdType=o->rxcdtype;
03604 tChan.rxSqVoxAdj=o->rxsqvoxadj;
03605
03606 if (o->txprelim)
03607 tChan.txMod = 2;
03608
03609 tChan.txMixA = o->txmixa;
03610 tChan.txMixB = o->txmixb;
03611
03612 tChan.rxCpuSaver=o->rxcpusaver;
03613 tChan.txCpuSaver=o->txcpusaver;
03614
03615 tChan.b.rxpolarity=o->b.rxpolarity;
03616 tChan.b.txpolarity=o->b.txpolarity;
03617
03618 tChan.b.dcsrxpolarity=o->b.dcsrxpolarity;
03619 tChan.b.dcstxpolarity=o->b.dcstxpolarity;
03620
03621 tChan.b.lsdrxpolarity=o->b.lsdrxpolarity;
03622 tChan.b.lsdtxpolarity=o->b.lsdtxpolarity;
03623
03624 tChan.tracetype=o->tracetype;
03625 tChan.tracelevel=o->tracelevel;
03626 tChan.rptnum=o->rptnum;
03627 tChan.idleinterval=o->idleinterval;
03628 tChan.turnoffs=o->turnoffs;
03629 tChan.area=o->area;
03630 tChan.ukey=o->ukey;
03631 tChan.name=o->name;
03632
03633 o->pmrChan=createPmrChannel(&tChan,FRAME_SIZE);
03634
03635 o->pmrChan->radioDuplex=o->radioduplex;
03636 o->pmrChan->b.loopback=0;
03637 o->pmrChan->txsettletime=o->txsettletime;
03638 o->pmrChan->rxCpuSaver=o->rxcpusaver;
03639 o->pmrChan->txCpuSaver=o->txcpusaver;
03640
03641 *(o->pmrChan->prxSquelchAdjust) =
03642 ((999 - o->rxsquelchadj) * 32767) / 1000;
03643
03644 *(o->pmrChan->prxVoiceAdjust)=o->rxvoiceadj*M_Q8;
03645 *(o->pmrChan->prxCtcssAdjust)=o->rxctcssadj*M_Q8;
03646 o->pmrChan->rxCtcss->relax=o->rxctcssrelax;
03647 o->pmrChan->txTocType = o->txtoctype;
03648
03649 if ( (o->txmixa == TX_OUT_LSD) ||
03650 (o->txmixa == TX_OUT_COMPOSITE) ||
03651 (o->txmixb == TX_OUT_LSD) ||
03652 (o->txmixb == TX_OUT_COMPOSITE))
03653 {
03654 set_txctcss_level(o);
03655 }
03656
03657 if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
03658 (o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
03659 )
03660 {
03661 ast_log(LOG_ERROR,"No txvoice output configured.\n");
03662 }
03663
03664 if( o->txctcssfreq[0] &&
03665 o->txmixa!=TX_OUT_LSD && o->txmixa!=TX_OUT_COMPOSITE &&
03666 o->txmixb!=TX_OUT_LSD && o->txmixb!=TX_OUT_COMPOSITE
03667 )
03668 {
03669 ast_log(LOG_ERROR,"No txtone output configured.\n");
03670 }
03671
03672 if(o->b.radioactive)
03673 {
03674
03675
03676
03677
03678
03679 usbradio_active = o->name;
03680
03681
03682
03683 ast_log(LOG_NOTICE,"radio active set to [%s]\n",o->name);
03684 }
03685 }
03686
03687 xpmr_config(o);
03688
03689 TRACEO(1,("store_config() 120\n"));
03690 mixer_write(o);
03691 TRACEO(1,("store_config() 130\n"));
03692 mult_set(o);
03693 TRACEO(1,("store_config() 140\n"));
03694 hidhdwconfig(o);
03695
03696 TRACEO(1,("store_config() 200\n"));
03697
03698 #ifndef NEW_ASTERISK
03699 if (pipe(o->sndcmd) != 0) {
03700 ast_log(LOG_ERROR, "Unable to create pipe\n");
03701 goto error;
03702 }
03703
03704 ast_pthread_create_background(&o->sthread, NULL, sound_thread, o);
03705 #endif
03706
03707
03708 if (o != &usbradio_default) {
03709 o->next = usbradio_default.next;
03710 usbradio_default.next = o;
03711 }
03712 TRACEO(1,("store_config() complete\n"));
03713 return o;
03714
03715 error:
03716 if (o != &usbradio_default)
03717 free(o);
03718 return NULL;
03719 }
03720
03721
03722 #if DEBUG_FILETEST == 1
03723
03724
03725
03726 int RxTestIt(struct chan_usbradio_pvt *o)
03727 {
03728 const int numSamples = SAMPLES_PER_BLOCK;
03729 const int numChannels = 16;
03730
03731 i16 sample,i,ii;
03732
03733 i32 txHangTime;
03734
03735 i16 txEnable;
03736
03737 t_pmr_chan tChan;
03738 t_pmr_chan *pChan;
03739
03740 FILE *hInput=NULL, *hOutput=NULL, *hOutputTx=NULL;
03741
03742 i16 iBuff[numSamples*2*6], oBuff[numSamples];
03743
03744 printf("RxTestIt()\n");
03745
03746 pChan=o->pmrChan;
03747 pChan->b.txCapture=1;
03748 pChan->b.rxCapture=1;
03749
03750 txEnable = 0;
03751
03752 hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm","r");
03753 if(!hInput){
03754 printf(" RxTestIt() File Not Found.\n");
03755 return 0;
03756 }
03757 hOutput = fopen("/usr/src/xpmr/testdata/rx_debug.pcm","w");
03758
03759 printf(" RxTestIt() Working...\n");
03760
03761 while(!feof(hInput))
03762 {
03763 fread((void *)iBuff,2,numSamples*2*6,hInput);
03764
03765 if(txHangTime)txHangTime-=numSamples;
03766 if(txHangTime<0)txHangTime=0;
03767
03768 if(pChan->rxCtcss->decode)txHangTime=(8000/1000*2000);
03769
03770 if(pChan->rxCtcss->decode && !txEnable)
03771 {
03772 txEnable=1;
03773
03774 }
03775 else if(!pChan->rxCtcss->decode && txEnable)
03776 {
03777 txEnable=0;
03778 }
03779
03780 PmrRx(pChan,iBuff,oBuff);
03781
03782 if (fwrite((void *)pChan->prxDebug,2,numSamples*numChannels,hOutput) != numSamples * numChannels) {
03783 ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
03784 }
03785 }
03786 pChan->b.txCapture=0;
03787 pChan->b.rxCapture=0;
03788
03789 if(hInput)fclose(hInput);
03790 if(hOutput)fclose(hOutput);
03791
03792 printf(" RxTestIt() Complete.\n");
03793
03794 return 0;
03795 }
03796 #endif
03797
03798 #ifdef NEW_ASTERISK
03799
03800 static char *res2cli(int r)
03801
03802 {
03803 switch (r)
03804 {
03805 case RESULT_SUCCESS:
03806 return(CLI_SUCCESS);
03807 case RESULT_SHOWUSAGE:
03808 return(CLI_SHOWUSAGE);
03809 default:
03810 return(CLI_FAILURE);
03811 }
03812 }
03813
03814 static char *handle_console_key(struct ast_cli_entry *e,
03815 int cmd, struct ast_cli_args *a)
03816 {
03817 switch (cmd) {
03818 case CLI_INIT:
03819 e->command = "radio key";
03820 e->usage = key_usage;
03821 return NULL;
03822 case CLI_GENERATE:
03823 return NULL;
03824 }
03825 return res2cli(console_key(a->fd,a->argc,a->argv));
03826 }
03827
03828 static char *handle_console_unkey(struct ast_cli_entry *e,
03829 int cmd, struct ast_cli_args *a)
03830 {
03831 switch (cmd) {
03832 case CLI_INIT:
03833 e->command = "radio unkey";
03834 e->usage = unkey_usage;
03835 return NULL;
03836 case CLI_GENERATE:
03837 return NULL;
03838 }
03839 return res2cli(console_unkey(a->fd,a->argc,a->argv));
03840 }
03841
03842 static char *handle_radio_tune(struct ast_cli_entry *e,
03843 int cmd, struct ast_cli_args *a)
03844 {
03845 switch (cmd) {
03846 case CLI_INIT:
03847 e->command = "radio tune";
03848 e->usage = radio_tune_usage;
03849 return NULL;
03850 case CLI_GENERATE:
03851 return NULL;
03852 }
03853 return res2cli(radio_tune(a->fd,a->argc,a->argv));
03854 }
03855
03856 static char *handle_radio_debug(struct ast_cli_entry *e,
03857 int cmd, struct ast_cli_args *a)
03858 {
03859 switch (cmd) {
03860 case CLI_INIT:
03861 e->command = "radio debug";
03862 e->usage = radio_tune_usage;
03863 return NULL;
03864 case CLI_GENERATE:
03865 return NULL;
03866 }
03867 return res2cli(radio_set_debug(a->fd,a->argc,a->argv));
03868 }
03869
03870 static char *handle_radio_debug_off(struct ast_cli_entry *e,
03871 int cmd, struct ast_cli_args *a)
03872 {
03873 switch (cmd) {
03874 case CLI_INIT:
03875 e->command = "radio debug off";
03876 e->usage = radio_tune_usage;
03877 return NULL;
03878 case CLI_GENERATE:
03879 return NULL;
03880 }
03881 return res2cli(radio_set_debug_off(a->fd,a->argc,a->argv));
03882 }
03883
03884 static char *handle_radio_active(struct ast_cli_entry *e,
03885 int cmd, struct ast_cli_args *a)
03886 {
03887 switch (cmd) {
03888 case CLI_INIT:
03889 e->command = "radio active";
03890 e->usage = active_usage;
03891 return NULL;
03892 case CLI_GENERATE:
03893 return NULL;
03894 }
03895 return res2cli(radio_active(a->fd,a->argc,a->argv));
03896 }
03897
03898 static char *handle_set_xdebug(struct ast_cli_entry *e,
03899 int cmd, struct ast_cli_args *a)
03900 {
03901 switch (cmd) {
03902 case CLI_INIT:
03903 e->command = "radio set xdebug";
03904 e->usage = active_usage;
03905 return NULL;
03906 case CLI_GENERATE:
03907 return NULL;
03908 }
03909 return res2cli(radio_set_xpmr_debug(a->fd,a->argc,a->argv));
03910 }
03911
03912
03913 static struct ast_cli_entry cli_usbradio[] = {
03914 AST_CLI_DEFINE(handle_console_key,"Simulate Rx Signal Present"),
03915 AST_CLI_DEFINE(handle_console_unkey,"Simulate Rx Signal Loss"),
03916 AST_CLI_DEFINE(handle_radio_tune,"Radio Tune"),
03917 AST_CLI_DEFINE(handle_radio_debug,"Radio Debug On"),
03918 AST_CLI_DEFINE(handle_radio_debug_off,"Radio Debug Off"),
03919 AST_CLI_DEFINE(handle_radio_active,"Change commanded device"),
03920 AST_CLI_DEFINE(handle_set_xdebug,"Radio set xpmr debug level")
03921 };
03922
03923 #endif
03924
03925 #include "./xpmr/xpmr.c"
03926 #ifdef HAVE_XPMRX
03927 #include "./xpmrx/xpmrx.c"
03928 #endif
03929
03930
03931
03932 static int load_module(void)
03933 {
03934 struct ast_config *cfg = NULL;
03935 char *ctg = NULL;
03936 #ifdef NEW_ASTERISK
03937 struct ast_flags zeroflag = {0};
03938 #endif
03939
03940 if (hid_device_mklist()) {
03941 ast_log(LOG_NOTICE, "Unable to make hid list\n");
03942 return AST_MODULE_LOAD_DECLINE;
03943 }
03944
03945 usb_list_check("");
03946
03947 usbradio_active = NULL;
03948
03949
03950 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
03951
03952
03953 #ifdef NEW_ASTERISK
03954 if (!(cfg = ast_config_load(config,zeroflag))) {
03955 #else
03956 if (!(cfg = ast_config_load(config))) {
03957 #endif
03958 ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
03959 return AST_MODULE_LOAD_DECLINE;
03960 }
03961
03962 do {
03963 store_config(cfg, ctg);
03964 } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
03965
03966 ast_config_destroy(cfg);
03967
03968 if (find_desc(usbradio_active) == NULL) {
03969 ast_log(LOG_NOTICE, "radio active device %s not found\n", usbradio_active);
03970
03971
03972 return AST_MODULE_LOAD_FAILURE;
03973 }
03974
03975 if (ast_channel_register(&usbradio_tech)) {
03976 ast_log(LOG_ERROR, "Unable to register channel type 'usb'\n");
03977 return AST_MODULE_LOAD_FAILURE;
03978 }
03979
03980 ast_cli_register_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
03981
03982 return AST_MODULE_LOAD_SUCCESS;
03983 }
03984
03985
03986 static int unload_module(void)
03987 {
03988 struct chan_usbradio_pvt *o;
03989
03990 ast_log(LOG_WARNING, "unload_module() called\n");
03991
03992 ast_channel_unregister(&usbradio_tech);
03993 ast_cli_unregister_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
03994
03995 for (o = usbradio_default.next; o; o = o->next) {
03996
03997 ast_log(LOG_WARNING, "destroyPmrChannel() called\n");
03998 if(o->pmrChan)destroyPmrChannel(o->pmrChan);
03999
04000 #if DEBUG_CAPTURES == 1
04001 if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
04002 if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
04003 if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
04004 if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
04005 if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
04006 if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
04007 #endif
04008
04009 close(o->sounddev);
04010 #ifndef NEW_ASTERISK
04011 if (o->sndcmd[0] > 0) {
04012 close(o->sndcmd[0]);
04013 close(o->sndcmd[1]);
04014 }
04015 #endif
04016 if (o->dsp) ast_dsp_free(o->dsp);
04017 if (o->owner)
04018 ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
04019 if (o->owner)
04020 return -1;
04021
04022
04023 }
04024 return 0;
04025 }
04026
04027 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "usb Console Channel Driver");
04028
04029
04030
04031