Thu Apr 28 2011 16:57:07

Asterisk developer's documentation


chan_usbradio.c File Reference

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"
Include dependency graph for chan_usbradio.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_pvtfind_desc (char *dev)
static struct chan_usbradio_pvtfind_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_pvtstore_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_channelusbradio_new (struct chan_usbradio_pvt *o, char *ext, char *ctx, int state)
static struct ast_frameusbradio_read (struct ast_channel *chan)
static struct ast_channelusbradio_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_infoast_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

Detailed Description

Channel driver for CM108 USB Cards with Radio Interface.

Author:
Jim Dixon <jim@lambdatel.com>
Steve Henke <w9sh@arrl.net>
See also
  • Config_usbradio

Definition in file chan_usbradio.c.


Define Documentation

#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().

#define M_F (   tag,
  f 
)    if (!strcasecmp((__s), tag)) { f; } else

Definition at line 295 of file chan_usbradio.c.

Referenced by store_config().

#define M_START (   var,
  val 
)    char *__s = var; char *__val = val;

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 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().


Enumeration Type Documentation

anonymous enum
Enumerator:
RX_AUDIO_NONE 
RX_AUDIO_SPEAKER 
RX_AUDIO_FLAT 

Definition at line 370 of file chan_usbradio.c.

anonymous enum
Enumerator:
CD_IGNORE 
CD_XPMR_NOISE 
CD_XPMR_VOX 
CD_HID 
CD_HID_INVERT 

Definition at line 371 of file chan_usbradio.c.

anonymous enum
Enumerator:
SD_IGNORE 
SD_HID 
SD_HID_INVERT 
SD_XPMR 

Definition at line 372 of file chan_usbradio.c.

{SD_IGNORE,SD_HID,SD_HID_INVERT,SD_XPMR};                 // no,external,externalinvert,software
anonymous enum
Enumerator:
RX_KEY_CARRIER 
RX_KEY_CARRIER_CODE 

Definition at line 373 of file chan_usbradio.c.

anonymous enum
Enumerator:
TX_OUT_OFF 
TX_OUT_VOICE 
TX_OUT_LSD 
TX_OUT_COMPOSITE 
TX_OUT_AUX 

Definition at line 374 of file chan_usbradio.c.

anonymous enum
Enumerator:
TOC_NONE 
TOC_PHASE 
TOC_NOTONE 

Definition at line 375 of file chan_usbradio.c.


Function Documentation

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.

References id, str, and type.

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().

{
   char c = 0;
   //printf("kickptt  %i  %i  %i\n",o->txkeyed,o->txchankey,o->txtestkey);
   if (!o) return;
   if (!o->pttkick) return;
   if (write(o->pttkick[1],&c,1) < 0) {
      ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno));
   }
}
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 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().

{

   if(o->pmrChan->spsTxOutA) {
      o->pmrChan->spsTxOutA->outputGain = 
         mult_calc((o->txmixaset * 152) / 1000);
   }
   if(o->pmrChan->spsTxOutB){
      o->pmrChan->spsTxOutB->outputGain = 
         mult_calc((o->txmixbset * 152) / 1000);
   }
}
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.

References id, str, and type.

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().

{
   float f;
   sscanf(s, "%30f", &f); 
   o->rxgain = f;
   //ast_log(LOG_WARNING, "set rxgain = %f\n", f);
}
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]
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;
}

Variable Documentation

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.

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.

struct sound sounds[] [static]

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.

Definition at line 625 of file chan_usbradio.c.

Referenced by store_config().

Definition at line 684 of file chan_usbradio.c.

Referenced by usbradio_new().