Channel driver for CM108 USB Cards with Radio Interface. More...
#include "asterisk.h"#include <stdio.h>#include <ctype.h>#include <math.h>#include <string.h>#include <unistd.h>#include <sys/ioctl.h>#include <fcntl.h>#include <sys/time.h>#include <stdlib.h>#include <errno.h>#include <usb.h>#include <alsa/asoundlib.h>#include "./xpmr/xpmr.h"#include <soundcard.h>#include "asterisk/lock.h"#include "asterisk/frame.h"#include "asterisk/logger.h"#include "asterisk/callerid.h"#include "asterisk/channel.h"#include "asterisk/module.h"#include "asterisk/options.h"#include "asterisk/pbx.h"#include "asterisk/config.h"#include "asterisk/cli.h"#include "asterisk/utils.h"#include "asterisk/causes.h"#include "asterisk/endian.h"#include "asterisk/stringfields.h"#include "asterisk/abstract_jb.h"#include "asterisk/musiconhold.h"#include "asterisk/dsp.h"#include "busy.h"#include "ringtone.h"#include "ring10.h"#include "answer.h"#include "./xpmr/xpmr.c"
Go to the source code of this file.
Data Structures | |
| struct | chan_usbradio_pvt |
| struct | sound |
Defines | |
| #define | BOOST_MAX 40 |
| #define | BOOST_SCALE (1<<9) |
| #define | C108_HID_INTERFACE 3 |
| #define | C108_PRODUCT_ID 0x000c |
| #define | C108_VENDOR_ID 0x0d8c |
| #define | CHAN_USBRADIO 1 |
| #define | config1 "usbradio_tune_%s.conf" |
| #define | DEBUG_CAP_RX_OUT 0 |
| #define | DEBUG_CAP_TX_OUT 0 |
| #define | DEBUG_CAPTURES 1 |
| #define | DEBUG_FILETEST 0 |
| #define | DEBUG_USBRADIO 0 |
| #define | DELIMCHR ',' |
| #define | DEV_DSP "/dev/dsp" |
| #define | EEPROM_CS_ADDR 62 |
| #define | EEPROM_END_ADDR 63 |
| #define | EEPROM_MAGIC 34329 |
| #define | EEPROM_MAGIC_ADDR 6 |
| #define | EEPROM_PHYSICAL_LEN 64 |
| #define | EEPROM_RXCTCSSADJ 13 |
| #define | EEPROM_RXMIXERSET 8 |
| #define | EEPROM_RXSQUELCHADJ 16 |
| #define | EEPROM_RXVOICEADJ 11 |
| #define | EEPROM_START_ADDR 6 |
| #define | EEPROM_TEST_ADDR EEPROM_END_ADDR |
| #define | EEPROM_TXCTCSSADJ 15 |
| #define | EEPROM_TXMIXASET 9 |
| #define | EEPROM_TXMIXBSET 10 |
| #define | FRAGS ( ( (6 * 5) << 16 ) | 0xc ) |
| #define | FRAME_SIZE 160 |
| #define | HID_REPORT_GET 0x01 |
| #define | HID_REPORT_SET 0x09 |
| #define | HID_RT_INPUT 0x01 |
| #define | HID_RT_OUTPUT 0x02 |
| #define | M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) ) |
| #define | M_END(x) x; |
| #define | M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else |
| #define | M_START(var, val) char *__s = var; char *__val = val; |
| #define | M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst))) |
| #define | M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) ) |
| #define | MIXER_PARAM_MIC_BOOST "Auto Gain Control" |
| #define | MIXER_PARAM_MIC_CAPTURE_SW "Mic Capture Switch" |
| #define | MIXER_PARAM_MIC_CAPTURE_VOL "Mic Capture Volume" |
| #define | MIXER_PARAM_MIC_PLAYBACK_SW "Mic Playback Switch" |
| #define | MIXER_PARAM_MIC_PLAYBACK_VOL "Mic Playback Volume" |
| #define | MIXER_PARAM_SPKR_PLAYBACK_SW "Speaker Playback Switch" |
| #define | MIXER_PARAM_SPKR_PLAYBACK_VOL "Speaker Playback Volume" |
| #define | NEW_ASTERISK |
| #define | O_CLOSE 0x444 |
| #define | pd(x) {printf(#x" = %d\n",x);} |
| #define | pf(x) {printf(#x" = %f\n",x);} |
| #define | pp(x) {printf(#x" = %p\n",x);} |
| #define | ps(x) {printf(#x" = %s\n",x);} |
| #define | QUEUE_SIZE 2 |
| #define | QUOTECHR 34 |
| #define | READERR_THRESHOLD 50 |
| #define | RX_CAP_OUT_FILE "/tmp/rx_cap_out.pcm" |
| #define | RX_CAP_RAW_FILE "/tmp/rx_cap_in.pcm" |
| #define | RX_CAP_TRACE_FILE "/tmp/rx_trace.pcm" |
| #define | TEXT_SIZE 256 |
| #define | traceusb1(a) |
| #define | traceusb2(a) |
| #define | TX_CAP_OUT_FILE "/tmp/tx_cap_out.pcm" |
| #define | TX_CAP_RAW_FILE "/tmp/tx_cap_in.pcm" |
| #define | TX_CAP_TRACE_FILE "/tmp/tx_trace.pcm" |
| #define | WARN_frag 4 |
| #define | WARN_speed 2 |
| #define | WARN_used_blocks 1 |
Enumerations | |
| enum | { RX_AUDIO_NONE, RX_AUDIO_SPEAKER, RX_AUDIO_FLAT } |
| enum | { CD_IGNORE, CD_XPMR_NOISE, CD_XPMR_VOX, CD_HID, CD_HID_INVERT } |
| enum | { SD_IGNORE, SD_HID, SD_HID_INVERT, SD_XPMR } |
| enum | { RX_KEY_CARRIER, RX_KEY_CARRIER_CODE } |
| enum | { TX_OUT_OFF, TX_OUT_VOICE, TX_OUT_LSD, TX_OUT_COMPOSITE, TX_OUT_AUX } |
| enum | { TOC_NONE, TOC_PHASE, TOC_NOTONE } |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | amixer_max (int devnum, char *param) |
| static int | console_key (int fd, int argc, char *argv[]) |
| static int | console_unkey (int fd, int argc, char *argv[]) |
| static struct chan_usbradio_pvt * | find_desc (char *dev) |
| static struct chan_usbradio_pvt * | find_desc_usb (char *devstr) |
| static unsigned short | get_eeprom (struct usb_dev_handle *handle, unsigned short *buf) |
| static struct usb_device * | hid_device_init (char *desired_device) |
| static int | hid_device_mklist (void) |
| static void | hid_get_inputs (struct usb_dev_handle *handle, unsigned char *inputs) |
| static void | hid_set_outputs (struct usb_dev_handle *handle, unsigned char *outputs) |
| static int | hidhdwconfig (struct chan_usbradio_pvt *o) |
| static void * | hidthread (void *arg) |
| static void | kickptt (struct chan_usbradio_pvt *o) |
| static int | load_module (void) |
| static void | mixer_write (struct chan_usbradio_pvt *o) |
| static int | mult_calc (int value) |
| static void | mult_set (struct chan_usbradio_pvt *o) |
| static void | pmrdump (struct chan_usbradio_pvt *o) |
| static void | put_eeprom (struct usb_dev_handle *handle, unsigned short *buf) |
| static int | radio_active (int fd, int argc, char *argv[]) |
| static int | radio_set_debug (int fd, int argc, char *argv[]) |
| static int | radio_set_debug_off (int fd, int argc, char *argv[]) |
| static int | radio_set_xpmr_debug (int fd, int argc, char *argv[]) |
| static int | radio_tune (int fd, int argc, char *argv[]) |
| static unsigned short | read_eeprom (struct usb_dev_handle *handle, int addr) |
| static void | ring (struct chan_usbradio_pvt *o, int x) |
| static void | send_sound (struct chan_usbradio_pvt *o) |
| static int | set_txctcss_level (struct chan_usbradio_pvt *o) |
| static int | setamixer (int devnum, char *param, int v1, int v2) |
| static int | setformat (struct chan_usbradio_pvt *o, int mode) |
| static void * | sound_thread (void *arg) |
| static int | soundcard_writeframe (struct chan_usbradio_pvt *o, short *data) |
| static struct chan_usbradio_pvt * | store_config (struct ast_config *cfg, char *ctg) |
| static void | store_rxcdtype (struct chan_usbradio_pvt *o, const char *s) |
| static void | store_rxctcssadj (struct chan_usbradio_pvt *o, const char *s) |
| static void | store_rxdemod (struct chan_usbradio_pvt *o, const char *s) |
| static void | store_rxgain (struct chan_usbradio_pvt *o, const char *s) |
| static void | store_rxsdtype (struct chan_usbradio_pvt *o, const char *s) |
| static void | store_rxvoiceadj (struct chan_usbradio_pvt *o, const char *s) |
| static void | store_txmixa (struct chan_usbradio_pvt *o, const char *s) |
| static void | store_txmixb (struct chan_usbradio_pvt *o, const char *s) |
| static void | store_txtoctype (struct chan_usbradio_pvt *o, const char *s) |
| static void | tune_rxctcss (int fd, struct chan_usbradio_pvt *o) |
| static void | tune_rxinput (int fd, struct chan_usbradio_pvt *o) |
| static void | tune_rxvoice (int fd, struct chan_usbradio_pvt *o) |
| static void | tune_txoutput (struct chan_usbradio_pvt *o, int value, int fd) |
| static void | tune_write (struct chan_usbradio_pvt *o) |
| static int | unload_module (void) |
| static int | usb_get_usbdev (char *devstr) |
| static int | usb_list_check (char *devstr) |
| static int | usbradio_answer (struct ast_channel *c) |
| static int | usbradio_call (struct ast_channel *c, char *dest, int timeout) |
| static int | usbradio_digit_begin (struct ast_channel *c, char digit) |
| static int | usbradio_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
| static int | usbradio_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| static int | usbradio_hangup (struct ast_channel *c) |
| static int | usbradio_indicate (struct ast_channel *chan, int cond, const void *data, size_t datalen) |
| static struct ast_channel * | usbradio_new (struct chan_usbradio_pvt *o, char *ext, char *ctx, int state) |
| static struct ast_frame * | usbradio_read (struct ast_channel *chan) |
| static struct ast_channel * | usbradio_request (const char *type, int format, void *data, int *cause) |
| static int | usbradio_text (struct ast_channel *c, const char *text) |
| static int | usbradio_write (struct ast_channel *chan, struct ast_frame *f) |
| static int | used_blocks (struct chan_usbradio_pvt *o) |
| static void | write_eeprom (struct usb_dev_handle *handle, int addr, unsigned short data) |
| static int | xpmr_config (struct chan_usbradio_pvt *o) |
Variables | |
| static struct ast_module_info __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "usb Console Channel Driver" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
| static char | active_usage [] = "to the device specified.\n" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_cli_entry | cli_usbradio [] |
| static const char * | config = "usbradio.conf" |
| static struct ast_jb_conf | default_jbconf |
| static FILE * | frxcapraw = NULL |
| static FILE * | frxcaptrace = NULL |
| static FILE * | frxoutraw = NULL |
| static FILE * | ftxcapraw = NULL |
| static FILE * | ftxcaptrace = NULL |
| static FILE * | ftxoutraw = NULL |
| static struct ast_jb_conf | global_jbconf |
| static char | key_usage [] = " Simulates COR active.\n" |
| static char | radio_tune_usage [] = "\n All [newsetting]'s are values 0-999\n\n" |
| static struct sound | sounds [] |
| static char | tdesc [] = "USB (CM108) Radio Channel Driver" |
| static char | unkey_usage [] = " Simulates COR un-active.\n" |
| static char * | usb_device_list = NULL |
| static int | usb_device_list_size = 0 |
| static char * | usbradio_active |
| static int | usbradio_debug |
| static struct chan_usbradio_pvt | usbradio_default |
| static struct ast_channel_tech | usbradio_tech |
Channel driver for CM108 USB Cards with Radio Interface.
Definition in file chan_usbradio.c.
| #define BOOST_MAX 40 |
Definition at line 457 of file chan_usbradio.c.
| #define BOOST_SCALE (1<<9) |
Definition at line 456 of file chan_usbradio.c.
Referenced by usbradio_read().
| #define C108_HID_INTERFACE 3 |
Definition at line 167 of file chan_usbradio.c.
Referenced by hid_get_inputs(), hid_set_outputs(), and hidthread().
| #define C108_PRODUCT_ID 0x000c |
Definition at line 166 of file chan_usbradio.c.
Referenced by hid_device_init(), and hid_device_mklist().
| #define C108_VENDOR_ID 0x0d8c |
Definition at line 165 of file chan_usbradio.c.
Referenced by hid_device_init(), and hid_device_mklist().
| #define CHAN_USBRADIO 1 |
Definition at line 83 of file chan_usbradio.c.
| #define config1 "usbradio_tune_%s.conf" |
Definition at line 357 of file chan_usbradio.c.
Referenced by store_config().
| #define DEBUG_CAP_RX_OUT 0 |
Definition at line 86 of file chan_usbradio.c.
| #define DEBUG_CAP_TX_OUT 0 |
Definition at line 87 of file chan_usbradio.c.
| #define DEBUG_CAPTURES 1 |
Definition at line 85 of file chan_usbradio.c.
| #define DEBUG_FILETEST 0 |
Definition at line 88 of file chan_usbradio.c.
| #define DEBUG_USBRADIO 0 |
Definition at line 84 of file chan_usbradio.c.
| #define DELIMCHR ',' |
Definition at line 106 of file chan_usbradio.c.
| #define DEV_DSP "/dev/dsp" |
Definition at line 353 of file chan_usbradio.c.
| #define EEPROM_CS_ADDR 62 |
Definition at line 181 of file chan_usbradio.c.
Referenced by put_eeprom().
| #define EEPROM_END_ADDR 63 |
Definition at line 176 of file chan_usbradio.c.
Referenced by get_eeprom().
| #define EEPROM_MAGIC 34329 |
Definition at line 180 of file chan_usbradio.c.
Referenced by hidthread(), and put_eeprom().
| #define EEPROM_MAGIC_ADDR 6 |
Definition at line 179 of file chan_usbradio.c.
Referenced by hidthread(), and put_eeprom().
| #define EEPROM_PHYSICAL_LEN 64 |
Definition at line 177 of file chan_usbradio.c.
| #define EEPROM_RXCTCSSADJ 13 |
Definition at line 186 of file chan_usbradio.c.
Referenced by hidthread(), and tune_write().
| #define EEPROM_RXMIXERSET 8 |
Definition at line 182 of file chan_usbradio.c.
Referenced by hidthread(), and tune_write().
| #define EEPROM_RXSQUELCHADJ 16 |
Definition at line 188 of file chan_usbradio.c.
Referenced by hidthread(), and tune_write().
| #define EEPROM_RXVOICEADJ 11 |
Definition at line 185 of file chan_usbradio.c.
Referenced by hidthread(), and tune_write().
| #define EEPROM_START_ADDR 6 |
Definition at line 175 of file chan_usbradio.c.
Referenced by get_eeprom(), and put_eeprom().
| #define EEPROM_TEST_ADDR EEPROM_END_ADDR |
Definition at line 178 of file chan_usbradio.c.
| #define EEPROM_TXCTCSSADJ 15 |
Definition at line 187 of file chan_usbradio.c.
Referenced by hidthread(), and tune_write().
| #define EEPROM_TXMIXASET 9 |
Definition at line 183 of file chan_usbradio.c.
Referenced by hidthread(), and tune_write().
| #define EEPROM_TXMIXBSET 10 |
Definition at line 184 of file chan_usbradio.c.
Referenced by hidthread(), and tune_write().
| #define FRAGS ( ( (6 * 5) << 16 ) | 0xc ) |
Definition at line 336 of file chan_usbradio.c.
| #define FRAME_SIZE 160 |
Definition at line 330 of file chan_usbradio.c.
Referenced by send_sound(), soundcard_writeframe(), store_config(), and usbradio_read().
| #define HID_REPORT_GET 0x01 |
Definition at line 169 of file chan_usbradio.c.
Referenced by hid_get_inputs().
| #define HID_REPORT_SET 0x09 |
Definition at line 170 of file chan_usbradio.c.
Referenced by hid_set_outputs().
| #define HID_RT_INPUT 0x01 |
Definition at line 172 of file chan_usbradio.c.
Referenced by hid_get_inputs().
| #define HID_RT_OUTPUT 0x02 |
Definition at line 173 of file chan_usbradio.c.
Referenced by hid_set_outputs().
| #define M_BOOL | ( | tag, | |
| dst | |||
| ) | M_F(tag, (dst) = ast_true(__val) ) |
Definition at line 296 of file chan_usbradio.c.
Referenced by store_config().
| #define M_END | ( | x | ) | x; |
Definition at line 294 of file chan_usbradio.c.
Referenced by store_config().
Definition at line 295 of file chan_usbradio.c.
Referenced by store_config().
Definition at line 292 of file chan_usbradio.c.
Referenced by store_config().
| #define M_STR | ( | tag, | |
| dst | |||
| ) | M_F(tag, ast_copy_string(dst, __val, sizeof(dst))) |
Definition at line 298 of file chan_usbradio.c.
Referenced by store_config().
| #define M_UINT | ( | tag, | |
| dst | |||
| ) | M_F(tag, (dst) = strtoul(__val, NULL, 0) ) |
Definition at line 297 of file chan_usbradio.c.
Referenced by store_config().
| #define MIXER_PARAM_MIC_BOOST "Auto Gain Control" |
Definition at line 102 of file chan_usbradio.c.
Referenced by mixer_write(), and tune_rxinput().
| #define MIXER_PARAM_MIC_CAPTURE_SW "Mic Capture Switch" |
Definition at line 100 of file chan_usbradio.c.
Referenced by mixer_write().
| #define MIXER_PARAM_MIC_CAPTURE_VOL "Mic Capture Volume" |
Definition at line 101 of file chan_usbradio.c.
Referenced by mixer_write(), store_config(), and tune_rxinput().
| #define MIXER_PARAM_MIC_PLAYBACK_SW "Mic Playback Switch" |
Definition at line 98 of file chan_usbradio.c.
Referenced by mixer_write().
| #define MIXER_PARAM_MIC_PLAYBACK_VOL "Mic Playback Volume" |
Definition at line 99 of file chan_usbradio.c.
Referenced by mixer_write().
| #define MIXER_PARAM_SPKR_PLAYBACK_SW "Speaker Playback Switch" |
Definition at line 103 of file chan_usbradio.c.
Referenced by mixer_write().
| #define MIXER_PARAM_SPKR_PLAYBACK_VOL "Speaker Playback Volume" |
Definition at line 104 of file chan_usbradio.c.
Referenced by mixer_write(), and store_config().
| #define NEW_ASTERISK |
Definition at line 1 of file chan_usbradio.c.
| #define O_CLOSE 0x444 |
Definition at line 348 of file chan_usbradio.c.
Referenced by setformat(), sound_thread(), and usbradio_hangup().
| #define pd | ( | x | ) | {printf(#x" = %d\n",x);} |
Definition at line 3141 of file chan_usbradio.c.
Referenced by pcm_write(), playtones_alloc(), and pmrdump().
| #define pf | ( | x | ) | {printf(#x" = %f\n",x);} |
Definition at line 3144 of file chan_usbradio.c.
Referenced by pmrdump().
| #define pp | ( | x | ) | {printf(#x" = %p\n",x);} |
Definition at line 3142 of file chan_usbradio.c.
Referenced by dahdi_setoption(), get_unaligned_uint16(), get_unaligned_uint32(), put_unaligned_uint16(), put_unaligned_uint32(), sms_readfile(), st_get_mode(), st_get_refresher(), st_get_se(), and utf8decode().
| #define ps | ( | x | ) | {printf(#x" = %s\n",x);} |
Definition at line 3143 of file chan_usbradio.c.
Referenced by playtones_alloc(), playtones_generator(), playtones_release(), and pmrdump().
| #define QUEUE_SIZE 2 |
Definition at line 331 of file chan_usbradio.c.
| #define QUOTECHR 34 |
Definition at line 107 of file chan_usbradio.c.
| #define READERR_THRESHOLD 50 |
Definition at line 109 of file chan_usbradio.c.
Referenced by usbradio_read().
| #define RX_CAP_OUT_FILE "/tmp/rx_cap_out.pcm" |
Definition at line 92 of file chan_usbradio.c.
Referenced by usbradio_read().
| #define RX_CAP_RAW_FILE "/tmp/rx_cap_in.pcm" |
Definition at line 90 of file chan_usbradio.c.
Referenced by radio_tune().
| #define RX_CAP_TRACE_FILE "/tmp/rx_trace.pcm" |
Definition at line 91 of file chan_usbradio.c.
Referenced by radio_tune().
| #define TEXT_SIZE 256 |
Definition at line 343 of file chan_usbradio.c.
| #define traceusb1 | ( | a | ) |
Definition at line 120 of file chan_usbradio.c.
Referenced by hidthread(), and store_config().
| #define traceusb2 | ( | a | ) |
Definition at line 126 of file chan_usbradio.c.
Referenced by usbradio_read(), and usbradio_write().
| #define TX_CAP_OUT_FILE "/tmp/tx_cap_out.pcm" |
Definition at line 96 of file chan_usbradio.c.
Referenced by usbradio_read().
| #define TX_CAP_RAW_FILE "/tmp/tx_cap_in.pcm" |
Definition at line 94 of file chan_usbradio.c.
Referenced by radio_tune().
| #define TX_CAP_TRACE_FILE "/tmp/tx_trace.pcm" |
Definition at line 95 of file chan_usbradio.c.
Referenced by radio_tune().
| #define WARN_frag 4 |
Definition at line 446 of file chan_usbradio.c.
Referenced by setformat().
| #define WARN_speed 2 |
Definition at line 445 of file chan_usbradio.c.
Referenced by setformat().
| #define WARN_used_blocks 1 |
Definition at line 444 of file chan_usbradio.c.
Referenced by used_blocks().
| anonymous enum |
Definition at line 370 of file chan_usbradio.c.
| anonymous enum |
Definition at line 371 of file chan_usbradio.c.
| anonymous enum |
Definition at line 372 of file chan_usbradio.c.
{SD_IGNORE,SD_HID,SD_HID_INVERT,SD_XPMR}; // no,external,externalinvert,software
| anonymous enum |
Definition at line 373 of file chan_usbradio.c.
| anonymous enum |
Definition at line 374 of file chan_usbradio.c.
| anonymous enum |
Definition at line 375 of file chan_usbradio.c.
| static void __reg_module | ( | void | ) | [static] |
Definition at line 4019 of file chan_usbradio.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 4019 of file chan_usbradio.c.
| static int amixer_max | ( | int | devnum, |
| char * | param | ||
| ) | [static] |
Definition at line 707 of file chan_usbradio.c.
Referenced by store_config().
{
int rv,type;
char str[100];
snd_hctl_t *hctl;
snd_ctl_elem_id_t *id;
snd_hctl_elem_t *elem;
snd_ctl_elem_info_t *info;
sprintf(str,"hw:%d",devnum);
if (snd_hctl_open(&hctl, str, 0)) return(-1);
snd_hctl_load(hctl);
snd_ctl_elem_id_alloca(&id);
snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
snd_ctl_elem_id_set_name(id, param);
elem = snd_hctl_find_elem(hctl, id);
if (!elem)
{
snd_hctl_close(hctl);
return(-1);
}
snd_ctl_elem_info_alloca(&info);
snd_hctl_elem_info(elem,info);
type = snd_ctl_elem_info_get_type(info);
rv = 0;
switch(type)
{
case SND_CTL_ELEM_TYPE_INTEGER:
rv = snd_ctl_elem_info_get_max(info);
break;
case SND_CTL_ELEM_TYPE_BOOLEAN:
rv = 1;
break;
}
snd_hctl_close(hctl);
return(rv);
}
| static int console_key | ( | int | fd, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 2249 of file chan_usbradio.c.
References find_desc(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and chan_usbradio_pvt::txtestkey.
{
struct chan_usbradio_pvt *o = find_desc(usbradio_active);
if (argc != 2)
return RESULT_SHOWUSAGE;
o->txtestkey = 1;
return RESULT_SUCCESS;
}
| static int console_unkey | ( | int | fd, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 2260 of file chan_usbradio.c.
References find_desc(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and chan_usbradio_pvt::txtestkey.
{
struct chan_usbradio_pvt *o = find_desc(usbradio_active);
if (argc != 2)
return RESULT_SHOWUSAGE;
o->txtestkey = 0;
return RESULT_SUCCESS;
}
| static struct chan_usbradio_pvt* find_desc | ( | char * | dev | ) | [static, read] |
Definition at line 1250 of file chan_usbradio.c.
References ast_log(), LOG_WARNING, chan_usbradio_pvt::name, and chan_usbradio_pvt::next.
Referenced by console_key(), console_unkey(), load_module(), radio_active(), radio_set_debug(), radio_set_debug_off(), radio_set_xpmr_debug(), radio_tune(), usbradio_request(), and usbradio_text().
{
struct chan_usbradio_pvt *o = NULL;
if (!dev)
ast_log(LOG_WARNING, "null dev\n");
for (o = usbradio_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
if (!o)
{
ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
}
return o;
}
| static struct chan_usbradio_pvt* find_desc_usb | ( | char * | devstr | ) | [static, read] |
Definition at line 1266 of file chan_usbradio.c.
References ast_log(), chan_usbradio_pvt::devstr, LOG_WARNING, and chan_usbradio_pvt::next.
Referenced by store_config().
{
struct chan_usbradio_pvt *o = NULL;
if (!devstr)
ast_log(LOG_WARNING, "null dev\n");
for (o = usbradio_default.next; o && devstr && strcmp(o->devstr, devstr) != 0; o = o->next);
return o;
}
| static unsigned short get_eeprom | ( | struct usb_dev_handle * | handle, |
| unsigned short * | buf | ||
| ) | [static] |
Definition at line 848 of file chan_usbradio.c.
References EEPROM_END_ADDR, EEPROM_START_ADDR, and read_eeprom().
Referenced by hidthread().
{
int i;
unsigned short cs;
cs = 0xffff;
for(i = EEPROM_START_ADDR; i < EEPROM_END_ADDR; i++)
{
cs += buf[i] = read_eeprom(handle,i);
}
return(cs);
}
| static struct usb_device* hid_device_init | ( | char * | desired_device | ) | [static, read] |
Definition at line 878 of file chan_usbradio.c.
References C108_PRODUCT_ID, C108_VENDOR_ID, and str.
Referenced by hidthread().
{
struct usb_bus *usb_bus;
struct usb_device *dev;
char devstr[200],str[200],desdev[200],*cp;
int i;
FILE *fp;
usb_init();
usb_find_busses();
usb_find_devices();
for (usb_bus = usb_busses;
usb_bus;
usb_bus = usb_bus->next) {
for (dev = usb_bus->devices;
dev;
dev = dev->next) {
if ((dev->descriptor.idVendor
== C108_VENDOR_ID) &&
(dev->descriptor.idProduct
== C108_PRODUCT_ID))
{
sprintf(devstr,"%s/%s", usb_bus->dirname,dev->filename);
for(i = 0; i < 32; i++)
{
sprintf(str,"/proc/asound/card%d/usbbus",i);
fp = fopen(str,"r");
if (!fp) continue;
if ((!fgets(desdev,sizeof(desdev) - 1,fp)) || (!desdev[0]))
{
fclose(fp);
continue;
}
fclose(fp);
if (desdev[strlen(desdev) - 1] == '\n')
desdev[strlen(desdev) -1 ] = 0;
if (strcasecmp(desdev,devstr)) continue;
if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
else strcpy(str,"/sys/class/sound/dsp/device");
memset(desdev,0,sizeof(desdev));
if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
{
sprintf(str,"/sys/class/sound/controlC%d/device",i);
memset(desdev,0,sizeof(desdev));
if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
}
cp = strrchr(desdev,'/');
if (cp) *cp = 0; else continue;
cp = strrchr(desdev,'/');
if (!cp) continue;
cp++;
break;
}
if (i >= 32) continue;
if (!strcmp(cp,desired_device)) return dev;
}
}
}
return NULL;
}
| static int hid_device_mklist | ( | void | ) | [static] |
Definition at line 940 of file chan_usbradio.c.
References ast_malloc, ast_realloc, C108_PRODUCT_ID, C108_VENDOR_ID, and str.
Referenced by load_module().
{
struct usb_bus *usb_bus;
struct usb_device *dev;
char devstr[200],str[200],desdev[200],*cp;
int i;
FILE *fp;
usb_device_list = ast_malloc(2);
if (!usb_device_list) return -1;
memset(usb_device_list,0,2);
usb_init();
usb_find_busses();
usb_find_devices();
for (usb_bus = usb_busses;
usb_bus;
usb_bus = usb_bus->next) {
for (dev = usb_bus->devices;
dev;
dev = dev->next) {
if ((dev->descriptor.idVendor
== C108_VENDOR_ID) &&
(dev->descriptor.idProduct
== C108_PRODUCT_ID))
{
sprintf(devstr,"%s/%s", usb_bus->dirname,dev->filename);
for(i = 0;i < 32; i++)
{
sprintf(str,"/proc/asound/card%d/usbbus",i);
fp = fopen(str,"r");
if (!fp) continue;
if ((!fgets(desdev,sizeof(desdev) - 1,fp)) || (!desdev[0]))
{
fclose(fp);
continue;
}
fclose(fp);
if (desdev[strlen(desdev) - 1] == '\n')
desdev[strlen(desdev) -1 ] = 0;
if (strcasecmp(desdev,devstr)) continue;
if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
else strcpy(str,"/sys/class/sound/dsp/device");
memset(desdev,0,sizeof(desdev));
if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
{
sprintf(str,"/sys/class/sound/controlC%d/device",i);
memset(desdev,0,sizeof(desdev));
if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
}
cp = strrchr(desdev,'/');
if (cp) *cp = 0; else continue;
cp = strrchr(desdev,'/');
if (!cp) continue;
cp++;
break;
}
if (i >= 32) return -1;
usb_device_list = ast_realloc(usb_device_list,
usb_device_list_size + 2 +
strlen(cp));
if (!usb_device_list) return -1;
usb_device_list_size += strlen(cp) + 2;
i = 0;
while(usb_device_list[i])
{
i += strlen(usb_device_list + i) + 1;
}
strcat(usb_device_list + i,cp);
usb_device_list[strlen(cp) + i + 1] = 0;
}
}
}
return 0;
}
| static void hid_get_inputs | ( | struct usb_dev_handle * | handle, |
| unsigned char * | inputs | ||
| ) | [static] |
Definition at line 809 of file chan_usbradio.c.
References C108_HID_INTERFACE, HID_REPORT_GET, and HID_RT_INPUT.
Referenced by hidthread(), and read_eeprom().
{
usleep(1500);
usb_control_msg(handle,
USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
HID_REPORT_GET,
0 + (HID_RT_INPUT << 8),
C108_HID_INTERFACE,
(char*)inputs, 4, 5000);
}
| static void hid_set_outputs | ( | struct usb_dev_handle * | handle, |
| unsigned char * | outputs | ||
| ) | [static] |
Definition at line 797 of file chan_usbradio.c.
References C108_HID_INTERFACE, HID_REPORT_SET, and HID_RT_OUTPUT.
Referenced by hidthread(), read_eeprom(), and write_eeprom().
{
usleep(1500);
usb_control_msg(handle,
USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
HID_REPORT_SET,
0 + (HID_RT_OUTPUT << 8),
C108_HID_INTERFACE,
(char*)outputs, 4, 5000);
}
| static int hidhdwconfig | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 1061 of file chan_usbradio.c.
References chan_usbradio_pvt::hdwtype, chan_usbradio_pvt::hid_gpio_ctl, chan_usbradio_pvt::hid_gpio_ctl_loc, chan_usbradio_pvt::hid_gpio_loc, chan_usbradio_pvt::hid_io_cor, chan_usbradio_pvt::hid_io_cor_loc, chan_usbradio_pvt::hid_io_ctcss, chan_usbradio_pvt::hid_io_ctcss_loc, and chan_usbradio_pvt::hid_io_ptt.
Referenced by store_config().
{
if(o->hdwtype==1) //sphusb
{
o->hid_gpio_ctl = 0x08; /* set GPIO4 to output mode */
o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
o->hid_io_cor = 4; /* GPIO3 is COR */
o->hid_io_cor_loc = 1; /* GPIO3 is COR */
o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
o->hid_io_ptt = 8; /* GPIO 4 is PTT */
o->hid_gpio_loc = 1; /* For ALL GPIO */
}
else if(o->hdwtype==0) //dudeusb
{
o->hid_gpio_ctl = 0x0c; /* set GPIO 3 & 4 to output mode */
o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
o->hid_io_cor = 2; /* VOLD DN is COR */
o->hid_io_cor_loc = 0; /* VOL DN COR */
o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
o->hid_io_ptt = 4; /* GPIO 3 is PTT */
o->hid_gpio_loc = 1; /* For ALL GPIO */
}
else if(o->hdwtype==3) // custom version
{
o->hid_gpio_ctl = 0x0c; /* set GPIO 3 & 4 to output mode */
o->hid_gpio_ctl_loc = 2; /* For CTL of GPIO */
o->hid_io_cor = 2; /* VOLD DN is COR */
o->hid_io_cor_loc = 0; /* VOL DN COR */
o->hid_io_ctcss = 2; /* GPIO 2 is External CTCSS */
o->hid_io_ctcss_loc = 1; /* is GPIO 2 */
o->hid_io_ptt = 4; /* GPIO 3 is PTT */
o->hid_gpio_loc = 1; /* For ALL GPIO */
}
return 0;
}
| static void* hidthread | ( | void * | arg | ) | [static] |
Definition at line 1113 of file chan_usbradio.c.
References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_poll, buf, C108_HID_INTERFACE, chan_usbradio_pvt::debuglevel, chan_usbradio_pvt::devstr, chan_usbradio_pvt::eeprom, EEPROM_MAGIC, EEPROM_MAGIC_ADDR, EEPROM_RXCTCSSADJ, EEPROM_RXMIXERSET, EEPROM_RXSQUELCHADJ, EEPROM_RXVOICEADJ, EEPROM_TXCTCSSADJ, EEPROM_TXMIXASET, EEPROM_TXMIXBSET, chan_usbradio_pvt::eepromctl, chan_usbradio_pvt::eepromlock, errno, get_eeprom(), hid_device_init(), hid_get_inputs(), chan_usbradio_pvt::hid_gpio_ctl, chan_usbradio_pvt::hid_gpio_ctl_loc, chan_usbradio_pvt::hid_gpio_loc, chan_usbradio_pvt::hid_io_cor, chan_usbradio_pvt::hid_io_cor_loc, chan_usbradio_pvt::hid_io_ptt, hid_set_outputs(), chan_usbradio_pvt::invertptt, chan_usbradio_pvt::lasthidtime, chan_usbradio_pvt::lasttx, LOG_ERROR, LOG_NOTICE, LOG_WARNING, chan_usbradio_pvt::name, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::pttkick, put_eeprom(), chan_usbradio_pvt::rxctcssadj, chan_usbradio_pvt::rxhidsq, chan_usbradio_pvt::rxmixerset, chan_usbradio_pvt::rxsquelchadj, chan_usbradio_pvt::rxvoiceadj, chan_usbradio_pvt::stophid, traceusb1, chan_usbradio_pvt::txctcssadj, chan_usbradio_pvt::txmixaset, chan_usbradio_pvt::txmixbset, and chan_usbradio_pvt::wanteeprom.
Referenced by usbradio_call().
{
unsigned char buf[4],bufsave[4],keyed;
char lastrx, txtmp;
int res;
struct usb_device *usb_dev;
struct usb_dev_handle *usb_handle;
struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
struct pollfd pfd = { .events = POLLIN };
usb_dev = hid_device_init(o->devstr);
if (usb_dev == NULL) {
ast_log(LOG_ERROR,"USB HID device not found\n");
pthread_exit(NULL);
}
usb_handle = usb_open(usb_dev);
if (usb_handle == NULL) {
ast_log(LOG_ERROR,"Not able to open USB device\n");
pthread_exit(NULL);
}
if (usb_claim_interface(usb_handle,C108_HID_INTERFACE) < 0)
{
if (usb_detach_kernel_driver_np(usb_handle,C108_HID_INTERFACE) < 0) {
ast_log(LOG_ERROR,"Not able to detach the USB device\n");
pthread_exit(NULL);
}
if (usb_claim_interface(usb_handle,C108_HID_INTERFACE) < 0) {
ast_log(LOG_ERROR,"Not able to claim the USB device\n");
pthread_exit(NULL);
}
}
memset(buf,0,sizeof(buf));
buf[2] = o->hid_gpio_ctl;
buf[1] = 0;
hid_set_outputs(usb_handle,buf);
memcpy(bufsave,buf,sizeof(buf));
if (pipe(o->pttkick) == -1)
{
ast_log(LOG_ERROR,"Not able to create pipe\n");
pthread_exit(NULL);
}
traceusb1(("hidthread: Starting normally on %s!!\n",o->name));
lastrx = 0;
// popen
while (!o->stophid) {
pfd.fd = o->pttkick[0];
pfd.revents = 0;
res = ast_poll(&pfd, 1, 50);
if (res < 0) {
ast_log(LOG_WARNING, "poll() failed: %s\n", strerror(errno));
usleep(10000);
continue;
}
if (pfd.revents & POLLIN) {
char c;
if (read(o->pttkick[0], &c, 1) < 0) {
ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
}
}
if (o->wanteeprom) {
ast_mutex_lock(&o->eepromlock);
if (o->eepromctl == 1) { /* to read */
/* if CS okay */
if (!get_eeprom(usb_handle, o->eeprom)) {
if (o->eeprom[EEPROM_MAGIC_ADDR] != EEPROM_MAGIC) {
ast_log(LOG_NOTICE, "UNSUCCESSFUL: EEPROM MAGIC NUMBER BAD on channel %s\n", o->name);
} else {
o->rxmixerset = o->eeprom[EEPROM_RXMIXERSET];
o->txmixaset = o->eeprom[EEPROM_TXMIXASET];
o->txmixbset = o->eeprom[EEPROM_TXMIXBSET];
memcpy(&o->rxvoiceadj, &o->eeprom[EEPROM_RXVOICEADJ], sizeof(float));
memcpy(&o->rxctcssadj, &o->eeprom[EEPROM_RXCTCSSADJ], sizeof(float));
o->txctcssadj = o->eeprom[EEPROM_TXCTCSSADJ];
o->rxsquelchadj = o->eeprom[EEPROM_RXSQUELCHADJ];
ast_log(LOG_NOTICE,"EEPROM Loaded on channel %s\n",o->name);
}
} else {
ast_log(LOG_NOTICE, "USB Adapter has no EEPROM installed or Checksum BAD on channel %s\n", o->name);
}
hid_set_outputs(usb_handle,bufsave);
}
if (o->eepromctl == 2) { /* to write */
put_eeprom(usb_handle,o->eeprom);
hid_set_outputs(usb_handle,bufsave);
ast_log(LOG_NOTICE, "USB Parameters written to EEPROM on %s\n", o->name);
}
o->eepromctl = 0;
ast_mutex_unlock(&o->eepromlock);
}
buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
hid_get_inputs(usb_handle,buf);
keyed = !(buf[o->hid_io_cor_loc] & o->hid_io_cor);
if (keyed != o->rxhidsq) {
if (o->debuglevel) {
printf("chan_usbradio() hidthread: update rxhidsq = %d\n", keyed);
}
o->rxhidsq=keyed;
}
/* if change in tx state as controlled by xpmr */
txtmp = o->pmrChan->txPttOut;
if (o->lasttx != txtmp) {
o->pmrChan->txPttHid = o->lasttx = txtmp;
if (o->debuglevel) {
ast_debug(0, "hidthread: tx set to %d\n", txtmp);
}
buf[o->hid_gpio_loc] = 0;
if (!o->invertptt) {
if (txtmp) {
buf[o->hid_gpio_loc] = o->hid_io_ptt;
}
} else {
if (!txtmp) {
buf[o->hid_gpio_loc] = o->hid_io_ptt;
}
}
buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
memcpy(bufsave, buf, sizeof(buf));
hid_set_outputs(usb_handle, buf);
}
time(&o->lasthidtime);
}
buf[o->hid_gpio_loc] = 0;
if (o->invertptt) {
buf[o->hid_gpio_loc] = o->hid_io_ptt;
}
buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
hid_set_outputs(usb_handle, buf);
pthread_exit(0);
}
| static void kickptt | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 1101 of file chan_usbradio.c.
References ast_log(), errno, LOG_ERROR, and chan_usbradio_pvt::pttkick.
Referenced by usbradio_read().
| static int load_module | ( | void | ) | [static] |
Definition at line 3924 of file chan_usbradio.c.
References ARRAY_LEN, ast_category_browse(), ast_channel_register(), ast_cli_register_multiple(), ast_config_destroy(), ast_config_load, ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, CONFIG_STATUS_FILEINVALID, find_desc(), global_jbconf, hid_device_mklist(), LOG_ERROR, LOG_NOTICE, store_config(), and usb_list_check().
{
struct ast_config *cfg = NULL;
char *ctg = NULL;
#ifdef NEW_ASTERISK
struct ast_flags zeroflag = {0};
#endif
if (hid_device_mklist()) {
ast_log(LOG_NOTICE, "Unable to make hid list\n");
return AST_MODULE_LOAD_DECLINE;
}
usb_list_check("");
usbradio_active = NULL;
/* Copy the default jb config over global_jbconf */
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
/* load config file */
#ifdef NEW_ASTERISK
if (!(cfg = ast_config_load(config,zeroflag)) || cfg == CONFIG_STATUS_FILEINVALID) {
#else
if (!(cfg = ast_config_load(config))) || cfg == CONFIG_STATUS_FILEINVALID {
#endif
ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
return AST_MODULE_LOAD_DECLINE;
}
do {
store_config(cfg, ctg);
} while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
ast_config_destroy(cfg);
if (find_desc(usbradio_active) == NULL) {
ast_log(LOG_NOTICE, "radio active device %s not found\n", usbradio_active);
/* XXX we could default to 'dsp' perhaps ? */
/* XXX should cleanup allocated memory etc. */
return AST_MODULE_LOAD_DECLINE;
}
if (ast_channel_register(&usbradio_tech)) {
ast_log(LOG_ERROR, "Unable to register channel type 'usb'\n");
return AST_MODULE_LOAD_DECLINE;
}
ast_cli_register_multiple(cli_usbradio, ARRAY_LEN(cli_usbradio));
return AST_MODULE_LOAD_SUCCESS;
}
| static void mixer_write | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 3100 of file chan_usbradio.c.
References chan_usbradio_pvt::devicenum, chan_usbradio_pvt::micmax, MIXER_PARAM_MIC_BOOST, MIXER_PARAM_MIC_CAPTURE_SW, MIXER_PARAM_MIC_CAPTURE_VOL, MIXER_PARAM_MIC_PLAYBACK_SW, MIXER_PARAM_MIC_PLAYBACK_VOL, MIXER_PARAM_SPKR_PLAYBACK_SW, MIXER_PARAM_SPKR_PLAYBACK_VOL, chan_usbradio_pvt::rxboostset, chan_usbradio_pvt::rxmixerset, setamixer(), chan_usbradio_pvt::spkrmax, chan_usbradio_pvt::txmixaset, and chan_usbradio_pvt::txmixbset.
Referenced by radio_tune(), set_txctcss_level(), and store_config().
{
setamixer(o->devicenum,MIXER_PARAM_MIC_PLAYBACK_SW,0,0);
setamixer(o->devicenum,MIXER_PARAM_MIC_PLAYBACK_VOL,0,0);
setamixer(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_SW,1,0);
setamixer(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_VOL,
o->txmixaset * o->spkrmax / 1000,
o->txmixbset * o->spkrmax / 1000);
setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL,
o->rxmixerset * o->micmax / 1000,0);
setamixer(o->devicenum,MIXER_PARAM_MIC_BOOST,o->rxboostset,0);
setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_SW,1,0);
}
| static int mult_calc | ( | int | value | ) | [static] |
Definition at line 3131 of file chan_usbradio.c.
Referenced by mult_set().
{
const int multx=M_Q8;
int pot,mult;
pot=((int)(value/4)*4)+2;
mult = multx-( ( multx * (3-(value%4)) ) / (pot+2) );
return(mult);
}
| static void mult_set | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 3116 of file chan_usbradio.c.
References mult_calc(), chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::txmixaset, and chan_usbradio_pvt::txmixbset.
Referenced by radio_tune(), set_txctcss_level(), and store_config().
| static void pmrdump | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 3220 of file chan_usbradio.c.
References chan_usbradio_pvt::b, chan_usbradio_pvt::devicenum, chan_usbradio_pvt::devstr, chan_usbradio_pvt::micmax, chan_usbradio_pvt::numrxctcssfreqs, pd, pf, chan_usbradio_pvt::pmrChan, ps, chan_usbradio_pvt::rxboostset, chan_usbradio_pvt::rxcdtype, chan_usbradio_pvt::rxctcss, chan_usbradio_pvt::rxctcssadj, chan_usbradio_pvt::rxdemod, chan_usbradio_pvt::rxmixerset, chan_usbradio_pvt::rxpolarity, chan_usbradio_pvt::rxsdtype, chan_usbradio_pvt::rxsquelchadj, chan_usbradio_pvt::rxvoiceadj, chan_usbradio_pvt::spkrmax, chan_usbradio_pvt::txctcss, chan_usbradio_pvt::txctcssdefault, chan_usbradio_pvt::txctcssfreq, chan_usbradio_pvt::txmixa, chan_usbradio_pvt::txmixaset, chan_usbradio_pvt::txmixb, chan_usbradio_pvt::txmixbset, chan_usbradio_pvt::txpolarity, chan_usbradio_pvt::txprelim, and chan_usbradio_pvt::txtoctype.
Referenced by radio_tune().
{
t_pmr_chan *p;
int i;
p=o->pmrChan;
printf("\nodump()\n");
pd(o->devicenum);
ps(o->devstr);
pd(o->micmax);
pd(o->spkrmax);
pd(o->rxdemod);
pd(o->rxcdtype);
pd(o->rxsdtype);
pd(o->txtoctype);
pd(o->rxmixerset);
pd(o->rxboostset);
pf(o->rxvoiceadj);
pf(o->rxctcssadj);
pd(o->rxsquelchadj);
ps(o->txctcssdefault);
ps(o->txctcssfreq);
pd(o->numrxctcssfreqs);
if(o->numrxctcssfreqs>0)
{
for(i=0;i<o->numrxctcssfreqs;i++)
{
printf(" %i = %s %s\n",i,o->rxctcss[i],o->txctcss[i]);
}
}
pd(o->b.rxpolarity);
pd(o->b.txpolarity);
pd(o->txprelim);
pd(o->txmixa);
pd(o->txmixb);
pd(o->txmixaset);
pd(o->txmixbset);
printf("\npmrdump()\n");
pd(p->devicenum);
printf("prxSquelchAdjust=%i\n",*(o->pmrChan->prxSquelchAdjust));
pd(p->rxCarrierPoint);
pd(p->rxCarrierHyst);
pd(*p->prxVoiceAdjust);
pd(*p->prxCtcssAdjust);
pd(p->rxfreq);
pd(p->txfreq);
pd(p->rxCtcss->relax);
//pf(p->rxCtcssFreq);
pd(p->numrxcodes);
if(o->pmrChan->numrxcodes>0)
{
for(i=0;i<o->pmrChan->numrxcodes;i++)
{
printf(" %i = %s\n",i,o->pmrChan->pRxCode[i]);
}
}
pd(p->txTocType);
ps(p->pTxCodeDefault);
pd(p->txcodedefaultsmode);
pd(p->numtxcodes);
if(o->pmrChan->numtxcodes>0)
{
for(i=0;i<o->pmrChan->numtxcodes;i++)
{
printf(" %i = %s\n",i,o->pmrChan->pTxCode[i]);
}
}
pd(p->b.rxpolarity);
pd(p->b.txpolarity);
pd(p->b.dcsrxpolarity);
pd(p->b.dcstxpolarity);
pd(p->b.lsdrxpolarity);
pd(p->b.lsdtxpolarity);
pd(p->txMixA);
pd(p->txMixB);
pd(p->rxDeEmpEnable);
pd(p->rxCenterSlicerEnable);
pd(p->rxCtcssDecodeEnable);
pd(p->rxDcsDecodeEnable);
pd(p->b.ctcssRxEnable);
pd(p->b.dcsRxEnable);
pd(p->b.lmrRxEnable);
pd(p->b.dstRxEnable);
pd(p->smode);
pd(p->txHpfEnable);
pd(p->txLimiterEnable);
pd(p->txPreEmpEnable);
pd(p->txLpfEnable);
if(p->spsTxOutA)pd(p->spsTxOutA->outputGain);
if(p->spsTxOutB)pd(p->spsTxOutB->outputGain);
pd(p->txPttIn);
pd(p->txPttOut);
pd(p->tracetype);
return;
}
| static void put_eeprom | ( | struct usb_dev_handle * | handle, |
| unsigned short * | buf | ||
| ) | [static] |
Definition at line 862 of file chan_usbradio.c.
References EEPROM_CS_ADDR, EEPROM_MAGIC, EEPROM_MAGIC_ADDR, EEPROM_START_ADDR, and write_eeprom().
Referenced by hidthread().
{
int i;
unsigned short cs;
cs = 0xffff;
buf[EEPROM_MAGIC_ADDR] = EEPROM_MAGIC;
for(i = EEPROM_START_ADDR; i < EEPROM_CS_ADDR; i++)
{
write_eeprom(handle,i,buf[i]);
cs += buf[i];
}
buf[EEPROM_CS_ADDR] = (65535 - cs) + 1;
write_eeprom(handle,i,buf[EEPROM_CS_ADDR]);
}
| static int radio_active | ( | int | fd, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 2560 of file chan_usbradio.c.
References ast_cli(), find_desc(), chan_usbradio_pvt::name, chan_usbradio_pvt::next, chan_usbradio_pvt::pmrChan, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
{
if (argc == 2)
ast_cli(fd, "active (command) USB Radio device is [%s]\n", usbradio_active);
else if (argc != 3)
return RESULT_SHOWUSAGE;
else {
struct chan_usbradio_pvt *o;
if (strcmp(argv[2], "show") == 0) {
for (o = usbradio_default.next; o; o = o->next)
ast_cli(fd, "device [%s] exists\n", o->name);
return RESULT_SUCCESS;
}
o = find_desc(argv[2]);
if (o == NULL)
ast_cli(fd, "No device [%s] exists\n", argv[2]);
else
{
struct chan_usbradio_pvt *ao;
for (ao = usbradio_default.next; ao && ao->name ; ao = ao->next)ao->pmrChan->b.radioactive=0;
usbradio_active = o->name;
o->pmrChan->b.radioactive=1;
}
}
return RESULT_SUCCESS;
}
| static int radio_set_debug | ( | int | fd, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 2542 of file chan_usbradio.c.
References ast_cli(), chan_usbradio_pvt::debuglevel, find_desc(), and RESULT_SUCCESS.
{
struct chan_usbradio_pvt *o = find_desc(usbradio_active);
o->debuglevel=1;
ast_cli(fd,"usbradio debug on.\n");
return RESULT_SUCCESS;
}
| static int radio_set_debug_off | ( | int | fd, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 2551 of file chan_usbradio.c.
References ast_cli(), chan_usbradio_pvt::debuglevel, find_desc(), and RESULT_SUCCESS.
{
struct chan_usbradio_pvt *o = find_desc(usbradio_active);
o->debuglevel=0;
ast_cli(fd,"usbradio debug off.\n");
return RESULT_SUCCESS;
}
| static int radio_set_xpmr_debug | ( | int | fd, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 2589 of file chan_usbradio.c.
References ast_cli(), find_desc(), chan_usbradio_pvt::pmrChan, and RESULT_SUCCESS.
{
struct chan_usbradio_pvt *o = find_desc(usbradio_active);
if (argc == 4)
{
int i;
i = atoi(argv[3]);
if ((i >= 0) && (i <= 100))
{
o->pmrChan->tracelevel=i;
}
}
// add ability to set it for a number of frames after which it reverts
ast_cli(fd,"usbradio xdebug on tracelevel %i\n",o->pmrChan->tracelevel);
return RESULT_SUCCESS;
}
| static int radio_tune | ( | int | fd, |
| int | argc, | ||
| char * | argv[] | ||
| ) | [static] |
Definition at line 2270 of file chan_usbradio.c.
References ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), chan_usbradio_pvt::b, chan_usbradio_pvt::devstr, chan_usbradio_pvt::eepromctl, chan_usbradio_pvt::eepromlock, find_desc(), LOG_ERROR, LOG_WARNING, mixer_write(), mult_set(), chan_usbradio_pvt::name, chan_usbradio_pvt::pmrChan, pmrdump(), RESULT_SHOWUSAGE, RESULT_SUCCESS, RX_CAP_RAW_FILE, RX_CAP_TRACE_FILE, chan_usbradio_pvt::rxcap2, chan_usbradio_pvt::rxcapraw, chan_usbradio_pvt::rxsquelchadj, set_txctcss_level(), tune_rxctcss(), tune_rxinput(), tune_rxvoice(), tune_txoutput(), tune_write(), TX_CAP_RAW_FILE, TX_CAP_TRACE_FILE, TX_OUT_AUX, TX_OUT_COMPOSITE, TX_OUT_LSD, TX_OUT_VOICE, chan_usbradio_pvt::txcap2, chan_usbradio_pvt::txcapraw, chan_usbradio_pvt::txctcssadj, chan_usbradio_pvt::txmixa, chan_usbradio_pvt::txmixaset, chan_usbradio_pvt::txmixb, chan_usbradio_pvt::txmixbset, and chan_usbradio_pvt::txtestkey.
{
struct chan_usbradio_pvt *o = find_desc(usbradio_active);
int i=0;
if ((argc < 2) || (argc > 4))
return RESULT_SHOWUSAGE;
if (argc == 2) /* just show stuff */
{
ast_cli(fd,"Active radio interface is [%s]\n",usbradio_active);
ast_cli(fd,"Output A is currently set to ");
if(o->txmixa==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
else if (o->txmixa==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
else if (o->txmixa==TX_OUT_LSD)ast_cli(fd,"tone.\n");
else if (o->txmixa==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
else ast_cli(fd,"off.\n");
ast_cli(fd,"Output B is currently set to ");
if(o->txmixb==TX_OUT_COMPOSITE)ast_cli(fd,"composite.\n");
else if (o->txmixb==TX_OUT_VOICE)ast_cli(fd,"voice.\n");
else if (o->txmixb==TX_OUT_LSD)ast_cli(fd,"tone.\n");
else if (o->txmixb==TX_OUT_AUX)ast_cli(fd,"auxvoice.\n");
else ast_cli(fd,"off.\n");
ast_cli(fd,"Tx Voice Level currently set to %d\n",o->txmixaset);
ast_cli(fd,"Tx Tone Level currently set to %d\n",o->txctcssadj);
ast_cli(fd,"Rx Squelch currently set to %d\n",o->rxsquelchadj);
ast_cli(fd,"Device String is %s\n",o->devstr);
return RESULT_SHOWUSAGE;
}
o->pmrChan->b.tuning=1;
if (!strcasecmp(argv[2],"rxnoise")) tune_rxinput(fd,o);
else if (!strcasecmp(argv[2],"rxvoice")) tune_rxvoice(fd,o);
else if (!strcasecmp(argv[2],"rxtone")) tune_rxctcss(fd,o);
else if (!strcasecmp(argv[2],"rxsquelch"))
{
if (argc == 3)
{
ast_cli(fd,"Current Signal Strength is %d\n",((32767-o->pmrChan->rxRssi)*1000/32767));
ast_cli(fd,"Current Squelch setting is %d\n",o->rxsquelchadj);
//ast_cli(fd,"Current Raw RSSI is %d\n",o->pmrChan->rxRssi);
//ast_cli(fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
} else {
i = atoi(argv[3]);
if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
ast_cli(fd,"Changed Squelch setting to %d\n",i);
o->rxsquelchadj = i;
*(o->pmrChan->prxSquelchAdjust)= ((999 - i) * 32767) / 1000;
}
}
else if (!strcasecmp(argv[2],"txvoice")) {
i = 0;
if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
(o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
)
{
ast_log(LOG_ERROR,"No txvoice output configured.\n");
}
else if (argc == 3)
{
if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
else
ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
}
else
{
i = atoi(argv[3]);
if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
{
o->txmixaset=i;
ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
}
else
{
o->txmixbset=i;
ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
}
mixer_write(o);
mult_set(o);
ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
}
o->pmrChan->b.txCtcssInhibit=1;
tune_txoutput(o,i,fd);
o->pmrChan->b.txCtcssInhibit=0;
}
else if (!strcasecmp(argv[2],"txall")) {
i = 0;
if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
(o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
)
{
ast_log(LOG_ERROR,"No txvoice output configured.\n");
}
else if (argc == 3)
{
if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
ast_cli(fd,"Current txvoice setting on Channel A is %d\n",o->txmixaset);
else
ast_cli(fd,"Current txvoice setting on Channel B is %d\n",o->txmixbset);
}
else
{
i = atoi(argv[3]);
if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
if((o->txmixa==TX_OUT_VOICE)||(o->txmixa==TX_OUT_COMPOSITE))
{
o->txmixaset=i;
ast_cli(fd,"Changed txvoice setting on Channel A to %d\n",o->txmixaset);
}
else
{
o->txmixbset=i;
ast_cli(fd,"Changed txvoice setting on Channel B to %d\n",o->txmixbset);
}
mixer_write(o);
mult_set(o);
ast_cli(fd,"Changed Tx Voice Output setting to %d\n",i);
}
tune_txoutput(o,i,fd);
}
else if (!strcasecmp(argv[2],"auxvoice")) {
i = 0;
if( (o->txmixa!=TX_OUT_AUX) && (o->txmixb!=TX_OUT_AUX))
{
ast_log(LOG_WARNING,"No auxvoice output configured.\n");
}
else if (argc == 3)
{
if(o->txmixa==TX_OUT_AUX)
ast_cli(fd,"Current auxvoice setting on Channel A is %d\n",o->txmixaset);
else
ast_cli(fd,"Current auxvoice setting on Channel B is %d\n",o->txmixbset);
}
else
{
i = atoi(argv[3]);
if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
if(o->txmixa==TX_OUT_AUX)
{
o->txmixbset=i;
ast_cli(fd,"Changed auxvoice setting on Channel A to %d\n",o->txmixaset);
}
else
{
o->txmixbset=i;
ast_cli(fd,"Changed auxvoice setting on Channel B to %d\n",o->txmixbset);
}
mixer_write(o);
mult_set(o);
}
//tune_auxoutput(o,i);
}
else if (!strcasecmp(argv[2],"txtone"))
{
if (argc == 3)
ast_cli(fd,"Current Tx CTCSS modulation setting = %d\n",o->txctcssadj);
else
{
i = atoi(argv[3]);
if ((i < 0) || (i > 999)) return RESULT_SHOWUSAGE;
o->txctcssadj = i;
set_txctcss_level(o);
ast_cli(fd,"Changed Tx CTCSS modulation setting to %i\n",i);
}
o->txtestkey=1;
usleep(5000000);
o->txtestkey=0;
}
else if (!strcasecmp(argv[2],"dump")) pmrdump(o);
else if (!strcasecmp(argv[2],"nocap"))
{
ast_cli(fd,"File capture (trace) was rx=%d tx=%d and now off.\n",o->b.rxcap2,o->b.txcap2);
ast_cli(fd,"File capture (raw) was rx=%d tx=%d and now off.\n",o->b.rxcapraw,o->b.txcapraw);
o->b.rxcapraw=o->b.txcapraw=o->b.rxcap2=o->b.txcap2=o->pmrChan->b.rxCapture=o->pmrChan->b.txCapture=0;
if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
}
else if (!strcasecmp(argv[2],"rxtracecap"))
{
if (!frxcaptrace) frxcaptrace= fopen(RX_CAP_TRACE_FILE,"w");
ast_cli(fd,"Trace rx on.\n");
o->b.rxcap2=o->pmrChan->b.rxCapture=1;
}
else if (!strcasecmp(argv[2],"txtracecap"))
{
if (!ftxcaptrace) ftxcaptrace= fopen(TX_CAP_TRACE_FILE,"w");
ast_cli(fd,"Trace tx on.\n");
o->b.txcap2=o->pmrChan->b.txCapture=1;
}
else if (!strcasecmp(argv[2],"rxcap"))
{
if (!frxcapraw) frxcapraw = fopen(RX_CAP_RAW_FILE,"w");
ast_cli(fd,"cap rx raw on.\n");
o->b.rxcapraw=1;
}
else if (!strcasecmp(argv[2],"txcap"))
{
if (!ftxcapraw) ftxcapraw = fopen(TX_CAP_RAW_FILE,"w");
ast_cli(fd,"cap tx raw on.\n");
o->b.txcapraw=1;
}
else if (!strcasecmp(argv[2],"save"))
{
tune_write(o);
ast_cli(fd,"Saved radio tuning settings to usbradio_tune_%s.conf\n",o->name);
}
else if (!strcasecmp(argv[2],"load"))
{
ast_mutex_lock(&o->eepromlock);
while(o->eepromctl)
{
ast_mutex_unlock(&o->eepromlock);
usleep(10000);
ast_mutex_lock(&o->eepromlock);
}
o->eepromctl = 1; /* request a load */
ast_mutex_unlock(&o->eepromlock);
ast_cli(fd,"Requesting loading of tuning settings from EEPROM for channel %s\n",o->name);
}
else
{
o->pmrChan->b.tuning=0;
return RESULT_SHOWUSAGE;
}
o->pmrChan->b.tuning=0;
return RESULT_SUCCESS;
}
| static unsigned short read_eeprom | ( | struct usb_dev_handle * | handle, |
| int | addr | ||
| ) | [static] |
Definition at line 821 of file chan_usbradio.c.
References buf, hid_get_inputs(), and hid_set_outputs().
Referenced by get_eeprom().
{
unsigned char buf[4];
buf[0] = 0x80;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0x80 | (addr & 0x3f);
hid_set_outputs(handle,buf);
memset(buf,0,sizeof(buf));
hid_get_inputs(handle,buf);
return(buf[1] + (buf[2] << 8));
}
| static void ring | ( | struct chan_usbradio_pvt * | o, |
| int | x | ||
| ) | [static] |
Definition at line 1671 of file chan_usbradio.c.
References chan_usbradio_pvt::sndcmd.
Referenced by store_tone_zone_ring_cadence(), usbradio_hangup(), and usbradio_indicate().
{
#ifndef NEW_ASTERISK
write(o->sndcmd[1], &x, sizeof(x));
#endif
}
| static void send_sound | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 1384 of file chan_usbradio.c.
References ast_log(), chan_usbradio_pvt::cursound, sound::data, sound::datalen, FRAME_SIZE, LOG_WARNING, chan_usbradio_pvt::nosound, sound::repeat, s, sound::samplen, chan_usbradio_pvt::sampsent, sound::silencelen, and soundcard_writeframe().
Referenced by sound_thread().
{
short myframe[FRAME_SIZE];
int ofs, l, start;
int l_sampsent = o->sampsent;
struct sound *s;
if (o->cursound < 0) /* no sound to send */
return;
s = &sounds[o->cursound];
for (ofs = 0; ofs < FRAME_SIZE; ofs += l) {
l = s->samplen - l_sampsent; /* # of available samples */
if (l > 0) {
start = l_sampsent % s->datalen; /* source offset */
if (l > FRAME_SIZE - ofs) /* don't overflow the frame */
l = FRAME_SIZE - ofs;
if (l > s->datalen - start) /* don't overflow the source */
l = s->datalen - start;
memmove(myframe + ofs, s->data + start, l * 2);
if (0)
ast_log(LOG_WARNING, "send_sound sound %d/%d of %d into %d\n", l_sampsent, l, s->samplen, ofs);
l_sampsent += l;
} else { /* end of samples, maybe some silence */
static const short silence[FRAME_SIZE] = { 0, };
l += s->silencelen;
if (l > 0) {
if (l > FRAME_SIZE - ofs)
l = FRAME_SIZE - ofs;
memmove(myframe + ofs, silence, l * 2);
l_sampsent += l;
} else { /* silence is over, restart sound if loop */
if (s->repeat == 0) { /* last block */
o->cursound = -1;
o->nosound = 0; /* allow audio data */
if (ofs < FRAME_SIZE) /* pad with silence */
memmove(myframe + ofs, silence, (FRAME_SIZE - ofs) * 2);
}
l_sampsent = 0;
}
}
}
l = soundcard_writeframe(o, myframe);
if (l > 0)
o->sampsent = l_sampsent; /* update status */
}
| static int set_txctcss_level | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 2517 of file chan_usbradio.c.
References mixer_write(), mult_set(), chan_usbradio_pvt::pmrChan, TX_OUT_LSD, chan_usbradio_pvt::txctcssadj, chan_usbradio_pvt::txmixa, chan_usbradio_pvt::txmixaset, chan_usbradio_pvt::txmixb, and chan_usbradio_pvt::txmixbset.
Referenced by radio_tune(), and store_config().
{
if (o->txmixa == TX_OUT_LSD)
{
// o->txmixaset=(151*o->txctcssadj) / 1000;
o->txmixaset=o->txctcssadj;
mixer_write(o);
mult_set(o);
}
else if (o->txmixb == TX_OUT_LSD)
{
// o->txmixbset=(151*o->txctcssadj) / 1000;
o->txmixbset=o->txctcssadj;
mixer_write(o);
mult_set(o);
}
else
{
*o->pmrChan->ptxCtcssAdjust=(o->txctcssadj * M_Q8) / 1000;
}
return 0;
}
| static int setamixer | ( | int | devnum, |
| char * | param, | ||
| int | v1, | ||
| int | v2 | ||
| ) | [static] |
Definition at line 751 of file chan_usbradio.c.
Referenced by mixer_write(), and tune_rxinput().
{
int type;
char str[100];
snd_hctl_t *hctl;
snd_ctl_elem_id_t *id;
snd_ctl_elem_value_t *control;
snd_hctl_elem_t *elem;
snd_ctl_elem_info_t *info;
sprintf(str,"hw:%d",devnum);
if (snd_hctl_open(&hctl, str, 0)) return(-1);
snd_hctl_load(hctl);
snd_ctl_elem_id_alloca(&id);
snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
snd_ctl_elem_id_set_name(id, param);
elem = snd_hctl_find_elem(hctl, id);
if (!elem)
{
snd_hctl_close(hctl);
return(-1);
}
snd_ctl_elem_info_alloca(&info);
snd_hctl_elem_info(elem,info);
type = snd_ctl_elem_info_get_type(info);
snd_ctl_elem_value_alloca(&control);
snd_ctl_elem_value_set_id(control, id);
switch(type)
{
case SND_CTL_ELEM_TYPE_INTEGER:
snd_ctl_elem_value_set_integer(control, 0, v1);
if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2);
break;
case SND_CTL_ELEM_TYPE_BOOLEAN:
snd_ctl_elem_value_set_integer(control, 0, (v1 != 0));
break;
}
if (snd_hctl_elem_write(elem, control))
{
snd_hctl_close(hctl);
return(-1);
}
snd_hctl_close(hctl);
return(0);
}
| static int setformat | ( | struct chan_usbradio_pvt * | o, |
| int | mode | ||
| ) | [static] |
Definition at line 1502 of file chan_usbradio.c.
References ast_log(), ast_tvnow(), ast_verbose(), chan_usbradio_pvt::devicenum, chan_usbradio_pvt::duplex, errno, ast_channel::fds, chan_usbradio_pvt::frags, chan_usbradio_pvt::lastopen, LOG_WARNING, O_CLOSE, option_verbose, chan_usbradio_pvt::owner, chan_usbradio_pvt::sounddev, VERBOSE_PREFIX_2, WARN_frag, WARN_speed, and chan_usbradio_pvt::warned.
Referenced by sound_thread(), soundcard_writeframe(), usbradio_hangup(), and usbradio_new().
{
int fmt, desired, res, fd;
char device[100];
if (o->sounddev >= 0) {
ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
close(o->sounddev);
o->duplex = M_UNSET;
o->sounddev = -1;
}
if (mode == O_CLOSE) /* we are done */
return 0;
o->lastopen = ast_tvnow();
strcpy(device,"/dev/dsp");
if (o->devicenum)
sprintf(device,"/dev/dsp%d",o->devicenum);
fd = o->sounddev = open(device, mode | O_NONBLOCK);
if (fd < 0) {
ast_log(LOG_WARNING, "Unable to re-open DSP device %d: %s\n", o->devicenum, strerror(errno));
return -1;
}
if (o->owner)
o->owner->fds[0] = fd;
#if __BYTE_ORDER == __LITTLE_ENDIAN
fmt = AFMT_S16_LE;
#else
fmt = AFMT_S16_BE;
#endif
res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
return -1;
}
switch (mode) {
case O_RDWR:
res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
/* Check to see if duplex set (FreeBSD Bug) */
res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
o->duplex = M_FULL;
};
break;
case O_WRONLY:
o->duplex = M_WRITE;
break;
case O_RDONLY:
o->duplex = M_READ;
break;
}
fmt = 1;
res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
if (res < 0) {
ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
return -1;
}
fmt = desired = 48000; /* 8000 Hz desired */
res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
if (res < 0) {
ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
return -1;
}
if (fmt != desired) {
if (!(o->warned & WARN_speed)) {
ast_log(LOG_WARNING,
"Requested %d Hz, got %d Hz -- sound may be choppy\n",
desired, fmt);
o->warned |= WARN_speed;
}
}
/*
* on Freebsd, SETFRAGMENT does not work very well on some cards.
* Default to use 256 bytes, let the user override
*/
if (o->frags) {
fmt = o->frags;
res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
if (res < 0) {
if (!(o->warned & WARN_frag)) {
ast_log(LOG_WARNING,
"Unable to set fragment size -- sound may be choppy\n");
o->warned |= WARN_frag;
}
}
}
/* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
/* it may fail if we are in half duplex, never mind */
return 0;
}
| static void* sound_thread | ( | void * | arg | ) | [static] |
Definition at line 1433 of file chan_usbradio.c.
References ast_log(), ast_poll, chan_usbradio_pvt::cursound, errno, sound::ind, LOG_WARNING, chan_usbradio_pvt::nosound, O_CLOSE, chan_usbradio_pvt::owner, chan_usbradio_pvt::sampsent, send_sound(), setformat(), chan_usbradio_pvt::sndcmd, and chan_usbradio_pvt::sounddev.
Referenced by store_config().
{
char ign[4096];
struct chan_usbradio_pvt *o = (struct chan_usbradio_pvt *) arg;
/*
* Just in case, kick the driver by trying to read from it.
* Ignore errors - this read is almost guaranteed to fail.
*/
read(o->sounddev, ign, sizeof(ign));
for (;;) {
struct pollfd pfd[2] = { { .fd = o->sndcmd[0], .events = POLLIN }, { .fd = o->sounddev } };
int res;
if (o->cursound > -1 && o->sounddev < 0) {
setformat(o, O_RDWR); /* need the channel, try to reopen */
} else if (o->cursound == -1 && o->owner == NULL) {
setformat(o, O_CLOSE); /* can close */
}
if (o->sounddev > -1) {
if (!o->owner) { /* no one owns the audio, so we must drain it */
pfd[1].events = POLLIN;
}
if (o->cursound > -1) {
pfd[1].events |= POLLOUT;
}
}
res = ast_poll(pfd, o->sounddev > -1 ? 2 : 1, -1);
if (res < 1) {
ast_log(LOG_WARNING, "poll failed: %s\n", strerror(errno));
sleep(1);
continue;
}
if (pfd[0].revents & POLLIN) {
/* read which sound to play from the pipe */
int i, what = -1;
read(o->sndcmd[0], &what, sizeof(what));
for (i = 0; sounds[i].ind != -1; i++) {
if (sounds[i].ind == what) {
o->cursound = i;
o->sampsent = 0;
o->nosound = 1; /* block audio from pbx */
break;
}
}
if (sounds[i].ind == -1) {
ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
}
}
if (o->sounddev > -1) {
if (pfd[1].revents & POLLIN) { /* read and ignore errors */
read(o->sounddev, ign, sizeof(ign));
}
if (pfd[1].revents & POLLOUT) {
send_sound(o);
}
}
}
return NULL; /* Never reached */
}
| static int soundcard_writeframe | ( | struct chan_usbradio_pvt * | o, |
| short * | data | ||
| ) | [static] |
Definition at line 1339 of file chan_usbradio.c.
References ast_log(), FRAME_SIZE, LOG_WARNING, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::queuesize, setformat(), chan_usbradio_pvt::sounddev, used_blocks(), and chan_usbradio_pvt::w_errors.
Referenced by send_sound(), and usbradio_read().
{
int res;
if (o->sounddev < 0)
setformat(o, O_RDWR);
if (o->sounddev < 0)
return 0; /* not fatal */
// maw maw sph !!! may or may not be a good thing
// drop the frame if not transmitting, this keeps from gradually
// filling the buffer when asterisk clock > usb sound clock
if(!o->pmrChan->txPttIn && !o->pmrChan->txPttOut)
{
//return 0;
}
/*
* Nothing complex to manage the audio device queue.
* If the buffer is full just drop the extra, otherwise write.
* XXX in some cases it might be useful to write anyways after
* a number of failures, to restart the output chain.
*/
res = used_blocks(o);
if (res > o->queuesize) { /* no room to write a block */
// ast_log(LOG_WARNING, "sound device write buffer overflow\n");
if (o->w_errors++ == 0 && (usbradio_debug & 0x4))
ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
return 0;
}
o->w_errors = 0;
return write(o->sounddev, ((void *) data), FRAME_SIZE * 2 * 12);
}
| static struct chan_usbradio_pvt* store_config | ( | struct ast_config * | cfg, |
| char * | ctg | ||
| ) | [static, read] |
Definition at line 3391 of file chan_usbradio.c.
References amixer_max(), chan_usbradio_pvt::area, ast_calloc, ast_config_destroy(), ast_config_load, ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_features(), ast_jb_read_conf(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, ast_strdup, ast_tvnow(), ast_variable_browse(), chan_usbradio_pvt::autoanswer, chan_usbradio_pvt::autohangup, chan_usbradio_pvt::b, config1, CONFIG_STATUS_FILEINVALID, chan_usbradio_pvt::ctx, chan_usbradio_pvt::dcsrxpolarity, chan_usbradio_pvt::dcstxpolarity, chan_usbradio_pvt::debuglevel, chan_usbradio_pvt::devicenum, chan_usbradio_pvt::devstr, chan_usbradio_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DIGIT_DETECT, chan_usbradio_pvt::eepromctl, chan_usbradio_pvt::eepromlock, chan_usbradio_pvt::ext, find_desc_usb(), chan_usbradio_pvt::frags, FRAME_SIZE, free, global_jbconf, chan_usbradio_pvt::hdwtype, hidhdwconfig(), chan_usbradio_pvt::idleinterval, chan_usbradio_pvt::invertptt, chan_usbradio_pvt::language, chan_usbradio_pvt::lastopen, LOG_ERROR, LOG_NOTICE, LOG_WARNING, chan_usbradio_pvt::loopback, chan_usbradio_pvt::lsdrxpolarity, chan_usbradio_pvt::lsdtxpolarity, M_BOOL, M_END, M_F, M_START, M_STR, M_UINT, chan_usbradio_pvt::micmax, MIXER_PARAM_MIC_CAPTURE_VOL, MIXER_PARAM_SPKR_PLAYBACK_VOL, mixer_write(), chan_usbradio_pvt::mohinterpret, mult_set(), ast_variable::name, chan_usbradio_pvt::name, chan_usbradio_pvt::next, ast_variable::next, chan_usbradio_pvt::overridecontext, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::queuesize, chan_usbradio_pvt::radioactive, chan_usbradio_pvt::radioduplex, chan_usbradio_pvt::rptnum, chan_usbradio_pvt::rxboostset, chan_usbradio_pvt::rxcdtype, chan_usbradio_pvt::rxcpusaver, chan_usbradio_pvt::rxctcssadj, chan_usbradio_pvt::rxctcssfreqs, chan_usbradio_pvt::rxctcssrelax, chan_usbradio_pvt::rxdemod, chan_usbradio_pvt::rxfreq, chan_usbradio_pvt::rxmixerset, chan_usbradio_pvt::rxpolarity, chan_usbradio_pvt::rxsquelchadj, chan_usbradio_pvt::rxsqvoxadj, chan_usbradio_pvt::rxvoiceadj, s, set_txctcss_level(), chan_usbradio_pvt::sndcmd, sound_thread(), chan_usbradio_pvt::spkrmax, chan_usbradio_pvt::sthread, store_callerid(), store_rxcdtype(), store_rxctcssadj(), store_rxdemod(), store_rxgain(), store_rxsdtype(), store_rxvoiceadj(), store_txmixa(), store_txmixb(), store_txtoctype(), chan_usbradio_pvt::tracelevel, chan_usbradio_pvt::tracetype, traceusb1, chan_usbradio_pvt::turnoffs, TX_OUT_COMPOSITE, TX_OUT_LSD, TX_OUT_VOICE, chan_usbradio_pvt::txcpusaver, chan_usbradio_pvt::txctcssadj, chan_usbradio_pvt::txctcssdefault, chan_usbradio_pvt::txctcssfreq, chan_usbradio_pvt::txctcssfreqs, chan_usbradio_pvt::txfreq, chan_usbradio_pvt::txmixa, chan_usbradio_pvt::txmixaset, chan_usbradio_pvt::txmixb, chan_usbradio_pvt::txmixbset, chan_usbradio_pvt::txpolarity, chan_usbradio_pvt::txprelim, chan_usbradio_pvt::txsettletime, chan_usbradio_pvt::txtoctype, chan_usbradio_pvt::ukey, usb_get_usbdev(), usb_list_check(), usbradio_default, ast_variable::value, chan_usbradio_pvt::wanteeprom, and xpmr_config().
Referenced by load_module().
{
struct ast_variable *v;
struct chan_usbradio_pvt *o;
struct ast_config *cfg1;
int i;
char fname[200];
#ifdef NEW_ASTERISK
struct ast_flags zeroflag = {0};
#endif
if (ctg == NULL) {
traceusb1((" store_config() ctg == NULL\n"));
o = &usbradio_default;
ctg = "general";
} else {
/* "general" is also the default thing */
if (strcmp(ctg, "general") == 0) {
o = &usbradio_default;
} else {
// ast_log(LOG_NOTICE,"ast_calloc for chan_usbradio_pvt of %s\n",ctg);
if (!(o = ast_calloc(1, sizeof(*o))))
return NULL;
*o = usbradio_default;
o->name = ast_strdup(ctg);
if (!usbradio_active)
usbradio_active = o->name;
}
}
ast_mutex_init(&o->eepromlock);
strcpy(o->mohinterpret, "default");
/* fill other fields from configuration */
for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
M_START((char *)v->name, (char *)v->value);
/* handle jb conf */
if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
continue;
#if 0
M_BOOL("autoanswer", o->autoanswer)
M_BOOL("autohangup", o->autohangup)
M_BOOL("overridecontext", o->overridecontext)
M_STR("context", o->ctx)
M_STR("language", o->language)
M_STR("mohinterpret", o->mohinterpret)
M_STR("extension", o->ext)
M_F("callerid", store_callerid(o, v->value))
#endif
M_UINT("frags", o->frags)
M_UINT("queuesize",o->queuesize)
#if 0
M_UINT("devicenum",o->devicenum)
#endif
M_UINT("debug", usbradio_debug)
M_BOOL("rxcpusaver",o->rxcpusaver)
M_BOOL("txcpusaver",o->txcpusaver)
M_BOOL("invertptt",o->invertptt)
M_F("rxdemod",store_rxdemod(o,(char *)v->value))
M_BOOL("txprelim",o->txprelim);
M_F("txmixa",store_txmixa(o,(char *)v->value))
M_F("txmixb",store_txmixb(o,(char *)v->value))
M_F("carrierfrom",store_rxcdtype(o,(char *)v->value))
M_F("rxsdtype",store_rxsdtype(o,(char *)v->value))
M_UINT("rxsqvox",o->rxsqvoxadj)
M_STR("txctcssdefault",o->txctcssdefault)
M_STR("rxctcssfreqs",o->rxctcssfreqs)
M_STR("txctcssfreqs",o->txctcssfreqs)
M_UINT("rxfreq",o->rxfreq)
M_UINT("txfreq",o->txfreq)
M_F("rxgain",store_rxgain(o,(char *)v->value))
M_BOOL("rxboost",o->rxboostset)
M_UINT("rxctcssrelax",o->rxctcssrelax)
M_F("txtoctype",store_txtoctype(o,(char *)v->value))
M_UINT("hdwtype",o->hdwtype)
M_UINT("eeprom",o->wanteeprom)
M_UINT("duplex",o->radioduplex)
M_UINT("txsettletime",o->txsettletime)
M_BOOL("rxpolarity",o->b.rxpolarity)
M_BOOL("txpolarity",o->b.txpolarity)
M_BOOL("dcsrxpolarity",o->b.dcsrxpolarity)
M_BOOL("dcstxpolarity",o->b.dcstxpolarity)
M_BOOL("lsdrxpolarity",o->b.lsdrxpolarity)
M_BOOL("lsdtxpolarity",o->b.lsdtxpolarity)
M_BOOL("loopback",o->b.loopback)
M_BOOL("radioactive",o->b.radioactive)
M_UINT("rptnum",o->rptnum)
M_UINT("idleinterval",o->idleinterval)
M_UINT("turnoffs",o->turnoffs)
M_UINT("tracetype",o->tracetype)
M_UINT("tracelevel",o->tracelevel)
M_UINT("area",o->area)
M_STR("ukey",o->ukey)
M_END(;
);
}
o->debuglevel=0;
if (o == &usbradio_default) /* we are done with the default */
return NULL;
snprintf(fname,sizeof(fname) - 1,config1,o->name);
#ifdef NEW_ASTERISK
cfg1 = ast_config_load(fname,zeroflag);
#else
cfg1 = ast_config_load(fname);
#endif
o->rxmixerset = 500;
o->txmixaset = 500;
o->txmixbset = 500;
o->rxvoiceadj = 0.5;
o->rxctcssadj = 0.5;
o->txctcssadj = 200;
o->rxsquelchadj = 500;
o->devstr[0] = 0;
if (cfg1 && cfg1 != CONFIG_STATUS_FILEINVALID) {
for (v = ast_variable_browse(cfg1, o->name); v; v = v->next) {
M_START((char *)v->name, (char *)v->value);
M_UINT("rxmixerset", o->rxmixerset)
M_UINT("txmixaset", o->txmixaset)
M_UINT("txmixbset", o->txmixbset)
M_F("rxvoiceadj",store_rxvoiceadj(o,(char *)v->value))
M_F("rxctcssadj",store_rxctcssadj(o,(char *)v->value))
M_UINT("txctcssadj",o->txctcssadj);
M_UINT("rxsquelchadj", o->rxsquelchadj)
M_STR("devstr", o->devstr)
M_END(;
);
}
ast_config_destroy(cfg1);
} else ast_log(LOG_WARNING,"File %s not found, using default parameters.\n",fname);
if(o->wanteeprom)
{
ast_mutex_lock(&o->eepromlock);
while(o->eepromctl)
{
ast_mutex_unlock(&o->eepromlock);
usleep(10000);
ast_mutex_lock(&o->eepromlock);
}
o->eepromctl = 1; /* request a load */
ast_mutex_unlock(&o->eepromlock);
}
/* if our specified one exists in the list */
if ((!usb_list_check(o->devstr)) || find_desc_usb(o->devstr))
{
char *s;
for(s = usb_device_list; *s; s += strlen(s) + 1)
{
if (!find_desc_usb(s)) break;
}
if (!*s)
{
ast_log(LOG_WARNING,"Unable to assign USB device for channel %s\n",o->name);
goto error;
}
ast_log(LOG_NOTICE,"Assigned USB device %s to usbradio channel %s\n",s,o->name);
strcpy(o->devstr,s);
}
i = usb_get_usbdev(o->devstr);
if (i < 0)
{
ast_log(LOG_ERROR,"Not able to find alsa USB device\n");
goto error;
}
o->devicenum = i;
o->micmax = amixer_max(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL);
o->spkrmax = amixer_max(o->devicenum,MIXER_PARAM_SPKR_PLAYBACK_VOL);
o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
o->dsp = ast_dsp_new();
if (o->dsp)
{
#ifdef NEW_ASTERISK
ast_dsp_set_features(o->dsp,DSP_FEATURE_DIGIT_DETECT);
ast_dsp_set_digitmode(o->dsp,DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
#else
ast_dsp_set_features(o->dsp,DSP_FEATURE_DTMF_DETECT);
ast_dsp_digitmode(o->dsp,DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
#endif
}
if(o->pmrChan==NULL)
{
t_pmr_chan tChan;
// ast_log(LOG_NOTICE,"createPmrChannel() %s\n",o->name);
memset(&tChan,0,sizeof(t_pmr_chan));
tChan.pTxCodeDefault = o->txctcssdefault;
tChan.pRxCodeSrc = o->rxctcssfreqs;
tChan.pTxCodeSrc = o->txctcssfreqs;
tChan.rxDemod=o->rxdemod;
tChan.rxCdType=o->rxcdtype;
tChan.rxSqVoxAdj=o->rxsqvoxadj;
if (o->txprelim)
tChan.txMod = 2;
tChan.txMixA = o->txmixa;
tChan.txMixB = o->txmixb;
tChan.rxCpuSaver=o->rxcpusaver;
tChan.txCpuSaver=o->txcpusaver;
tChan.b.rxpolarity=o->b.rxpolarity;
tChan.b.txpolarity=o->b.txpolarity;
tChan.b.dcsrxpolarity=o->b.dcsrxpolarity;
tChan.b.dcstxpolarity=o->b.dcstxpolarity;
tChan.b.lsdrxpolarity=o->b.lsdrxpolarity;
tChan.b.lsdtxpolarity=o->b.lsdtxpolarity;
tChan.tracetype=o->tracetype;
tChan.tracelevel=o->tracelevel;
tChan.rptnum=o->rptnum;
tChan.idleinterval=o->idleinterval;
tChan.turnoffs=o->turnoffs;
tChan.area=o->area;
tChan.ukey=o->ukey;
tChan.name=o->name;
o->pmrChan=createPmrChannel(&tChan,FRAME_SIZE);
o->pmrChan->radioDuplex=o->radioduplex;
o->pmrChan->b.loopback=0;
o->pmrChan->txsettletime=o->txsettletime;
o->pmrChan->rxCpuSaver=o->rxcpusaver;
o->pmrChan->txCpuSaver=o->txcpusaver;
*(o->pmrChan->prxSquelchAdjust) =
((999 - o->rxsquelchadj) * 32767) / 1000;
*(o->pmrChan->prxVoiceAdjust)=o->rxvoiceadj*M_Q8;
*(o->pmrChan->prxCtcssAdjust)=o->rxctcssadj*M_Q8;
o->pmrChan->rxCtcss->relax=o->rxctcssrelax;
o->pmrChan->txTocType = o->txtoctype;
if ( (o->txmixa == TX_OUT_LSD) ||
(o->txmixa == TX_OUT_COMPOSITE) ||
(o->txmixb == TX_OUT_LSD) ||
(o->txmixb == TX_OUT_COMPOSITE))
{
set_txctcss_level(o);
}
if( (o->txmixa!=TX_OUT_VOICE) && (o->txmixb!=TX_OUT_VOICE) &&
(o->txmixa!=TX_OUT_COMPOSITE) && (o->txmixb!=TX_OUT_COMPOSITE)
)
{
ast_log(LOG_ERROR,"No txvoice output configured.\n");
}
if( o->txctcssfreq[0] &&
o->txmixa!=TX_OUT_LSD && o->txmixa!=TX_OUT_COMPOSITE &&
o->txmixb!=TX_OUT_LSD && o->txmixb!=TX_OUT_COMPOSITE
)
{
ast_log(LOG_ERROR,"No txtone output configured.\n");
}
if(o->b.radioactive)
{
// 20080328 sphenke asdf maw !!!
// this diagnostic option was working but now appears broken
// it's not required for operation so I'll fix it later.
//struct chan_usbradio_pvt *ao;
//for (ao = usbradio_default.next; ao && ao->name ; ao = ao->next)ao->pmrChan->b.radioactive=0;
usbradio_active = o->name;
// o->pmrChan->b.radioactive=1;
//o->b.radioactive=0;
//o->pmrChan->b.radioactive=0;
ast_log(LOG_NOTICE,"radio active set to [%s]\n",o->name);
}
}
xpmr_config(o);
TRACEO(1,("store_config() 120\n"));
mixer_write(o);
TRACEO(1,("store_config() 130\n"));
mult_set(o);
TRACEO(1,("store_config() 140\n"));
hidhdwconfig(o);
TRACEO(1,("store_config() 200\n"));
#ifndef NEW_ASTERISK
if (pipe(o->sndcmd) != 0) {
ast_log(LOG_ERROR, "Unable to create pipe\n");
goto error;
}
ast_pthread_create_background(&o->sthread, NULL, sound_thread, o);
#endif
/* link into list of devices */
if (o != &usbradio_default) {
o->next = usbradio_default.next;
usbradio_default.next = o;
}
TRACEO(1,("store_config() complete\n"));
return o;
error:
if (o != &usbradio_default)
free(o);
return NULL;
}
| static void store_rxcdtype | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2750 of file chan_usbradio.c.
References ast_log(), CD_HID, CD_HID_INVERT, CD_IGNORE, CD_XPMR_NOISE, CD_XPMR_VOX, LOG_WARNING, and chan_usbradio_pvt::rxcdtype.
Referenced by store_config().
{
if (!strcasecmp(s,"no")){
o->rxcdtype = CD_IGNORE;
}
else if (!strcasecmp(s,"usb")){
o->rxcdtype = CD_HID;
}
else if (!strcasecmp(s,"dsp")){
o->rxcdtype = CD_XPMR_NOISE;
}
else if (!strcasecmp(s,"vox")){
o->rxcdtype = CD_XPMR_VOX;
}
else if (!strcasecmp(s,"usbinvert")){
o->rxcdtype = CD_HID_INVERT;
}
else {
ast_log(LOG_WARNING,"Unrecognized rxcdtype parameter: %s\n",s);
}
//ast_log(LOG_WARNING, "set rxcdtype = %s\n", s);
}
| static void store_rxctcssadj | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2815 of file chan_usbradio.c.
References f, and chan_usbradio_pvt::rxctcssadj.
Referenced by store_config().
{
float f;
sscanf(s, "%30f", &f);
o->rxctcssadj = f;
//ast_log(LOG_WARNING, "set rxctcssadj = %f\n", f);
}
| static void store_rxdemod | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2682 of file chan_usbradio.c.
References ast_log(), LOG_WARNING, RX_AUDIO_FLAT, RX_AUDIO_NONE, RX_AUDIO_SPEAKER, and chan_usbradio_pvt::rxdemod.
Referenced by store_config().
{
if (!strcasecmp(s,"no")){
o->rxdemod = RX_AUDIO_NONE;
}
else if (!strcasecmp(s,"speaker")){
o->rxdemod = RX_AUDIO_SPEAKER;
}
else if (!strcasecmp(s,"flat")){
o->rxdemod = RX_AUDIO_FLAT;
}
else {
ast_log(LOG_WARNING,"Unrecognized rxdemod parameter: %s\n",s);
}
//ast_log(LOG_WARNING, "set rxdemod = %s\n", s);
}
| static void store_rxgain | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2797 of file chan_usbradio.c.
References f, and chan_usbradio_pvt::rxgain.
Referenced by store_config().
| static void store_rxsdtype | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2775 of file chan_usbradio.c.
References ast_log(), LOG_WARNING, chan_usbradio_pvt::rxsdtype, SD_HID, SD_HID_INVERT, SD_IGNORE, and SD_XPMR.
Referenced by store_config().
{
if (!strcasecmp(s,"no") || !strcasecmp(s,"SD_IGNORE")){
o->rxsdtype = SD_IGNORE;
}
else if (!strcasecmp(s,"usb") || !strcasecmp(s,"SD_HID")){
o->rxsdtype = SD_HID;
}
else if (!strcasecmp(s,"usbinvert") || !strcasecmp(s,"SD_HID_INVERT")){
o->rxsdtype = SD_HID_INVERT;
}
else if (!strcasecmp(s,"software") || !strcasecmp(s,"SD_XPMR")){
o->rxsdtype = SD_XPMR;
}
else {
ast_log(LOG_WARNING,"Unrecognized rxsdtype parameter: %s\n",s);
}
//ast_log(LOG_WARNING, "set rxsdtype = %s\n", s);
}
| static void store_rxvoiceadj | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2806 of file chan_usbradio.c.
References f, and chan_usbradio_pvt::rxvoiceadj.
Referenced by store_config().
{
float f;
sscanf(s, "%30f", &f);
o->rxvoiceadj = f;
//ast_log(LOG_WARNING, "set rxvoiceadj = %f\n", f);
}
| static void store_txmixa | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2701 of file chan_usbradio.c.
References ast_log(), LOG_WARNING, TX_OUT_AUX, TX_OUT_COMPOSITE, TX_OUT_LSD, TX_OUT_OFF, TX_OUT_VOICE, and chan_usbradio_pvt::txmixa.
Referenced by store_config().
{
if (!strcasecmp(s,"no")){
o->txmixa = TX_OUT_OFF;
}
else if (!strcasecmp(s,"voice")){
o->txmixa = TX_OUT_VOICE;
}
else if (!strcasecmp(s,"tone")){
o->txmixa = TX_OUT_LSD;
}
else if (!strcasecmp(s,"composite")){
o->txmixa = TX_OUT_COMPOSITE;
}
else if (!strcasecmp(s,"auxvoice")){
o->txmixa = TX_OUT_AUX;
}
else {
ast_log(LOG_WARNING,"Unrecognized txmixa parameter: %s\n",s);
}
//ast_log(LOG_WARNING, "set txmixa = %s\n", s);
}
| static void store_txmixb | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2725 of file chan_usbradio.c.
References ast_log(), LOG_WARNING, TX_OUT_AUX, TX_OUT_COMPOSITE, TX_OUT_LSD, TX_OUT_OFF, TX_OUT_VOICE, and chan_usbradio_pvt::txmixb.
Referenced by store_config().
{
if (!strcasecmp(s,"no")){
o->txmixb = TX_OUT_OFF;
}
else if (!strcasecmp(s,"voice")){
o->txmixb = TX_OUT_VOICE;
}
else if (!strcasecmp(s,"tone")){
o->txmixb = TX_OUT_LSD;
}
else if (!strcasecmp(s,"composite")){
o->txmixb = TX_OUT_COMPOSITE;
}
else if (!strcasecmp(s,"auxvoice")){
o->txmixb = TX_OUT_AUX;
}
else {
ast_log(LOG_WARNING,"Unrecognized txmixb parameter: %s\n",s);
}
//ast_log(LOG_WARNING, "set txmixb = %s\n", s);
}
| static void store_txtoctype | ( | struct chan_usbradio_pvt * | o, |
| const char * | s | ||
| ) | [static] |
Definition at line 2824 of file chan_usbradio.c.
References ast_log(), LOG_WARNING, TOC_NONE, TOC_NOTONE, TOC_PHASE, and chan_usbradio_pvt::txtoctype.
Referenced by store_config().
{
if (!strcasecmp(s,"no") || !strcasecmp(s,"TOC_NONE")){
o->txtoctype = TOC_NONE;
}
else if (!strcasecmp(s,"phase") || !strcasecmp(s,"TOC_PHASE")){
o->txtoctype = TOC_PHASE;
}
else if (!strcasecmp(s,"notone") || !strcasecmp(s,"TOC_NOTONE")){
o->txtoctype = TOC_NOTONE;
}
else {
ast_log(LOG_WARNING,"Unrecognized txtoctype parameter: %s\n",s);
}
}
| static void tune_rxctcss | ( | int | fd, |
| struct chan_usbradio_pvt * | o | ||
| ) | [static] |
Definition at line 3001 of file chan_usbradio.c.
References ast_cli(), chan_usbradio_pvt::pmrChan, and chan_usbradio_pvt::rxctcssadj.
Referenced by radio_tune().
{
const int target=2400; // was 4096 pre 20080205
const int tolerance=100;
const float settingmin=0.1;
const float settingmax=8;
const float settingstart=1;
const int maxtries=12;
float setting;
int tries=0, meas;
ast_cli(fd,"INFO: RX CTCSS ADJUST START.\n");
ast_cli(fd,"target=%i tolerance=%i \n",target,tolerance);
o->pmrChan->b.tuning=1;
o->pmrChan->spsMeasure->source=o->pmrChan->prxCtcssMeasure;
o->pmrChan->spsMeasure->discfactor=400;
o->pmrChan->spsMeasure->enabled=1;
setting=settingstart;
while(tries<maxtries)
{
*(o->pmrChan->prxCtcssAdjust)=setting*M_Q8;
usleep(10000);
o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
usleep(500000);
meas = o->pmrChan->spsMeasure->apeak;
ast_cli(fd,"tries=%i, setting=%f, meas=%i\n",tries,setting,meas);
if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
setting=setting*target/meas;
}
else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
{
break;
}
if(setting<settingmin)setting=settingmin;
else if(setting>settingmax)setting=settingmax;
tries++;
}
o->pmrChan->spsMeasure->enabled=0;
ast_cli(fd,"DONE tries=%i, setting=%f, meas=%f\n",tries,setting,(float)meas);
if( meas<(target-tolerance) || meas>(target+tolerance) ){
ast_cli(fd,"ERROR: RX CTCSS GAIN ADJUST FAILED.\n");
}else{
ast_cli(fd,"INFO: RX CTCSS GAIN ADJUST SUCCESS.\n");
o->rxctcssadj=setting;
}
o->pmrChan->b.tuning=0;
}
| static void tune_rxinput | ( | int | fd, |
| struct chan_usbradio_pvt * | o | ||
| ) | [static] |
Definition at line 2855 of file chan_usbradio.c.
References ast_cli(), CD_XPMR_NOISE, chan_usbradio_pvt::devicenum, chan_usbradio_pvt::micmax, MIXER_PARAM_MIC_BOOST, MIXER_PARAM_MIC_CAPTURE_VOL, chan_usbradio_pvt::pmrChan, RX_AUDIO_SPEAKER, chan_usbradio_pvt::rxboostset, chan_usbradio_pvt::rxcdtype, chan_usbradio_pvt::rxdemod, chan_usbradio_pvt::rxmixerset, and setamixer().
Referenced by radio_tune().
{
const int target=23000;
const int tolerance=2000;
const int settingmin=1;
const int settingstart=2;
const int maxtries=12;
float settingmax;
int setting=0, tries=0, tmpdiscfactor, meas;
int tunetype=0;
settingmax = o->micmax;
if(o->pmrChan->rxDemod)tunetype=1;
o->pmrChan->b.tuning=1;
setting = settingstart;
ast_cli(fd,"tune rxnoise maxtries=%i, target=%i, tolerance=%i\n",maxtries,target,tolerance);
while(tries<maxtries)
{
setamixer(o->devicenum,MIXER_PARAM_MIC_CAPTURE_VOL,setting,0);
setamixer(o->devicenum,MIXER_PARAM_MIC_BOOST,o->rxboostset,0);
usleep(100000);
if(o->rxcdtype!=CD_XPMR_NOISE || o->rxdemod==RX_AUDIO_SPEAKER)
{
// printf("Measure Direct Input\n");
o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
o->pmrChan->spsMeasure->discfactor=2000;
o->pmrChan->spsMeasure->enabled=1;
o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
usleep(400000);
meas=o->pmrChan->spsMeasure->apeak;
o->pmrChan->spsMeasure->enabled=0;
}
else
{
// printf("Measure HF Noise\n");
tmpdiscfactor=o->pmrChan->spsRx->discfactor;
o->pmrChan->spsRx->discfactor=(i16)2000;
o->pmrChan->spsRx->discounteru=o->pmrChan->spsRx->discounterl=0;
o->pmrChan->spsRx->amax=o->pmrChan->spsRx->amin=0;
usleep(200000);
meas=o->pmrChan->rxRssi;
o->pmrChan->spsRx->discfactor=tmpdiscfactor;
o->pmrChan->spsRx->discounteru=o->pmrChan->spsRx->discounterl=0;
o->pmrChan->spsRx->amax=o->pmrChan->spsRx->amin=0;
}
if(!meas)meas++;
ast_cli(fd,"tries=%i, setting=%i, meas=%i\n",tries,setting,meas);
if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
setting=setting*target/meas;
}
else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
{
break;
}
if(setting<settingmin)setting=settingmin;
else if(setting>settingmax)setting=settingmax;
tries++;
}
ast_cli(fd,"DONE tries=%i, setting=%i, meas=%i\n",tries,
(setting * 1000) / o->micmax,meas);
if( meas<(target-tolerance) || meas>(target+tolerance) ){
ast_cli(fd,"ERROR: RX INPUT ADJUST FAILED.\n");
}else{
ast_cli(fd,"INFO: RX INPUT ADJUST SUCCESS.\n");
o->rxmixerset=(setting * 1000) / o->micmax;
}
o->pmrChan->b.tuning=0;
}
| static void tune_rxvoice | ( | int | fd, |
| struct chan_usbradio_pvt * | o | ||
| ) | [static] |
Definition at line 2935 of file chan_usbradio.c.
References ast_cli(), chan_usbradio_pvt::pmrChan, and chan_usbradio_pvt::rxvoiceadj.
Referenced by radio_tune().
{
const int target=7200; // peak
const int tolerance=360; // peak to peak
const float settingmin=0.1;
const float settingmax=4;
const float settingstart=1;
const int maxtries=12;
float setting;
int tries=0, meas;
ast_cli(fd,"INFO: RX VOICE ADJUST START.\n");
ast_cli(fd,"target=%i tolerance=%i \n",target,tolerance);
o->pmrChan->b.tuning=1;
if(!o->pmrChan->spsMeasure)
ast_cli(fd,"ERROR: NO MEASURE BLOCK.\n");
if(!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
ast_cli(fd,"ERROR: NO SOURCE OR MEASURE SETTING.\n");
o->pmrChan->spsMeasure->source=o->pmrChan->spsRxOut->sink;
o->pmrChan->spsMeasure->enabled=1;
o->pmrChan->spsMeasure->discfactor=1000;
setting=settingstart;
// ast_cli(fd,"ERROR: NO MEASURE BLOCK.\n");
while(tries<maxtries)
{
*(o->pmrChan->prxVoiceAdjust)=setting*M_Q8;
usleep(10000);
o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
usleep(1000000);
meas = o->pmrChan->spsMeasure->apeak;
ast_cli(fd,"tries=%i, setting=%f, meas=%i\n",tries,setting,meas);
if( meas<(target-tolerance) || meas>(target+tolerance) || tries<3){
setting=setting*target/meas;
}
else if(tries>4 && meas>(target-tolerance) && meas<(target+tolerance) )
{
break;
}
if(setting<settingmin)setting=settingmin;
else if(setting>settingmax)setting=settingmax;
tries++;
}
o->pmrChan->spsMeasure->enabled=0;
ast_cli(fd,"DONE tries=%i, setting=%f, meas=%f\n",tries,setting,(float)meas);
if( meas<(target-tolerance) || meas>(target+tolerance) ){
ast_cli(fd,"ERROR: RX VOICE GAIN ADJUST FAILED.\n");
}else{
ast_cli(fd,"INFO: RX VOICE GAIN ADJUST SUCCESS.\n");
o->rxvoiceadj=setting;
}
o->pmrChan->b.tuning=0;
}
| static void tune_txoutput | ( | struct chan_usbradio_pvt * | o, |
| int | value, | ||
| int | fd | ||
| ) | [static] |
Definition at line 2841 of file chan_usbradio.c.
References ast_cli(), chan_usbradio_pvt::name, chan_usbradio_pvt::pmrChan, and chan_usbradio_pvt::txtestkey.
Referenced by radio_tune().
{
o->txtestkey=1;
o->pmrChan->txPttIn=1;
TxTestTone(o->pmrChan, 1); // generate 1KHz tone at 7200 peak
if (fd > 0) ast_cli(fd,"Tone output starting on channel %s...\n",o->name);
usleep(5000000);
TxTestTone(o->pmrChan, 0);
if (fd > 0) ast_cli(fd,"Tone output ending on channel %s...\n",o->name);
o->pmrChan->txPttIn=0;
o->txtestkey=0;
}
| static void tune_write | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 3057 of file chan_usbradio.c.
References ast_mutex_lock(), ast_mutex_unlock(), chan_usbradio_pvt::devicenum, chan_usbradio_pvt::devstr, chan_usbradio_pvt::eeprom, EEPROM_RXCTCSSADJ, EEPROM_RXMIXERSET, EEPROM_RXSQUELCHADJ, EEPROM_RXVOICEADJ, EEPROM_TXCTCSSADJ, EEPROM_TXMIXASET, EEPROM_TXMIXBSET, chan_usbradio_pvt::eepromctl, chan_usbradio_pvt::eepromlock, chan_usbradio_pvt::name, chan_usbradio_pvt::rxctcssadj, chan_usbradio_pvt::rxmixerset, chan_usbradio_pvt::rxsquelchadj, chan_usbradio_pvt::rxvoiceadj, chan_usbradio_pvt::txctcssadj, chan_usbradio_pvt::txmixaset, chan_usbradio_pvt::txmixbset, and chan_usbradio_pvt::wanteeprom.
Referenced by radio_tune().
{
FILE *fp;
char fname[200];
snprintf(fname,sizeof(fname) - 1,"/etc/asterisk/usbradio_tune_%s.conf",o->name);
fp = fopen(fname,"w");
fprintf(fp,"[%s]\n",o->name);
fprintf(fp,"; name=%s\n",o->name);
fprintf(fp,"; devicenum=%i\n",o->devicenum);
fprintf(fp,"devstr=%s\n",o->devstr);
fprintf(fp,"rxmixerset=%i\n",o->rxmixerset);
fprintf(fp,"txmixaset=%i\n",o->txmixaset);
fprintf(fp,"txmixbset=%i\n",o->txmixbset);
fprintf(fp,"rxvoiceadj=%f\n",o->rxvoiceadj);
fprintf(fp,"rxctcssadj=%f\n",o->rxctcssadj);
fprintf(fp,"txctcssadj=%i\n",o->txctcssadj);
fprintf(fp,"rxsquelchadj=%i\n",o->rxsquelchadj);
fclose(fp);
if(o->wanteeprom)
{
ast_mutex_lock(&o->eepromlock);
while(o->eepromctl)
{
ast_mutex_unlock(&o->eepromlock);
usleep(10000);
ast_mutex_lock(&o->eepromlock);
}
o->eeprom[EEPROM_RXMIXERSET] = o->rxmixerset;
o->eeprom[EEPROM_TXMIXASET] = o->txmixaset;
o->eeprom[EEPROM_TXMIXBSET] = o->txmixbset;
memcpy(&o->eeprom[EEPROM_RXVOICEADJ],&o->rxvoiceadj,sizeof(float));
memcpy(&o->eeprom[EEPROM_RXCTCSSADJ],&o->rxctcssadj,sizeof(float));
o->eeprom[EEPROM_TXCTCSSADJ] = o->txctcssadj;
o->eeprom[EEPROM_RXSQUELCHADJ] = o->rxsquelchadj;
o->eepromctl = 2; /* request a write */
ast_mutex_unlock(&o->eepromlock);
}
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 3978 of file chan_usbradio.c.
References ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_dsp_free(), ast_log(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, chan_usbradio_pvt::dsp, LOG_WARNING, chan_usbradio_pvt::next, chan_usbradio_pvt::owner, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::sndcmd, and chan_usbradio_pvt::sounddev.
{
struct chan_usbradio_pvt *o;
ast_log(LOG_WARNING, "unload_module() called\n");
ast_channel_unregister(&usbradio_tech);
ast_cli_unregister_multiple(cli_usbradio, ARRAY_LEN(cli_usbradio));
for (o = usbradio_default.next; o; o = o->next) {
ast_log(LOG_WARNING, "destroyPmrChannel() called\n");
if(o->pmrChan)destroyPmrChannel(o->pmrChan);
#if DEBUG_CAPTURES == 1
if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
#endif
close(o->sounddev);
#ifndef NEW_ASTERISK
if (o->sndcmd[0] > 0) {
close(o->sndcmd[0]);
close(o->sndcmd[1]);
}
#endif
if (o->dsp) ast_dsp_free(o->dsp);
if (o->owner)
ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
if (o->owner) /* XXX how ??? */
return -1;
/* XXX what about the thread ? */
/* XXX what about the memory allocated ? */
}
return 0;
}
| static int usb_get_usbdev | ( | char * | devstr | ) | [static] |
Definition at line 1018 of file chan_usbradio.c.
References str.
Referenced by store_config().
{
int i;
char str[200],desdev[200],*cp;
for(i = 0;i < 32; i++)
{
if (i) sprintf(str,"/sys/class/sound/dsp%d/device",i);
else strcpy(str,"/sys/class/sound/dsp/device");
memset(desdev,0,sizeof(desdev));
if (readlink(str,desdev,sizeof(desdev) - 1) == -1)
{
sprintf(str,"/sys/class/sound/controlC%d/device",i);
memset(desdev,0,sizeof(desdev));
if (readlink(str,desdev,sizeof(desdev) - 1) == -1) continue;
}
cp = strrchr(desdev,'/');
if (cp) *cp = 0; else continue;
cp = strrchr(desdev,'/');
if (!cp) continue;
cp++;
if (!strcasecmp(cp,devstr)) break;
}
if (i >= 32) return -1;
return i;
}
| static int usb_list_check | ( | char * | devstr | ) | [static] |
Definition at line 1046 of file chan_usbradio.c.
References s, and usb_device_list.
Referenced by load_module(), and store_config().
{
char *s = usb_device_list;
if (!s) return(0);
while(*s)
{
if (!strcasecmp(s,devstr)) return(1);
s += strlen(s) + 1;
}
return(0);
}
| static int usbradio_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 1695 of file chan_usbradio.c.
References ast_setstate(), AST_STATE_UP, chan_usbradio_pvt::cursound, chan_usbradio_pvt::nosound, and ast_channel::tech_pvt.
{
#ifndef NEW_ASTERISK
struct chan_usbradio_pvt *o = c->tech_pvt;
#endif
ast_setstate(c, AST_STATE_UP);
#ifndef NEW_ASTERISK
o->cursound = -1;
o->nosound = 0;
#endif
return 0;
}
| static int usbradio_call | ( | struct ast_channel * | c, |
| char * | dest, | ||
| int | timeout | ||
| ) | [static] |
Definition at line 1681 of file chan_usbradio.c.
References ast_pthread_create_background, ast_setstate(), AST_STATE_UP, hidthread(), chan_usbradio_pvt::hidthread, chan_usbradio_pvt::lasthidtime, chan_usbradio_pvt::stophid, and ast_channel::tech_pvt.
{
struct chan_usbradio_pvt *o = c->tech_pvt;
o->stophid = 0;
time(&o->lasthidtime);
ast_pthread_create_background(&o->hidthread, NULL, hidthread, o);
ast_setstate(c, AST_STATE_UP);
return 0;
}
| static int usbradio_digit_begin | ( | struct ast_channel * | c, |
| char | digit | ||
| ) | [static] |
Definition at line 1602 of file chan_usbradio.c.
{
return 0;
}
| static int usbradio_digit_end | ( | struct ast_channel * | c, |
| char | digit, | ||
| unsigned int | duration | ||
| ) | [static] |
Definition at line 1607 of file chan_usbradio.c.
References ast_verbose().
{
/* no better use for received digits than print them */
ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
digit, duration);
return 0;
}
| static int usbradio_fixup | ( | struct ast_channel * | oldchan, |
| struct ast_channel * | newchan | ||
| ) | [static] |
Definition at line 2100 of file chan_usbradio.c.
References ast_log(), LOG_WARNING, chan_usbradio_pvt::owner, and ast_channel::tech_pvt.
{
struct chan_usbradio_pvt *o = newchan->tech_pvt;
ast_log(LOG_WARNING,"usbradio_fixup()\n");
o->owner = newchan;
return 0;
}
| static int usbradio_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 1709 of file chan_usbradio.c.
References AST_CONTROL_CONGESTION, ast_module_unref(), chan_usbradio_pvt::autoanswer, chan_usbradio_pvt::autohangup, chan_usbradio_pvt::cursound, chan_usbradio_pvt::hidthread, chan_usbradio_pvt::hookstate, chan_usbradio_pvt::nosound, O_CLOSE, chan_usbradio_pvt::owner, ring(), ast_module_info::self, setformat(), chan_usbradio_pvt::stophid, and ast_channel::tech_pvt.
{
struct chan_usbradio_pvt *o = c->tech_pvt;
//ast_log(LOG_NOTICE, "usbradio_hangup()\n");
#ifndef NEW_ASTERISK
o->cursound = -1;
o->nosound = 0;
#endif
c->tech_pvt = NULL;
o->owner = NULL;
ast_module_unref(ast_module_info->self);
if (o->hookstate) {
if (o->autoanswer || o->autohangup) {
/* Assume auto-hangup too */
o->hookstate = 0;
setformat(o, O_CLOSE);
} else {
/* Make congestion noise */
ring(o, AST_CONTROL_CONGESTION);
}
}
o->stophid = 1;
pthread_join(o->hidthread,NULL);
return 0;
}
| static int usbradio_indicate | ( | struct ast_channel * | chan, |
| int | cond, | ||
| const void * | data, | ||
| size_t | datalen | ||
| ) | [static] |
Definition at line 2108 of file chan_usbradio.c.
References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_verbose(), cond, chan_usbradio_pvt::cursound, chan_usbradio_pvt::debuglevel, LOG_WARNING, chan_usbradio_pvt::mohinterpret, ast_channel::name, chan_usbradio_pvt::nosound, ring(), ast_channel::tech_pvt, and chan_usbradio_pvt::txkeyed.
{
struct chan_usbradio_pvt *o = c->tech_pvt;
int res = -1;
switch (cond) {
case AST_CONTROL_BUSY:
case AST_CONTROL_CONGESTION:
case AST_CONTROL_RINGING:
res = cond;
break;
case -1:
#ifndef NEW_ASTERISK
o->cursound = -1;
o->nosound = 0; /* when cursound is -1 nosound must be 0 */
#endif
return 0;
case AST_CONTROL_VIDUPDATE:
res = -1;
break;
case AST_CONTROL_HOLD:
ast_verbose(" << Console Has Been Placed on Hold >> \n");
ast_moh_start(c, data, o->mohinterpret);
break;
case AST_CONTROL_UNHOLD:
ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
ast_moh_stop(c);
break;
case AST_CONTROL_PROCEEDING:
ast_verbose(" << Call Proceeding... >> \n");
ast_moh_stop(c);
break;
case AST_CONTROL_PROGRESS:
ast_verbose(" << Call Progress... >> \n");
ast_moh_stop(c);
break;
case AST_CONTROL_RADIO_KEY:
o->txkeyed = 1;
if(o->debuglevel)ast_verbose(" << AST_CONTROL_RADIO_KEY Radio Transmit On. >> \n");
break;
case AST_CONTROL_RADIO_UNKEY:
o->txkeyed = 0;
if(o->debuglevel)ast_verbose(" << AST_CONTROL_RADIO_UNKEY Radio Transmit Off. >> \n");
break;
default:
ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
return -1;
}
if (res > -1)
ring(o, res);
return 0;
}
| static struct ast_channel* usbradio_new | ( | struct chan_usbradio_pvt * | o, |
| char * | ext, | ||
| char * | ctx, | ||
| int | state | ||
| ) | [static, read] |
Definition at line 2168 of file chan_usbradio.c.
References ast_channel_alloc(), AST_FORMAT_SLINEAR, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, chan_usbradio_pvt::cid_name, ast_callerid::cid_num, chan_usbradio_pvt::cid_num, ast_channel::fds, global_jbconf, language, chan_usbradio_pvt::language, LOG_WARNING, ast_channel::name, chan_usbradio_pvt::name, ast_channel::nativeformats, chan_usbradio_pvt::owner, ast_channel::readformat, ast_module_info::self, setformat(), chan_usbradio_pvt::sounddev, ast_channel::tech, ast_channel::tech_pvt, usbradio_tech, and ast_channel::writeformat.
Referenced by usbradio_request().
{
struct ast_channel *c;
c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "Radio/%s", o->name);
if (c == NULL)
return NULL;
c->tech = &usbradio_tech;
if (o->sounddev < 0)
setformat(o, O_RDWR);
c->fds[0] = o->sounddev; /* -1 if device closed, override later */
c->nativeformats = AST_FORMAT_SLINEAR;
c->readformat = AST_FORMAT_SLINEAR;
c->writeformat = AST_FORMAT_SLINEAR;
c->tech_pvt = o;
if (!ast_strlen_zero(o->language))
ast_string_field_set(c, language, o->language);
/* Don't use ast_set_callerid() here because it will
* generate a needless NewCallerID event */
c->cid.cid_num = ast_strdup(o->cid_num);
c->cid.cid_ani = ast_strdup(o->cid_num);
c->cid.cid_name = ast_strdup(o->cid_name);
if (!ast_strlen_zero(ext))
c->cid.cid_dnid = ast_strdup(ext);
o->owner = c;
ast_module_ref(ast_module_info->self);
ast_jb_configure(c, &global_jbconf);
if (state != AST_STATE_DOWN) {
if (ast_pbx_start(c)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
ast_hangup(c);
o->owner = c = NULL;
/* XXX what about the channel itself ? */
/* XXX what about usecnt ? */
}
}
return c;
}
| static struct ast_frame * usbradio_read | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 1781 of file chan_usbradio.c.
References ast_channel::_state, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_dsp_process(), AST_FORMAT_SLINEAR, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_queue_frame(), AST_STATE_UP, chan_usbradio_pvt::b, chan_usbradio_pvt::boost, BOOST_SCALE, CD_HID, CD_HID_INVERT, CD_XPMR_NOISE, CD_XPMR_VOX, ast_frame::data, ast_frame::datalen, chan_usbradio_pvt::debuglevel, chan_usbradio_pvt::dsp, errno, f, FRAME_SIZE, ast_frame::frametype, fwrite, kickptt(), chan_usbradio_pvt::lasthidtime, chan_usbradio_pvt::lastrx, LOG_ERROR, LOG_NOTICE, LOG_WARNING, chan_usbradio_pvt::mute, ast_channel::name, chan_usbradio_pvt::name, ast_frame::offset, chan_usbradio_pvt::owner, chan_usbradio_pvt::pmrChan, ast_frame::ptr, chan_usbradio_pvt::radioduplex, chan_usbradio_pvt::read_f, READERR_THRESHOLD, chan_usbradio_pvt::readerrs, chan_usbradio_pvt::readpos, RX_CAP_OUT_FILE, chan_usbradio_pvt::rxcap2, chan_usbradio_pvt::rxcapraw, chan_usbradio_pvt::rxcarrierdetect, chan_usbradio_pvt::rxcdtype, chan_usbradio_pvt::rxctcssdecode, chan_usbradio_pvt::rxctcssfreq, chan_usbradio_pvt::rxdcsdecode, chan_usbradio_pvt::rxhidsq, chan_usbradio_pvt::rxkeyed, chan_usbradio_pvt::rxlsddecode, ast_frame::samples, soundcard_writeframe(), chan_usbradio_pvt::sounddev, ast_frame::src, ast_frame::subclass, ast_channel::tech_pvt, traceusb2, TX_CAP_OUT_FILE, chan_usbradio_pvt::txcap2, chan_usbradio_pvt::txkeyed, chan_usbradio_pvt::txtestkey, ast_channel_tech::type, chan_usbradio_pvt::usbradio_read_buf, chan_usbradio_pvt::usbradio_read_buf_8k, chan_usbradio_pvt::usbradio_write_buf, chan_usbradio_pvt::usbradio_write_buf_1, and chan_usbradio_pvt::usbradio_write_dst.
{
int res, src, datalen, oldpttout;
int cd,sd;
struct chan_usbradio_pvt *o = c->tech_pvt;
struct ast_frame *f = &o->read_f,*f1;
struct ast_frame wf = { AST_FRAME_CONTROL };
time_t now;
traceusb2(("usbradio_read()\n"));
if (o->lasthidtime)
{
time(&now);
if ((now - o->lasthidtime) > 3)
{
ast_log(LOG_ERROR,"HID process has died or something!!\n");
return NULL;
}
}
/* XXX can be simplified returning &ast_null_frame */
/* prepare a NULL frame in case we don't have enough data to return */
memset(f, '\0', sizeof(struct ast_frame));
f->frametype = AST_FRAME_NULL;
f->src = usbradio_tech.type;
res = read(o->sounddev, o->usbradio_read_buf + o->readpos,
sizeof(o->usbradio_read_buf) - o->readpos);
if (res < 0) /* audio data not ready, return a NULL frame */
{
if (errno != EAGAIN) return NULL;
if (o->readerrs++ > READERR_THRESHOLD)
{
ast_log(LOG_ERROR,"Stuck USB read channel [%s], un-sticking it!\n",o->name);
o->readerrs = 0;
return NULL;
}
if (o->readerrs == 1)
ast_log(LOG_WARNING,"Possibly stuck USB read channel. [%s]\n",o->name);
return f;
}
if (o->readerrs) ast_log(LOG_WARNING,"Nope, USB read channel [%s] wasn't stuck after all.\n",o->name);
o->readerrs = 0;
o->readpos += res;
if (o->readpos < sizeof(o->usbradio_read_buf)) /* not enough samples */
return f;
if (o->mute)
return f;
#if DEBUG_CAPTURES == 1
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)) {
ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
}
#endif
#if 1
if(o->txkeyed||o->txtestkey)
{
if(!o->pmrChan->txPttIn)
{
o->pmrChan->txPttIn=1;
if(o->debuglevel) ast_log(LOG_NOTICE,"txPttIn = %i, chan %s\n",o->pmrChan->txPttIn,o->owner->name);
}
}
else if(o->pmrChan->txPttIn)
{
o->pmrChan->txPttIn=0;
if(o->debuglevel) ast_log(LOG_NOTICE,"txPttIn = %i, chan %s\n",o->pmrChan->txPttIn,o->owner->name);
}
oldpttout = o->pmrChan->txPttOut;
PmrRx( o->pmrChan,
(i16 *)(o->usbradio_read_buf + AST_FRIENDLY_OFFSET),
(i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET),
(i16 *)(o->usbradio_write_buf_1));
if (oldpttout != o->pmrChan->txPttOut)
{
if(o->debuglevel) ast_log(LOG_NOTICE,"txPttOut = %i, chan %s\n",o->pmrChan->txPttOut,o->owner->name);
kickptt(o);
}
#if 0 // to write 48KS/s stereo tx data to a file
if (!ftxoutraw) ftxoutraw = fopen(TX_CAP_OUT_FILE,"w");
if (ftxoutraw) fwrite(o->usbradio_write_buf_1,1,FRAME_SIZE * 2 * 6,ftxoutraw);
#endif
#if DEBUG_CAPTURES == 1 && XPMR_DEBUG0 == 1
if ((o->b.txcap2 && ftxcaptrace) && (fwrite((o->pmrChan->ptxDebug),1,FRAME_SIZE * 2 * 16,ftxcaptrace) != FRAME_SIZE * 2 * 16)) {
ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
}
#endif
// 160 samples * 2 bytes/sample * 2 chan * 6x oversampling to 48KS/s
datalen = FRAME_SIZE * 24;
src = 0; /* read position into f->data */
while (src < datalen)
{
/* Compute spare room in the buffer */
int l = sizeof(o->usbradio_write_buf) - o->usbradio_write_dst;
if (datalen - src >= l)
{
/* enough to fill a frame */
memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
soundcard_writeframe(o, (short *) o->usbradio_write_buf);
src += l;
o->usbradio_write_dst = 0;
}
else
{
/* copy residue */
l = datalen - src;
memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
src += l; /* but really, we are done */
o->usbradio_write_dst += l;
}
}
#else
static FILE *hInput;
i16 iBuff[FRAME_SIZE*2*6];
o->pmrChan->b.rxCapture=1;
if(!hInput)
{
hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm","r");
if(!hInput)
{
printf(" Input Data File Not Found.\n");
return 0;
}
}
if(0==fread((void *)iBuff,2,FRAME_SIZE*2*6,hInput))exit;
PmrRx( o->pmrChan,
(i16 *)iBuff,
(i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
#endif
#if 0
if (!frxoutraw) frxoutraw = fopen(RX_CAP_OUT_FILE,"w");
if (frxoutraw) fwrite((o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET),1,FRAME_SIZE * 2,frxoutraw);
#endif
#if DEBUG_CAPTURES == 1 && XPMR_DEBUG0 == 1
if ((frxcaptrace && o->b.rxcap2 && o->pmrChan->b.radioactive) && (fwrite((o->pmrChan->prxDebug),1,FRAME_SIZE * 2 * 16,frxcaptrace) != FRAME_SIZE * 2 * 16 )) {
ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
}
#endif
cd = 0;
if(o->rxcdtype==CD_HID && (o->pmrChan->rxExtCarrierDetect!=o->rxhidsq))
o->pmrChan->rxExtCarrierDetect=o->rxhidsq;
if(o->rxcdtype==CD_HID_INVERT && (o->pmrChan->rxExtCarrierDetect==o->rxhidsq))
o->pmrChan->rxExtCarrierDetect=!o->rxhidsq;
if( (o->rxcdtype==CD_HID && o->rxhidsq) ||
(o->rxcdtype==CD_HID_INVERT && !o->rxhidsq) ||
(o->rxcdtype==CD_XPMR_NOISE && o->pmrChan->rxCarrierDetect) ||
(o->rxcdtype==CD_XPMR_VOX && o->pmrChan->rxCarrierDetect)
)
{
if (!o->pmrChan->txPttOut || o->radioduplex)cd=1;
}
else
{
cd=0;
}
if(cd!=o->rxcarrierdetect)
{
o->rxcarrierdetect=cd;
if(o->debuglevel) ast_log(LOG_NOTICE,"rxcarrierdetect = %i, chan %s\n",cd,o->owner->name);
// printf("rxcarrierdetect = %i, chan %s\n",res,o->owner->name);
}
if(o->pmrChan->b.ctcssRxEnable && o->pmrChan->rxCtcss->decode!=o->rxctcssdecode)
{
if(o->debuglevel)ast_log(LOG_NOTICE,"rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
// printf("rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
o->rxctcssdecode=o->pmrChan->rxCtcss->decode;
strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
}
#ifndef HAVE_XPMRX
if( !o->pmrChan->b.ctcssRxEnable ||
( o->pmrChan->b.ctcssRxEnable &&
o->pmrChan->rxCtcss->decode>CTCSS_NULL &&
o->pmrChan->smode==SMODE_CTCSS )
)
{
sd=1;
}
else
{
sd=0;
}
#else
if( (!o->pmrChan->b.ctcssRxEnable && !o->pmrChan->b.dcsRxEnable && !o->pmrChan->b.lmrRxEnable) ||
( o->pmrChan->b.ctcssRxEnable &&
o->pmrChan->rxCtcss->decode>CTCSS_NULL &&
o->pmrChan->smode==SMODE_CTCSS ) ||
( o->pmrChan->b.dcsRxEnable &&
o->pmrChan->decDcs->decode > 0 &&
o->pmrChan->smode==SMODE_DCS )
)
{
sd=1;
}
else
{
sd=0;
}
if(o->pmrChan->decDcs->decode!=o->rxdcsdecode)
{
if(o->debuglevel)ast_log(LOG_NOTICE,"rxdcsdecode = %s, chan %s\n",o->pmrChan->rxctcssfreq,o->owner->name);
// printf("rxctcssdecode = %i, chan %s\n",o->pmrChan->rxCtcss->decode,o->owner->name);
o->rxdcsdecode=o->pmrChan->decDcs->decode;
strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
}
if(o->pmrChan->rptnum && (o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed != o->rxlsddecode))
{
if(o->debuglevel)ast_log(LOG_NOTICE,"rxLSDecode = %s, chan %s\n",o->pmrChan->rxctcssfreq,o->owner->name);
o->rxlsddecode=o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed;
strcpy(o->rxctcssfreq, o->pmrChan->rxctcssfreq);
}
if( (o->pmrChan->rptnum>0 && o->pmrChan->smode==SMODE_LSD && o->pmrChan->pLsdCtl->cs[o->pmrChan->rptnum].b.rxkeyed)||
(o->pmrChan->smode==SMODE_DCS && o->pmrChan->decDcs->decode>0) )
{
sd=1;
}
#endif
if ( cd && sd )
{
//if(!o->rxkeyed)o->pmrChan->dd.b.doitnow=1;
if(!o->rxkeyed && o->debuglevel)ast_log(LOG_NOTICE,"o->rxkeyed = 1, chan %s\n", o->owner->name);
o->rxkeyed = 1;
}
else
{
//if(o->rxkeyed)o->pmrChan->dd.b.doitnow=1;
if(o->rxkeyed && o->debuglevel)ast_log(LOG_NOTICE,"o->rxkeyed = 0, chan %s\n",o->owner->name);
o->rxkeyed = 0;
}
// provide rx signal detect conditions
if (o->lastrx && (!o->rxkeyed))
{
o->lastrx = 0;
//printf("AST_CONTROL_RADIO_UNKEY\n");
wf.subclass = AST_CONTROL_RADIO_UNKEY;
ast_queue_frame(o->owner, &wf);
}
else if ((!o->lastrx) && (o->rxkeyed))
{
o->lastrx = 1;
//printf("AST_CONTROL_RADIO_KEY\n");
wf.subclass = AST_CONTROL_RADIO_KEY;
if(o->rxctcssdecode)
{
wf.data.ptr = o->rxctcssfreq;
wf.datalen = strlen(o->rxctcssfreq) + 1;
TRACEO(1,("AST_CONTROL_RADIO_KEY text=%s\n",o->rxctcssfreq));
}
ast_queue_frame(o->owner, &wf);
}
o->readpos = AST_FRIENDLY_OFFSET; /* reset read pointer for next frame */
if (c->_state != AST_STATE_UP) /* drop data if frame is not up */
return f;
/* ok we can build and deliver the frame to the caller */
f->frametype = AST_FRAME_VOICE;
f->subclass = AST_FORMAT_SLINEAR;
f->samples = FRAME_SIZE;
f->datalen = FRAME_SIZE * 2;
f->data.ptr = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
if (o->boost != BOOST_SCALE) { /* scale and clip values */
int i, x;
int16_t *p = (int16_t *) f->data.ptr;
for (i = 0; i < f->samples; i++) {
x = (p[i] * o->boost) / BOOST_SCALE;
if (x > 32767)
x = 32767;
else if (x < -32768)
x = -32768;
p[i] = x;
}
}
f->offset = AST_FRIENDLY_OFFSET;
if (o->dsp)
{
f1 = ast_dsp_process(c,o->dsp,f);
if ((f1->frametype == AST_FRAME_DTMF_END) ||
(f1->frametype == AST_FRAME_DTMF_BEGIN))
{
if ((f1->subclass == 'm') || (f1->subclass == 'u'))
{
f1->frametype = AST_FRAME_NULL;
f1->subclass = 0;
return(f1);
}
if (f1->frametype == AST_FRAME_DTMF_END)
ast_log(LOG_NOTICE,"Got DTMF char %c\n",f1->subclass);
return(f1);
}
}
return f;
}
| static struct ast_channel * usbradio_request | ( | const char * | type, |
| int | format, | ||
| void * | data, | ||
| int * | cause | ||
| ) | [static, read] |
Definition at line 2211 of file chan_usbradio.c.
References AST_CAUSE_BUSY, AST_FORMAT_SLINEAR, ast_log(), AST_STATE_DOWN, chan_usbradio_pvt::b, find_desc(), LOG_NOTICE, LOG_WARNING, chan_usbradio_pvt::owner, chan_usbradio_pvt::remoted, usbradio_new(), and xpmr_config().
{
struct ast_channel *c;
struct chan_usbradio_pvt *o = find_desc(data);
TRACEO(1,("usbradio_request()\n"));
if (0)
{
ast_log(LOG_WARNING, "usbradio_request type <%s> data 0x%p <%s>\n", type, data, (char *) data);
}
if (o == NULL) {
ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
/* XXX we could default to 'dsp' perhaps ? */
return NULL;
}
if ((format & AST_FORMAT_SLINEAR) == 0) {
ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
return NULL;
}
if (o->owner) {
ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
*cause = AST_CAUSE_BUSY;
return NULL;
}
c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
if (c == NULL) {
ast_log(LOG_WARNING, "Unable to create new usb channel\n");
return NULL;
}
o->b.remoted=0;
xpmr_config(o);
return c;
}
| static int usbradio_text | ( | struct ast_channel * | c, |
| const char * | text | ||
| ) | [static] |
Definition at line 1618 of file chan_usbradio.c.
References ast_log(), ast_verbose(), chan_usbradio_pvt::b, chan, chan_usbradio_pvt::debuglevel, find_desc(), LOG_ERROR, LOG_NOTICE, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::remoted, round, chan_usbradio_pvt::set_rxctcssfreqs, chan_usbradio_pvt::set_rxfreq, chan_usbradio_pvt::set_txctcssfreqs, chan_usbradio_pvt::set_txfreq, and xpmr_config().
{
struct chan_usbradio_pvt *o = find_desc(usbradio_active);
double tx,rx;
char cnt,rxs[16],txs[16],txpl[16],rxpl[16];
char pwr,*cmd;
cmd = alloca(strlen(text) + 10);
/* print received messages */
if(o->debuglevel)ast_verbose(" << Console Received usbradio text %s >> \n", text);
cnt = sscanf(text, "%300s %15s %15s %15s %15s %1c", cmd, rxs, txs, rxpl, txpl, &pwr);
if (strcmp(cmd,"SETCHAN")==0)
{
u8 chan;
chan=strtod(rxs,NULL);
ppbinout(chan);
if(o->debuglevel)ast_log(LOG_NOTICE,"parse usbradio SETCHAN cmd: %s chan: %i\n",text,chan);
return 0;
}
if (cnt < 6)
{
ast_log(LOG_ERROR,"Cannot parse usbradio text: %s\n",text);
return 0;
}
else
{
if(o->debuglevel)ast_verbose(" << %s %s %s %s %s %c >> \n", cmd,rxs,txs,rxpl,txpl,pwr);
}
if (strcmp(cmd,"SETFREQ")==0)
{
if(o->debuglevel)ast_log(LOG_NOTICE,"parse usbradio SETFREQ cmd: %s\n",text);
tx=strtod(txs,NULL);
rx=strtod(rxs,NULL);
o->set_txfreq = round(tx * (double)1000000);
o->set_rxfreq = round(rx * (double)1000000);
o->pmrChan->txpower = (pwr == 'H');
strcpy(o->set_rxctcssfreqs,rxpl);
strcpy(o->set_txctcssfreqs,txpl);
o->b.remoted=1;
xpmr_config(o);
return 0;
}
ast_log(LOG_ERROR,"Cannot parse usbradio cmd: %s\n",text);
return 0;
}
| static int usbradio_write | ( | struct ast_channel * | chan, |
| struct ast_frame * | f | ||
| ) | [static] |
Definition at line 1738 of file chan_usbradio.c.
References ast_log(), chan_usbradio_pvt::b, chan_usbradio_pvt::cursound, ast_frame::data, ast_frame::datalen, errno, fwrite, LOG_ERROR, chan_usbradio_pvt::nosound, chan_usbradio_pvt::pmrChan, ast_frame::ptr, ast_channel::tech_pvt, traceusb2, chan_usbradio_pvt::txcapraw, and chan_usbradio_pvt::txkeyed.
{
struct chan_usbradio_pvt *o = c->tech_pvt;
traceusb2(("usbradio_write() o->nosound= %i\n",o->nosound));
#ifndef NEW_ASTERISK
/* Immediately return if no sound is enabled */
if (o->nosound)
return 0;
/* Stop any currently playing sound */
o->cursound = -1;
#endif
/*
* we could receive a block which is not a multiple of our
* FRAME_SIZE, so buffer it locally and write to the device
* in FRAME_SIZE chunks.
* Keep the residue stored for future use.
*/
#if DEBUG_CAPTURES == 1 // to write input data to a file datalen=320
if (ftxcapraw && o->b.txcapraw)
{
i16 i, tbuff[f->datalen];
for(i=0;i<f->datalen;i+=2)
{
tbuff[i]= ((i16*)(f->data.ptr))[i/2];
tbuff[i+1]= o->txkeyed*M_Q13;
}
if (fwrite(tbuff,2,f->datalen,ftxcapraw) != f->datalen) {
ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
}
//fwrite(f->data,1,f->datalen,ftxcapraw);
}
#endif
// maw just take the data from the network and save it for PmrRx processing
PmrTx(o->pmrChan,(i16*)f->data.ptr);
return 0;
}
| static int used_blocks | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 1317 of file chan_usbradio.c.
References ast_log(), LOG_WARNING, chan_usbradio_pvt::sounddev, chan_usbradio_pvt::total_blocks, WARN_used_blocks, and chan_usbradio_pvt::warned.
Referenced by soundcard_writeframe().
{
struct audio_buf_info info;
if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
if (!(o->warned & WARN_used_blocks)) {
ast_log(LOG_WARNING, "Error reading output space\n");
o->warned |= WARN_used_blocks;
}
return 1;
}
if (o->total_blocks == 0) {
if (0) /* debugging */
ast_log(LOG_WARNING, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
o->total_blocks = info.fragments;
}
return o->total_blocks - info.fragments;
}
| static void write_eeprom | ( | struct usb_dev_handle * | handle, |
| int | addr, | ||
| unsigned short | data | ||
| ) | [static] |
Definition at line 835 of file chan_usbradio.c.
References buf, and hid_set_outputs().
Referenced by put_eeprom().
{
unsigned char buf[4];
buf[0] = 0x80;
buf[1] = data & 0xff;
buf[2] = data >> 8;
buf[3] = 0xc0 | (addr & 0x3f);
hid_set_outputs(handle,buf);
}
| static int xpmr_config | ( | struct chan_usbradio_pvt * | o | ) | [static] |
Definition at line 3345 of file chan_usbradio.c.
References ast_log(), chan_usbradio_pvt::b, LOG_ERROR, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::remoted, chan_usbradio_pvt::rxctcssfreqs, chan_usbradio_pvt::rxctcssrelax, chan_usbradio_pvt::rxfreq, chan_usbradio_pvt::set_rxctcssfreqs, chan_usbradio_pvt::set_rxfreq, chan_usbradio_pvt::set_txctcssdefault, chan_usbradio_pvt::set_txctcssfreqs, chan_usbradio_pvt::set_txfreq, chan_usbradio_pvt::txctcssdefault, chan_usbradio_pvt::txctcssfreqs, and chan_usbradio_pvt::txfreq.
Referenced by store_config(), usbradio_request(), and usbradio_text().
{
//ast_log(LOG_NOTICE,"xpmr_config()\n");
TRACEO(1,("xpmr_config()\n"));
if(o->pmrChan==NULL)
{
ast_log(LOG_ERROR,"pmr channel structure NULL\n");
return 1;
}
o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
o->pmrChan->txpower=0;
if(o->b.remoted)
{
o->pmrChan->pTxCodeDefault = o->set_txctcssdefault;
o->pmrChan->pRxCodeSrc=o->set_rxctcssfreqs;
o->pmrChan->pTxCodeSrc=o->set_txctcssfreqs;
o->pmrChan->rxfreq=o->set_rxfreq;
o->pmrChan->txfreq=o->set_txfreq;
/* printf(" remoted %s %s --> %s \n",o->pmrChan->txctcssdefault,
o->pmrChan->txctcssfreq,o->pmrChan->rxctcssfreq); */
}
else
{
// set xpmr pointers to source strings
o->pmrChan->pTxCodeDefault = o->txctcssdefault;
o->pmrChan->pRxCodeSrc = o->rxctcssfreqs;
o->pmrChan->pTxCodeSrc = o->txctcssfreqs;
o->pmrChan->rxfreq = o->rxfreq;
o->pmrChan->txfreq = o->txfreq;
}
code_string_parse(o->pmrChan);
if(o->pmrChan->rxfreq) o->pmrChan->b.reprog=1;
return 0;
}
struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "usb Console Channel Driver" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 4019 of file chan_usbradio.c.
char active_usage[] = "to the device specified.\n" [static] |
Definition at line 2617 of file chan_usbradio.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 4019 of file chan_usbradio.c.
struct ast_cli_entry cli_usbradio[] [static] |
Definition at line 2640 of file chan_usbradio.c.
const char* config = "usbradio.conf" [static] |
Definition at line 356 of file chan_usbradio.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 191 of file chan_usbradio.c.
FILE* frxcapraw = NULL [static] |
Definition at line 359 of file chan_usbradio.c.
| FILE * frxcaptrace = NULL |
Definition at line 359 of file chan_usbradio.c.
| FILE * frxoutraw = NULL |
Definition at line 359 of file chan_usbradio.c.
FILE* ftxcapraw = NULL [static] |
Definition at line 360 of file chan_usbradio.c.
| FILE * ftxcaptrace = NULL |
Definition at line 360 of file chan_usbradio.c.
| FILE * ftxoutraw = NULL |
Definition at line 360 of file chan_usbradio.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 199 of file chan_usbradio.c.
Referenced by load_module(), store_config(), and usbradio_new().
char key_usage[] = " Simulates COR active.\n" [static] |
Definition at line 2609 of file chan_usbradio.c.
char radio_tune_usage[] = "\n All [newsetting]'s are values 0-999\n\n" [static] |
Definition at line 2625 of file chan_usbradio.c.
Definition at line 396 of file chan_usbradio.c.
char tdesc[] = "USB (CM108) Radio Channel Driver" [static] |
Definition at line 682 of file chan_usbradio.c.
char unkey_usage[] = " Simulates COR un-active.\n" [static] |
Definition at line 2613 of file chan_usbradio.c.
char* usb_device_list = NULL [static] |
Definition at line 362 of file chan_usbradio.c.
Referenced by usb_list_check().
int usb_device_list_size = 0 [static] |
Definition at line 363 of file chan_usbradio.c.
char* usbradio_active [static] |
Definition at line 660 of file chan_usbradio.c.
int usbradio_debug [static] |
Definition at line 365 of file chan_usbradio.c.
struct chan_usbradio_pvt usbradio_default [static] |
Definition at line 625 of file chan_usbradio.c.
Referenced by store_config().
struct ast_channel_tech usbradio_tech [static] |
Definition at line 684 of file chan_usbradio.c.
Referenced by usbradio_new().