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