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