Wed Oct 28 11:46:05 2009

Asterisk developer's documentation


chan_usbradio.c File Reference

Channel driver for CM108 USB Cards with Radio Interface. More...

#include "asterisk.h"
#include <ctype.h>
#include <math.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/time.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/callerid.h"
#include "asterisk/channel.h"
#include "asterisk/module.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 "./xpmr/xpmr.c"

Include dependency graph for chan_usbradio.c:

Go to the source code of this file.

Data Structures

struct  chan_usbradio_pvt

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 DEBUG_CAP_RX_OUT   0
#define DEBUG_CAP_TX_OUT   0
#define DEBUG_CAPTURES   1
#define DEBUG_FILETEST   0
#define DEBUG_USBRADIO   0
#define DEV_DSP   "/dev/dsp"
#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 MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MIN(a, b)   ((a) < (b) ? (a) : (b))
#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 O_CLOSE   0x444
#define pd(x)   ast_debug(4, #x" = %d\n", x)
#define pf(x)   ast_debug(4, #x" = %f\n", x)
#define pp(x)   ast_debug(4, #x" = %p\n", x)
#define ps(x)   ast_debug(4, #x" = %s\n", x)
#define QUEUE_SIZE   20
#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 struct chan_usbradio_pvtfind_desc (char *dev)
 returns a pointer to the descriptor with the given name
static char * handle_cli_radio_key (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_radio_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_radio_set_debug_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_radio_tune (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_radio_unkey (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct usb_device * hid_device_init (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 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 int set_txctcss_level (struct chan_usbradio_pvt *o)
static int setamixer (int devnum, char *param, int v1, int v2)
 Call with: devnum: alsa major device number, param: ascii Formal Parameter Name, val1, first or only value, val2 second value, or 0 if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.
static int setformat (struct chan_usbradio_pvt *o, int mode)
static int soundcard_writeframe (struct chan_usbradio_pvt *o, short *data)
 Write an exactly FRAME_SIZE sized frame.
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_rxctcssfreq (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_txctcssfreq (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 (struct chan_usbradio_pvt *o)
static void tune_rxinput (struct chan_usbradio_pvt *o)
static void tune_rxvoice (struct chan_usbradio_pvt *o)
static void tune_txoutput (struct chan_usbradio_pvt *o, int value)
static void tune_write (struct chan_usbradio_pvt *o)
static int unload_module (void)
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)
 split a string in extension-context, returns pointers to malloc'ed strings. If we do not have 'overridecontext' then the last @ is considered as a context separator, and the context is overridden. This is usually not very necessary as you can play with the dialplan, and it is nice not to need it because you have '@' in SIP addresses. Return value is the buffer address.

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "usb Console Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static const struct
ast_module_info
ast_module_info = &__mod_info
static struct ast_cli_entry cli_radio_set_debug_deprecated = AST_CLI_DEFINE(handle_cli_radio_set_debug_deprecated, "Enable/Disable Radio Debugging")
static struct ast_cli_entry cli_usbradio []
static const char * config = "usbradio.conf"
static const char * config1 = "usbradio_tune.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 tdesc [] = "USB (CM108) Radio Channel Driver"
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 318 of file chan_usbradio.c.

#define BOOST_SCALE   (1<<9)

Definition at line 317 of file chan_usbradio.c.

#define C108_HID_INTERFACE   3

Definition at line 119 of file chan_usbradio.c.

Referenced by hid_get_inputs(), hid_set_outputs(), and hidthread().

#define C108_PRODUCT_ID   0x000c

Definition at line 118 of file chan_usbradio.c.

Referenced by hid_device_init().

#define C108_VENDOR_ID   0x0d8c

Definition at line 117 of file chan_usbradio.c.

Referenced by hid_device_init().

#define CHAN_USBRADIO   1

Definition at line 53 of file chan_usbradio.c.

#define DEBUG_CAP_RX_OUT   0

Definition at line 58 of file chan_usbradio.c.

#define DEBUG_CAP_TX_OUT   0

Definition at line 59 of file chan_usbradio.c.

#define DEBUG_CAPTURES   1

Definition at line 56 of file chan_usbradio.c.

#define DEBUG_FILETEST   0

Definition at line 61 of file chan_usbradio.c.

#define DEBUG_USBRADIO   0

Definition at line 55 of file chan_usbradio.c.

#define DEV_DSP   "/dev/dsp"

Definition at line 252 of file chan_usbradio.c.

#define FRAGS   ( ( (6 * 5) << 16 ) | 0xc )

Definition at line 235 of file chan_usbradio.c.

#define FRAME_SIZE   160

usbradio.conf parameters are START_CONFIG

[general] ; General config options, with default values shown. ; You should use one section per device, with [general] being used ; for the device. ; ; ; debug = 0x0 ; misc debug flags, default is 0

; Set the device to use for I/O ; devicenum = 0 ; Set hardware type here ; hdwtype=0 ; 0=limey, 1=sph

; rxboostset=0 ; no rx gain boost ; rxctcssrelax=1 ; reduce talkoff from radios w/o CTCSS Tx HPF ; rxctcssfreq=100.0 ; rx ctcss freq in floating point. must be in table ; txctcssfreq=100.0 ; tx ctcss freq, any frequency permitted

; carrierfrom=dsp ;no,usb,usbinvert,dsp,vox ; ctcssfrom=dsp ;no,usb,dsp

; rxdemod=flat ; input type from radio: no,speaker,flat ; txprelim=yes ; output is pre-emphasised and limited ; txtoctype=no ; no,phase,notone

; txmixa=composite ;no,voice,tone,composite,auxvoice ; txmixb=no ;no,voice,tone,composite,auxvoice

; invertptt=0

;------------------------------ JITTER BUFFER CONFIGURATION -------------------------- ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an ; USBRADIO channel. Defaults to "no". An enabled jitterbuffer will ; be used only if the sending side can create and the receiving ; side can not accept jitter. The USBRADIO channel can't accept jitter, ; thus an enabled jitterbuffer on the receive USBRADIO side will always ; be used if the sending side can create jitter.

; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.

; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is ; resynchronized. Useful to improve the quality of the voice, with ; big jumps in/broken timestamps, usualy sent from exotic devices ; and programs. Defaults to 1000.

; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of an USBRADIO ; channel. Two implementations are currenlty available - "fixed" ; (with size always equals to jbmax-size) and "adaptive" (with ; variable size, actually the new jb of IAX2). Defaults to fixed.

; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no". ;-----------------------------------------------------------------------------------

END_CONFIG

The following parameters are used in the driver:

FRAME_SIZE the size of an audio frame, in samples. 160 is used almost universally, so you should not change it.

FRAGS the argument for the SETFRAGMENT ioctl. Overridden by the 'frags' parameter in usbradio.conf

Bits 0-7 are the base-2 log of the device's block size, bits 16-31 are the number of blocks in the driver's queue. There are a lot of differences in the way this parameter is supported by different drivers, so you may need to experiment a bit with the value. A good default for linux is 30 blocks of 64 bytes, which results in 6 frames of 320 bytes (160 samples). FreeBSD works decently with blocks of 256 or 512 bytes, leaving the number unspecified. Note that this only refers to the device buffer size, this module will then try to keep the lenght of audio buffered within small constraints.

QUEUE_SIZE The max number of blocks actually allowed in the device driver's buffer, irrespective of the available number. Overridden by the 'queuesize' parameter in usbradio.conf

Should be >=2, and at most as large as the hw queue above (otherwise it will never be full).

Definition at line 229 of file chan_usbradio.c.

#define HID_REPORT_GET   0x01

Definition at line 121 of file chan_usbradio.c.

Referenced by hid_get_inputs().

#define HID_REPORT_SET   0x09

Definition at line 122 of file chan_usbradio.c.

Referenced by hid_set_outputs().

#define HID_RT_INPUT   0x01

Definition at line 124 of file chan_usbradio.c.

Referenced by hid_get_inputs().

#define HID_RT_OUTPUT   0x02

Definition at line 125 of file chan_usbradio.c.

Referenced by hid_set_outputs().

#define MAX ( a,
 )     ((a) > (b) ? (a) : (b))

Definition at line 259 of file chan_usbradio.c.

#define MIN ( a,
 )     ((a) < (b) ? (a) : (b))

Definition at line 256 of file chan_usbradio.c.

#define MIXER_PARAM_MIC_BOOST   "Auto Gain Control"

Definition at line 75 of file chan_usbradio.c.

Referenced by mixer_write(), and tune_rxinput().

#define MIXER_PARAM_MIC_CAPTURE_SW   "Mic Capture Switch"

Definition at line 73 of file chan_usbradio.c.

Referenced by mixer_write().

#define MIXER_PARAM_MIC_CAPTURE_VOL   "Mic Capture Volume"

Definition at line 74 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 71 of file chan_usbradio.c.

Referenced by mixer_write().

#define MIXER_PARAM_MIC_PLAYBACK_VOL   "Mic Playback Volume"

Definition at line 72 of file chan_usbradio.c.

Referenced by mixer_write().

#define MIXER_PARAM_SPKR_PLAYBACK_SW   "Speaker Playback Switch"

Definition at line 76 of file chan_usbradio.c.

Referenced by mixer_write().

#define MIXER_PARAM_SPKR_PLAYBACK_VOL   "Speaker Playback Volume"

Definition at line 77 of file chan_usbradio.c.

Referenced by mixer_write(), and store_config().

#define O_CLOSE   0x444

Definition at line 247 of file chan_usbradio.c.

#define pd (  )     ast_debug(4, #x" = %d\n", x)

Definition at line 2129 of file chan_usbradio.c.

Referenced by pcm_write(), playtones_alloc(), and pmrdump().

#define pf (  )     ast_debug(4, #x" = %f\n", x)

Definition at line 2132 of file chan_usbradio.c.

Referenced by pmrdump().

#define pp (  )     ast_debug(4, #x" = %p\n", x)

#define ps (  )     ast_debug(4, #x" = %s\n", x)

#define QUEUE_SIZE   20

Definition at line 230 of file chan_usbradio.c.

#define RX_CAP_OUT_FILE   "/tmp/rx_cap_out.pcm"

Definition at line 65 of file chan_usbradio.c.

Referenced by usbradio_read().

#define RX_CAP_RAW_FILE   "/tmp/rx_cap_in.pcm"

Definition at line 63 of file chan_usbradio.c.

Referenced by handle_cli_radio_tune().

#define RX_CAP_TRACE_FILE   "/tmp/rx_trace.pcm"

Definition at line 64 of file chan_usbradio.c.

Referenced by handle_cli_radio_tune().

#define TEXT_SIZE   256

Definition at line 242 of file chan_usbradio.c.

#define traceusb1 ( a,
...   ) 

Definition at line 84 of file chan_usbradio.c.

Referenced by hidthread(), and store_config().

#define traceusb2 ( a,
...   ) 

Definition at line 90 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 69 of file chan_usbradio.c.

Referenced by usbradio_write().

#define TX_CAP_RAW_FILE   "/tmp/tx_cap_in.pcm"

Definition at line 67 of file chan_usbradio.c.

Referenced by handle_cli_radio_tune().

#define TX_CAP_TRACE_FILE   "/tmp/tx_trace.pcm"

Definition at line 68 of file chan_usbradio.c.

Referenced by handle_cli_radio_tune().

#define WARN_frag   4

Definition at line 307 of file chan_usbradio.c.

#define WARN_speed   2

Definition at line 306 of file chan_usbradio.c.

#define WARN_used_blocks   1

Definition at line 305 of file chan_usbradio.c.


Enumeration Type Documentation

anonymous enum

Enumerator:
RX_AUDIO_NONE 
RX_AUDIO_SPEAKER 
RX_AUDIO_FLAT 

Definition at line 273 of file chan_usbradio.c.

anonymous enum

Enumerator:
CD_IGNORE 
CD_XPMR_NOISE 
CD_XPMR_VOX 
CD_HID 
CD_HID_INVERT 

Definition at line 274 of file chan_usbradio.c.

anonymous enum

Enumerator:
SD_IGNORE 
SD_HID 
SD_HID_INVERT 
SD_XPMR 

Definition at line 275 of file chan_usbradio.c.

00275 {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 276 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 277 of file chan_usbradio.c.

anonymous enum

Enumerator:
TOC_NONE 
TOC_PHASE 
TOC_NOTONE 

Definition at line 278 of file chan_usbradio.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 2529 of file chan_usbradio.c.

static void __unreg_module ( void   )  [static]

Definition at line 2529 of file chan_usbradio.c.

static int amixer_max ( int  devnum,
char *  param 
) [static]

Definition at line 495 of file chan_usbradio.c.

References id, str, and type.

Referenced by store_config().

00496 {
00497    int   rv,type;
00498    char str[15];
00499    snd_hctl_t *hctl;
00500    snd_ctl_elem_id_t *id;
00501    snd_hctl_elem_t *elem;
00502    snd_ctl_elem_info_t *info;
00503 
00504    snprintf(str, sizeof(str), "hw:%d", devnum);
00505    if (snd_hctl_open(&hctl, str, 0))
00506       return -1;
00507    snd_hctl_load(hctl);
00508    id = alloca(snd_ctl_elem_id_sizeof());
00509    memset(id, 0, snd_ctl_elem_id_sizeof());
00510    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
00511    snd_ctl_elem_id_set_name(id, param);  
00512    elem = snd_hctl_find_elem(hctl, id);
00513    if (!elem) {
00514       snd_hctl_close(hctl);
00515       return -1;
00516    }
00517    info = alloca(snd_ctl_elem_info_sizeof());
00518    memset(info, 0, snd_ctl_elem_info_sizeof());
00519    snd_hctl_elem_info(elem,info);
00520    type = snd_ctl_elem_info_get_type(info);
00521    rv = 0;
00522    switch (type) {
00523    case SND_CTL_ELEM_TYPE_INTEGER:
00524       rv = snd_ctl_elem_info_get_max(info);
00525       break;
00526    case SND_CTL_ELEM_TYPE_BOOLEAN:
00527       rv = 1;
00528       break;
00529    }
00530    snd_hctl_close(hctl);
00531    return(rv);
00532 }

static struct chan_usbradio_pvt* find_desc ( char *  dev  )  [static, read]

returns a pointer to the descriptor with the given name

Definition at line 735 of file chan_usbradio.c.

References ast_log(), LOG_WARNING, chan_usbradio_pvt::name, and chan_usbradio_pvt::next.

00736 {
00737    struct chan_usbradio_pvt *o = NULL;
00738 
00739    if (!dev)
00740       ast_log(LOG_WARNING, "null dev\n");
00741 
00742    for (o = usbradio_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
00743 
00744    if (!o)
00745       ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
00746 
00747    return o;
00748 }

static char* handle_cli_radio_key ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1355 of file chan_usbradio.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, find_desc(), chan_usbradio_pvt::txtestkey, and ast_cli_entry::usage.

01356 {
01357    struct chan_usbradio_pvt *o = NULL;
01358 
01359    switch (cmd) {
01360    case CLI_INIT:
01361       e->command = "radio key";
01362       e->usage =
01363          "Usage: radio key\n"
01364          "       Simulates COR active.\n";
01365       return NULL;
01366    case CLI_GENERATE:
01367       return NULL;
01368    }
01369 
01370    if (a->argc != 2)
01371       return CLI_SHOWUSAGE;
01372 
01373    o = find_desc(usbradio_active);
01374    o->txtestkey = 1;
01375 
01376    return CLI_SUCCESS;
01377 }

static char* handle_cli_radio_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1661 of file chan_usbradio.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, chan_usbradio_pvt::debuglevel, ast_cli_args::fd, find_desc(), and ast_cli_entry::usage.

01662 {
01663    struct chan_usbradio_pvt *o = NULL;
01664 
01665    switch (cmd) {
01666    case CLI_INIT:
01667       e->command = "radio set debug {on|off}";
01668       e->usage =
01669          "Usage: radio set debug {on|off}\n"
01670          "       Enable/Disable radio debugging.\n";
01671    case CLI_GENERATE:
01672       return NULL;
01673    }
01674 
01675    if (a->argc != e->args)
01676       return CLI_SHOWUSAGE;
01677 
01678    o = find_desc(usbradio_active);
01679 
01680    if (!strncasecmp(a->argv[e->args - 1], "on", 2))
01681       o->debuglevel = 1;
01682    else if (!strncasecmp(a->argv[e->args - 1], "off", 3))
01683       o->debuglevel = 0;
01684    else
01685       return CLI_SHOWUSAGE;
01686 
01687    ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
01688 
01689    return CLI_SUCCESS;
01690 }

static char* handle_cli_radio_set_debug_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1631 of file chan_usbradio.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, chan_usbradio_pvt::debuglevel, ast_cli_args::fd, find_desc(), and ast_cli_entry::usage.

01632 {
01633    struct chan_usbradio_pvt *o = NULL;
01634 
01635    switch (cmd) {
01636    case CLI_INIT:
01637       e->command = "radio set debug [off]";
01638       e->usage =
01639          "Usage: radio set debug [off]\n"
01640          "       Enable/Disable radio debugging.\n";
01641    case CLI_GENERATE:
01642       return NULL;
01643    }
01644    if (a->argc < 3 || a->argc > 4)
01645       return CLI_SHOWUSAGE;
01646    if (a->argc == 4 && strncasecmp(a->argv[3], "off", 3))
01647       return CLI_SHOWUSAGE;
01648 
01649    o = find_desc(usbradio_active);
01650 
01651    if (a->argc == 3)
01652       o->debuglevel = 1;
01653    else
01654       o->debuglevel = 0;
01655 
01656    ast_cli(a->fd, "USB Radio debugging %s.\n", o->debuglevel ? "enabled" : "disabled");
01657 
01658    return CLI_SUCCESS;
01659 }

static char* handle_cli_radio_tune ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1403 of file chan_usbradio.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_log(), chan_usbradio_pvt::b, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, find_desc(), LOG_ERROR, LOG_WARNING, mixer_write(), mult_set(), chan_usbradio_pvt::pmrChan, pmrdump(), 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, chan_usbradio_pvt::txtestkey, and ast_cli_entry::usage.

01404 {
01405    struct chan_usbradio_pvt *o = NULL;
01406    int i = 0;
01407 
01408    switch (cmd) {
01409    case CLI_INIT:
01410       e->command = "radio tune [rxnoise|rxvoice|rxtone|rxsquelch|rxcap|rxtracecap|"
01411          "txvoice|txtone|txcap|txtracecap|auxvoice|nocap|dump|save]";
01412       /* radio tune 6 3000        measured tx value */
01413       e->usage =
01414          "Usage: radio tune <function>\n"
01415          "       rxnoise\n"
01416          "       rxvoice\n"
01417          "       rxtone\n"
01418          "       rxsquelch [newsetting]\n"
01419          "       rxcap\n"
01420          "       rxtracecap\n"
01421          "       txvoice [newsetting]\n"
01422          "       txtone [newsetting]\n"
01423          "       txcap\n"
01424          "       txtracecap\n"
01425          "       auxvoice [newsetting]\n"
01426          "       nocap\n"
01427          "       dump\n"
01428          "       save (settings to tuning file)\n"
01429          "\n"
01430          "       All [newsetting]s are values 0-999\n";
01431       return NULL;
01432    case CLI_GENERATE:
01433       return NULL;
01434    }
01435 
01436    if ((a->argc < 2) || (a->argc > 4))
01437       return CLI_SHOWUSAGE; 
01438 
01439    if (a->argc == 2) { /* just show stuff */
01440       ast_cli(a->fd, "Output A is currently set to %s.\n",
01441          o->txmixa == TX_OUT_COMPOSITE ? "composite" :
01442          o->txmixa == TX_OUT_VOICE ? "voice" :
01443          o->txmixa == TX_OUT_LSD ? "tone" :
01444          o->txmixa == TX_OUT_AUX ? "auxvoice" :
01445          "off");
01446 
01447       ast_cli(a->fd, "Output B is currently set to %s.\n",
01448          o->txmixb == TX_OUT_COMPOSITE ? "composite" :
01449          o->txmixb == TX_OUT_VOICE ? "voice" :
01450          o->txmixb == TX_OUT_LSD ? "tone" :
01451          o->txmixb == TX_OUT_AUX ? "auxvoice" :
01452          "off");
01453 
01454       ast_cli(a->fd, "Tx Voice Level currently set to %d\n", o->txmixaset);
01455       ast_cli(a->fd, "Tx Tone Level currently set to %d\n", o->txctcssadj);
01456       ast_cli(a->fd, "Rx Squelch currently set to %d\n", o->rxsquelchadj);
01457       return CLI_SHOWUSAGE;
01458    }
01459 
01460    o = find_desc(usbradio_active);
01461 
01462    if (!strcasecmp(a->argv[2], "rxnoise"))
01463       tune_rxinput(o);
01464    else if (!strcasecmp(a->argv[2], "rxvoice"))
01465       tune_rxvoice(o);
01466    else if (!strcasecmp(a->argv[2], "rxtone"))
01467       tune_rxctcss(o);
01468    else if (!strcasecmp(a->argv[2], "rxsquelch")) {
01469       if (a->argc == 3) {
01470           ast_cli(a->fd, "Current Signal Strength is %d\n", ((32767 - o->pmrChan->rxRssi) * 1000 / 32767));
01471           ast_cli(a->fd, "Current Squelch setting is %d\n", o->rxsquelchadj);
01472 #if 0
01473          ast_cli(a->fd,"Current Raw RSSI        is %d\n",o->pmrChan->rxRssi);
01474           ast_cli(a->fd,"Current (real) Squelch setting is %d\n",*(o->pmrChan->prxSquelchAdjust));
01475 #endif
01476       } else {
01477          i = atoi(a->argv[3]);
01478          if ((i < 0) || (i > 999))
01479             return CLI_SHOWUSAGE;
01480          ast_cli(a->fd, "Changed Squelch setting to %d\n", i);
01481          o->rxsquelchadj = i;
01482          *(o->pmrChan->prxSquelchAdjust) = ((999 - i) * 32767) / 1000;
01483       }
01484    } else if (!strcasecmp(a->argv[2], "txvoice")) {
01485       i = 0;
01486 
01487       if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
01488          (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE)) {
01489          ast_log(LOG_ERROR, "No txvoice output configured.\n");
01490       } else if (a->argc == 3) {
01491          if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE))
01492             ast_cli(a->fd, "Current txvoice setting on Channel A is %d\n", o->txmixaset);
01493          else
01494             ast_cli(a->fd, "Current txvoice setting on Channel B is %d\n", o->txmixbset);
01495       } else {
01496          i = atoi(a->argv[3]);
01497          if ((i < 0) || (i > 999))
01498             return CLI_SHOWUSAGE;
01499 
01500          if ((o->txmixa == TX_OUT_VOICE) || (o->txmixa == TX_OUT_COMPOSITE)) {
01501             o->txmixaset = i;
01502             ast_cli(a->fd, "Changed txvoice setting on Channel A to %d\n", o->txmixaset);
01503          } else {
01504             o->txmixbset = i;   
01505             ast_cli(a->fd, "Changed txvoice setting on Channel B to %d\n", o->txmixbset);
01506          }
01507          mixer_write(o);
01508          mult_set(o);
01509          ast_cli(a->fd, "Changed Tx Voice Output setting to %d\n", i);
01510       }
01511       tune_txoutput(o,i);
01512    } else if (!strcasecmp(a->argv[2], "auxvoice")) {
01513       i = 0;
01514       if ( (o->txmixa != TX_OUT_AUX) && (o->txmixb != TX_OUT_AUX))
01515          ast_log(LOG_WARNING, "No auxvoice output configured.\n");
01516       else if (a->argc == 3) {
01517          if (o->txmixa == TX_OUT_AUX)
01518             ast_cli(a->fd, "Current auxvoice setting on Channel A is %d\n", o->txmixaset);
01519          else
01520             ast_cli(a->fd, "Current auxvoice setting on Channel B is %d\n", o->txmixbset);
01521       } else {
01522          i = atoi(a->argv[3]);
01523          if ((i < 0) || (i > 999))
01524             return CLI_SHOWUSAGE;
01525          if (o->txmixa == TX_OUT_AUX) {
01526             o->txmixbset = i;
01527             ast_cli(a->fd, "Changed auxvoice setting on Channel A to %d\n", o->txmixaset);
01528          } else {
01529             o->txmixbset = i;
01530             ast_cli(a->fd, "Changed auxvoice setting on Channel B to %d\n", o->txmixbset);
01531          }
01532          mixer_write(o);
01533          mult_set(o);
01534       }
01535       /* tune_auxoutput(o,i); */
01536    } else if (!strcasecmp(a->argv[2], "txtone")) {
01537       if (a->argc == 3)
01538          ast_cli(a->fd, "Current Tx CTCSS modulation setting = %d\n", o->txctcssadj);
01539       else {
01540          i = atoi(a->argv[3]);
01541          if ((i < 0) || (i > 999))
01542             return CLI_SHOWUSAGE;
01543          o->txctcssadj = i;
01544          set_txctcss_level(o);
01545          ast_cli(a->fd, "Changed Tx CTCSS modulation setting to %i\n", i);
01546       }
01547       o->txtestkey = 1;
01548       usleep(5000000);
01549       o->txtestkey = 0;
01550    } else if (!strcasecmp(a->argv[2],"dump"))
01551       pmrdump(o);
01552    else if (!strcasecmp(a->argv[2],"nocap")) {
01553       ast_cli(a->fd, "File capture (trace) was rx=%d tx=%d and now off.\n", o->b.rxcap2, o->b.txcap2);
01554       ast_cli(a->fd, "File capture (raw)   was rx=%d tx=%d and now off.\n", o->b.rxcapraw, o->b.txcapraw);
01555       o->b.rxcapraw = o->b.txcapraw = o->b.rxcap2 = o->b.txcap2 = o->pmrChan->b.rxCapture = o->pmrChan->b.txCapture = 0;
01556       if (frxcapraw) {
01557          fclose(frxcapraw);
01558          frxcapraw = NULL;
01559       }
01560       if (frxcaptrace) {
01561          fclose(frxcaptrace);
01562          frxcaptrace = NULL;
01563       }
01564       if (frxoutraw) {
01565          fclose(frxoutraw);
01566          frxoutraw = NULL;
01567       }
01568       if (ftxcapraw) {
01569          fclose(ftxcapraw);
01570          ftxcapraw = NULL;
01571       }
01572       if (ftxcaptrace) {
01573          fclose(ftxcaptrace);
01574          ftxcaptrace = NULL;
01575       }
01576       if (ftxoutraw) {
01577          fclose(ftxoutraw);
01578          ftxoutraw = NULL;
01579       }
01580    } else if (!strcasecmp(a->argv[2], "rxtracecap")) {
01581       if (!frxcaptrace)
01582          frxcaptrace = fopen(RX_CAP_TRACE_FILE, "w");
01583       ast_cli(a->fd, "Trace rx on.\n");
01584       o->b.rxcap2 = o->pmrChan->b.rxCapture = 1;
01585    } else if (!strcasecmp(a->argv[2], "txtracecap")) {
01586       if (!ftxcaptrace)
01587          ftxcaptrace = fopen(TX_CAP_TRACE_FILE, "w");
01588       ast_cli(a->fd, "Trace tx on.\n");
01589       o->b.txcap2 = o->pmrChan->b.txCapture = 1;
01590    } else if (!strcasecmp(a->argv[2], "rxcap")) {
01591       if (!frxcapraw)
01592          frxcapraw = fopen(RX_CAP_RAW_FILE, "w");
01593       ast_cli(a->fd, "cap rx raw on.\n");
01594       o->b.rxcapraw = 1;
01595    } else if (!strcasecmp(a->argv[2], "txcap")) {
01596       if (!ftxcapraw)
01597          ftxcapraw = fopen(TX_CAP_RAW_FILE, "w");
01598       ast_cli(a->fd, "cap tx raw on.\n");
01599       o->b.txcapraw = 1;
01600    } else if (!strcasecmp(a->argv[2], "save")) {
01601       tune_write(o);
01602       ast_cli(a->fd, "Saved radio tuning settings to usbradio_tune.conf\n");
01603    } else
01604       return CLI_SHOWUSAGE;
01605    return CLI_SUCCESS;
01606 }

static char* handle_cli_radio_unkey ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1379 of file chan_usbradio.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, find_desc(), chan_usbradio_pvt::txtestkey, and ast_cli_entry::usage.

01380 {
01381    struct chan_usbradio_pvt *o = NULL;
01382 
01383    switch (cmd) {
01384    case CLI_INIT:
01385       e->command = "radio unkey";
01386       e->usage =
01387          "Usage: radio unkey\n"
01388          "       Simulates COR un-active.\n";
01389       return NULL;
01390    case CLI_GENERATE:
01391       return NULL;
01392    }
01393 
01394    if (a->argc != 2)
01395       return CLI_SHOWUSAGE;
01396 
01397    o = find_desc(usbradio_active);
01398    o->txtestkey = 0;
01399 
01400    return CLI_SUCCESS;
01401 }

static struct usb_device* hid_device_init ( void   )  [static, read]

Definition at line 609 of file chan_usbradio.c.

References C108_PRODUCT_ID, and C108_VENDOR_ID.

Referenced by hidthread().

00610 {
00611    struct usb_bus *usb_bus;
00612    struct usb_device *dev;
00613 
00614    usb_init();
00615    usb_find_busses();
00616    usb_find_devices();
00617    for (usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next) {
00618       for (dev = usb_bus->devices; dev; dev = dev->next) {
00619          if ((dev->descriptor.idVendor == C108_VENDOR_ID) && (dev->descriptor.idProduct == C108_PRODUCT_ID))
00620             return dev;
00621       }
00622    }
00623    return NULL;
00624 }

static void hid_get_inputs ( struct usb_dev_handle *  handle,
unsigned char *  inputs 
) [static]

Definition at line 598 of file chan_usbradio.c.

References C108_HID_INTERFACE, HID_REPORT_GET, and HID_RT_INPUT.

Referenced by hidthread().

00600 {
00601    usb_control_msg(handle,
00602       USB_ENDPOINT_IN + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00603       HID_REPORT_GET,
00604       0 + (HID_RT_INPUT << 8),
00605       C108_HID_INTERFACE,
00606       (char *)inputs, 4, 5000);
00607 }

static void hid_set_outputs ( struct usb_dev_handle *  handle,
unsigned char *  outputs 
) [static]

Definition at line 587 of file chan_usbradio.c.

References C108_HID_INTERFACE, HID_REPORT_SET, and HID_RT_OUTPUT.

Referenced by hidthread().

00589 {
00590    usb_control_msg(handle,
00591       USB_ENDPOINT_OUT + USB_TYPE_CLASS + USB_RECIP_INTERFACE,
00592       HID_REPORT_SET,
00593       0 + (HID_RT_OUTPUT << 8),
00594       C108_HID_INTERFACE,
00595       (char *)outputs, 4, 5000);
00596 }

static int hidhdwconfig ( struct chan_usbradio_pvt o  )  [static]

Definition at line 626 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().

00627 {
00628    if (o->hdwtype == 1) {         /*sphusb */
00629       o->hid_gpio_ctl     =  0x08; /* set GPIO4 to output mode */
00630       o->hid_gpio_ctl_loc =  2;    /* For CTL of GPIO */
00631       o->hid_io_cor       =  4;    /* GPIO3 is COR */
00632       o->hid_io_cor_loc   =  1;    /* GPIO3 is COR */
00633       o->hid_io_ctcss     =  2;    /* GPIO 2 is External CTCSS */
00634       o->hid_io_ctcss_loc =  1;    /* is GPIO 2 */
00635       o->hid_io_ptt       =  8;    /* GPIO 4 is PTT */
00636       o->hid_gpio_loc     =  1;    /* For ALL GPIO */
00637    } else if (o->hdwtype == 0) {  /* dudeusb */
00638       o->hid_gpio_ctl     =  0x0c;/* set GPIO 3 & 4 to output mode */
00639       o->hid_gpio_ctl_loc =  2;    /* For CTL of GPIO */
00640       o->hid_io_cor       =  2;    /* VOLD DN is COR */
00641       o->hid_io_cor_loc   =  0;    /* VOL DN COR */
00642       o->hid_io_ctcss     =  2;    /* GPIO 2 is External CTCSS */
00643       o->hid_io_ctcss_loc =  1;    /* is GPIO 2 */
00644       o->hid_io_ptt       =  4;    /* GPIO 3 is PTT */
00645       o->hid_gpio_loc     =  1;    /* For ALL GPIO */
00646    } else if (o->hdwtype == 3) {  /* custom version */
00647       o->hid_gpio_ctl     =  0x0c; /* set GPIO 3 & 4 to output mode */
00648       o->hid_gpio_ctl_loc =  2;    /* For CTL of GPIO */
00649       o->hid_io_cor       =  2;    /* VOLD DN is COR */
00650       o->hid_io_cor_loc   =  0;    /* VOL DN COR */
00651       o->hid_io_ctcss     =  2;    /* GPIO 2 is External CTCSS */
00652       o->hid_io_ctcss_loc =  1;    /* is GPIO 2 */
00653       o->hid_io_ptt       =  4;    /* GPIO 3 is PTT */
00654       o->hid_gpio_loc     =  1;    /* For ALL GPIO */
00655    }
00656 
00657    return 0;
00658 }

static void* hidthread ( void *  arg  )  [static]

Definition at line 661 of file chan_usbradio.c.

References ast_log(), buf, C108_HID_INTERFACE, chan_usbradio_pvt::debuglevel, 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, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::rxhidsq, chan_usbradio_pvt::stophid, traceusb1, chan_usbradio_pvt::txchankey, chan_usbradio_pvt::txkeyed, and chan_usbradio_pvt::txtestkey.

Referenced by usbradio_call().

00662 {
00663    unsigned char buf[4], keyed;
00664    char lastrx, txtmp;
00665    struct usb_device *usb_dev;
00666    struct usb_dev_handle *usb_handle;
00667    struct chan_usbradio_pvt *o = arg;
00668 
00669    usb_dev = hid_device_init();
00670    if (usb_dev == NULL) {
00671       ast_log(LOG_ERROR, "USB HID device not found\n");
00672       pthread_exit(NULL);
00673    }
00674    usb_handle = usb_open(usb_dev);
00675    if (usb_handle == NULL) {
00676       ast_log(LOG_ERROR, "Not able to open USB device\n");
00677       pthread_exit(NULL);
00678    }
00679    if (usb_claim_interface(usb_handle, C108_HID_INTERFACE) < 0) {
00680            if (usb_detach_kernel_driver_np(usb_handle, C108_HID_INTERFACE) < 0) {
00681          ast_log(LOG_ERROR, "Not able to detach the USB device\n");
00682          pthread_exit(NULL);
00683       }
00684       if (usb_claim_interface(usb_handle, C108_HID_INTERFACE) < 0) {
00685          ast_log(LOG_ERROR, "Not able to claim the USB device\n");
00686          pthread_exit(NULL);
00687       }
00688    }
00689    memset(buf, 0, sizeof(buf));
00690    buf[2] = o->hid_gpio_ctl;
00691    buf[1] = 0;
00692    hid_set_outputs(usb_handle, buf);
00693    traceusb1("hidthread: Starting normally!!\n");
00694    lastrx = 0;
00695    while (!o->stophid) {
00696       buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
00697       hid_get_inputs(usb_handle, buf);
00698       keyed = !(buf[o->hid_io_cor_loc] & o->hid_io_cor);
00699       if (keyed != o->rxhidsq) {
00700          if (o->debuglevel)
00701             ast_log(LOG_NOTICE, "chan_usbradio() hidthread: update rxhidsq = %d\n", keyed);
00702          o->rxhidsq = keyed;      
00703       }
00704 
00705       /* if change in tx stuff */
00706       txtmp = 0;
00707       if (o->txkeyed || o->txchankey || o->txtestkey || o->pmrChan->txPttOut)
00708          txtmp = 1;
00709       
00710       if (o->lasttx != txtmp) {
00711          o->lasttx = txtmp;
00712          if (o->debuglevel)
00713             ast_log(LOG_NOTICE, "hidthread: tx set to %d\n", txtmp);
00714          buf[o->hid_gpio_loc] = 0;
00715          if (txtmp)
00716             buf[o->hid_gpio_loc] = o->hid_io_ptt;
00717          buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
00718          hid_set_outputs(usb_handle, buf);
00719       }
00720 
00721       time(&o->lasthidtime);
00722       usleep(50000);
00723    }
00724    buf[o->hid_gpio_loc] = 0;
00725    if (o->invertptt)
00726       buf[o->hid_gpio_loc] = o->hid_io_ptt;
00727    buf[o->hid_gpio_ctl_loc] = o->hid_gpio_ctl;
00728    hid_set_outputs(usb_handle, buf);
00729    pthread_exit(0);
00730 }

static int load_module ( void   )  [static]

Definition at line 2453 of file chan_usbradio.c.

References 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_FAILURE, AST_MODULE_LOAD_SUCCESS, find_desc(), global_jbconf, LOG_ERROR, LOG_NOTICE, and store_config().

02454 {
02455    struct ast_config *cfg = NULL;
02456    char *ctg = NULL;
02457    struct ast_flags config_flags = { 0 };
02458 
02459    /* Copy the default jb config over global_jbconf */
02460    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
02461 
02462    /* load config file */
02463    if (!(cfg = ast_config_load(config, config_flags))) {
02464       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
02465       return AST_MODULE_LOAD_DECLINE;
02466    }
02467 
02468    do {
02469       store_config(cfg, ctg);
02470    } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
02471 
02472    ast_config_destroy(cfg);
02473 
02474    if (find_desc(usbradio_active) == NULL) {
02475       ast_log(LOG_NOTICE, "Device %s not found\n", usbradio_active);
02476       /* XXX we could default to 'dsp' perhaps ? */
02477       /* XXX should cleanup allocated memory etc. */
02478       return AST_MODULE_LOAD_FAILURE;
02479    }
02480 
02481    if (ast_channel_register(&usbradio_tech)) {
02482       ast_log(LOG_ERROR, "Unable to register channel type 'usb'\n");
02483       return AST_MODULE_LOAD_FAILURE;
02484    }
02485 
02486    ast_cli_register_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
02487 
02488    return AST_MODULE_LOAD_SUCCESS;
02489 }

static void mixer_write ( struct chan_usbradio_pvt o  )  [static]

static int mult_calc ( int  value  )  [static]

Definition at line 2119 of file chan_usbradio.c.

Referenced by mult_set().

02120 {
02121    const int multx = M_Q8;
02122    int pot, mult;
02123 
02124    pot= ((int)(value / 4) * 4) + 2;
02125    mult = multx - ((multx * (3 - (value % 4))) / (pot + 2));
02126    return mult;
02127 }

static void mult_set ( struct chan_usbradio_pvt o  )  [static]

Definition at line 2104 of file chan_usbradio.c.

References mult_calc(), chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::txmixaset, and chan_usbradio_pvt::txmixbset.

Referenced by handle_cli_radio_tune(), set_txctcss_level(), and store_config().

02105 {
02106 
02107    if (o->pmrChan->spsTxOutA) {
02108       o->pmrChan->spsTxOutA->outputGain = 
02109          mult_calc((o->txmixaset * 152) / 1000);
02110    }
02111    if (o->pmrChan->spsTxOutB) {
02112       o->pmrChan->spsTxOutB->outputGain = 
02113          mult_calc((o->txmixbset * 152) / 1000);
02114    }
02115 }

static void pmrdump ( struct chan_usbradio_pvt o  )  [static]

Definition at line 2135 of file chan_usbradio.c.

References ast_debug, chan_usbradio_pvt::devicenum, pd, pf, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::rxcdtype, chan_usbradio_pvt::rxctcssadj, chan_usbradio_pvt::rxdemod, chan_usbradio_pvt::rxmixerset, chan_usbradio_pvt::rxsdtype, chan_usbradio_pvt::rxsquelchadj, chan_usbradio_pvt::rxvoiceadj, chan_usbradio_pvt::txmixa, chan_usbradio_pvt::txmixaset, chan_usbradio_pvt::txmixb, chan_usbradio_pvt::txmixbset, chan_usbradio_pvt::txprelim, and chan_usbradio_pvt::txtoctype.

Referenced by handle_cli_radio_tune().

02136 {
02137    t_pmr_chan *p;
02138 
02139    p = o->pmrChan;
02140 
02141    ast_debug(4, "odump()\n");
02142 
02143    pd(o->devicenum);
02144 
02145    pd(o->rxdemod);
02146    pd(o->rxcdtype);
02147    pd(o->rxsdtype);
02148    pd(o->txtoctype);
02149 
02150    pd(o->rxmixerset);
02151    pf(o->rxvoiceadj);
02152    pf(o->rxctcssadj);
02153    pd(o->rxsquelchadj);
02154     
02155    pd(o->txprelim);
02156    pd(o->txmixa);
02157    pd(o->txmixb);
02158    
02159    pd(o->txmixaset);
02160    pd(o->txmixbset);
02161    
02162    ast_debug(4, "pmrdump()\n");
02163  
02164    ast_debug(4, "prxSquelchAdjust=%d\n", *(o->pmrChan->prxSquelchAdjust));
02165 
02166    pd(p->rxCarrierPoint);
02167    pd(p->rxCarrierHyst);
02168 
02169    pd(p->rxCtcss->relax);
02170    pf(p->rxCtcssFreq);  
02171    pd(p->rxCtcssIndex);
02172    pf(p->txCtcssFreq);
02173 
02174    pd(p->txMixA);
02175    pd(p->txMixB);
02176     
02177    pd(p->rxDeEmpEnable);
02178    pd(p->rxCenterSlicerEnable);
02179    pd(p->rxCtcssDecodeEnable);
02180    pd(p->rxDcsDecodeEnable);
02181 
02182    pd(p->txHpfEnable);
02183    pd(p->txLimiterEnable);
02184    pd(p->txPreEmpEnable);
02185    pd(p->txLpfEnable);
02186 
02187    if (p->spsTxOutA)
02188       pd(p->spsTxOutA->outputGain);
02189    if (p->spsTxOutB)
02190       pd(p->spsTxOutB->outputGain);
02191 
02192    return;
02193 }

static int set_txctcss_level ( struct chan_usbradio_pvt o  )  [static]

Definition at line 1613 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 handle_cli_radio_tune(), and store_config().

01614 {                      
01615    if (o->txmixa == TX_OUT_LSD) {
01616       o->txmixaset = (151 * o->txctcssadj) / 1000;
01617       mixer_write(o);
01618       mult_set(o);
01619    } else if (o->txmixb == TX_OUT_LSD) {
01620       o->txmixbset = (151 * o->txctcssadj) / 1000;
01621       mixer_write(o);
01622       mult_set(o);
01623    } else {
01624       *o->pmrChan->ptxCtcssAdjust = (o->txctcssadj * M_Q8) / 1000;
01625    }
01626    return 0;
01627 }

static int setamixer ( int  devnum,
char *  param,
int  v1,
int  v2 
) [static]

Call with: devnum: alsa major device number, param: ascii Formal Parameter Name, val1, first or only value, val2 second value, or 0 if only 1 value. Values: 0-99 (percent) or 0-1 for baboon.

Note: must add -lasound to end of linkage

Definition at line 540 of file chan_usbradio.c.

References id, str, and type.

Referenced by mixer_write(), and tune_rxinput().

00541 {
00542    int   type;
00543    char str[15];
00544    snd_hctl_t *hctl;
00545    snd_ctl_elem_id_t *id;
00546    snd_ctl_elem_value_t *control;
00547    snd_hctl_elem_t *elem;
00548    snd_ctl_elem_info_t *info;
00549 
00550    snprintf(str, sizeof(str), "hw:%d", devnum);
00551    if (snd_hctl_open(&hctl, str, 0))
00552       return -1;
00553    snd_hctl_load(hctl);
00554    id = alloca(snd_ctl_elem_id_sizeof());
00555    memset(id, 0, snd_ctl_elem_id_sizeof());
00556    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
00557    snd_ctl_elem_id_set_name(id, param);  
00558    elem = snd_hctl_find_elem(hctl, id);
00559    if (!elem) {
00560       snd_hctl_close(hctl);
00561       return -1;
00562    }
00563    info = alloca(snd_ctl_elem_info_sizeof());
00564    memset(info, 0, snd_ctl_elem_info_sizeof());
00565    snd_hctl_elem_info(elem,info);
00566    type = snd_ctl_elem_info_get_type(info);
00567    control = alloca(snd_ctl_elem_value_sizeof());
00568    memset(control, 0, snd_ctl_elem_value_sizeof());
00569    snd_ctl_elem_value_set_id(control, id);    
00570    switch (type) {
00571    case SND_CTL_ELEM_TYPE_INTEGER:
00572       snd_ctl_elem_value_set_integer(control, 0, v1);
00573       if (v2 > 0) snd_ctl_elem_value_set_integer(control, 1, v2);
00574       break;
00575    case SND_CTL_ELEM_TYPE_BOOLEAN:
00576       snd_ctl_elem_value_set_integer(control, 0, (v1 != 0));
00577       break;
00578    }
00579    if (snd_hctl_elem_write(elem, control)) {
00580       snd_hctl_close(hctl);
00581       return(-1);
00582    }
00583    snd_hctl_close(hctl);
00584    return 0;
00585 }

static int setformat ( struct chan_usbradio_pvt o,
int  mode 
) [static]

Definition at line 840 of file chan_usbradio.c.

References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_verb, chan_usbradio_pvt::devicenum, chan_usbradio_pvt::duplex, errno, ast_channel::fds, chan_usbradio_pvt::frags, chan_usbradio_pvt::lastopen, LOG_WARNING, O_CLOSE, chan_usbradio_pvt::owner, chan_usbradio_pvt::sounddev, WARN_frag, WARN_speed, and chan_usbradio_pvt::warned.

00841 {
00842    int fmt, desired, res, fd;
00843    char device[20];
00844 
00845    if (o->sounddev >= 0) {
00846       ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
00847       close(o->sounddev);
00848       o->duplex = M_UNSET;
00849       o->sounddev = -1;
00850    }
00851    if (mode == O_CLOSE)    /* we are done */
00852       return 0;
00853    if (ast_tvdiff_ms(ast_tvnow(), o->lastopen) < 1000)
00854       return -1;           /* don't open too often */
00855    o->lastopen = ast_tvnow();
00856    strcpy(device, "/dev/dsp");
00857    if (o->devicenum)
00858       snprintf(device + strlen("/dev/dsp"), sizeof(device) - strlen("/dev/dsp"), "%d", o->devicenum);
00859    fd = o->sounddev = open(device, mode | O_NONBLOCK);
00860    if (fd < 0) {
00861       ast_log(LOG_WARNING, "Unable to re-open DSP device %d: %s\n", o->devicenum, strerror(errno));
00862       return -1;
00863    }
00864    if (o->owner)
00865       o->owner->fds[0] = fd;
00866 
00867 #if __BYTE_ORDER == __LITTLE_ENDIAN
00868    fmt = AFMT_S16_LE;
00869 #else
00870    fmt = AFMT_S16_BE;
00871 #endif
00872    res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
00873    if (res < 0) {
00874       ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
00875       return -1;
00876    }
00877    switch (mode) {
00878       case O_RDWR:
00879          res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
00880          /* Check to see if duplex set (FreeBSD Bug) */
00881          res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
00882          if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
00883             ast_verb(2, "Console is full duplex\n");
00884             o->duplex = M_FULL;
00885          };
00886          break;
00887       case O_WRONLY:
00888          o->duplex = M_WRITE;
00889          break;
00890       case O_RDONLY:
00891          o->duplex = M_READ;
00892          break;
00893    }
00894 
00895    fmt = 1;
00896    res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
00897    if (res < 0) {
00898       ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
00899       return -1;
00900    }
00901    fmt = desired = 48000;                    /* 8000 Hz desired */
00902    res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
00903 
00904    if (res < 0) {
00905       ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
00906       return -1;
00907    }
00908    if (fmt != desired) {
00909       if (!(o->warned & WARN_speed)) {
00910          ast_log(LOG_WARNING,
00911              "Requested %d Hz, got %d Hz -- sound may be choppy\n",
00912              desired, fmt);
00913          o->warned |= WARN_speed;
00914       }
00915    }
00916    /*
00917     * on Freebsd, SETFRAGMENT does not work very well on some cards.
00918     * Default to use 256 bytes, let the user override
00919     */
00920    if (o->frags) {
00921       fmt = o->frags;
00922       res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
00923       if (res < 0) {
00924          if (!(o->warned & WARN_frag)) {
00925             ast_log(LOG_WARNING,
00926                "Unable to set fragment size -- sound may be choppy\n");
00927             o->warned |= WARN_frag;
00928          }
00929       }
00930    }
00931    /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
00932    res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
00933    res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
00934    /* it may fail if we are in half duplex, never mind */
00935    return 0;
00936 }

static int soundcard_writeframe ( struct chan_usbradio_pvt o,
short *  data 
) [static]

Write an exactly FRAME_SIZE sized frame.

Definition at line 810 of file chan_usbradio.c.

References ast_log(), FRAME_SIZE, LOG_WARNING, chan_usbradio_pvt::queuesize, setformat(), chan_usbradio_pvt::sounddev, used_blocks(), and chan_usbradio_pvt::w_errors.

00811 {
00812    int res;
00813 
00814    if (o->sounddev < 0)
00815       setformat(o, O_RDWR);
00816    if (o->sounddev < 0)
00817       return 0;            /* not fatal */
00818    /*
00819     * Nothing complex to manage the audio device queue.
00820     * If the buffer is full just drop the extra, otherwise write.
00821     * XXX in some cases it might be useful to write anyways after
00822     * a number of failures, to restart the output chain.
00823     */
00824    res = used_blocks(o);
00825    if (res > o->queuesize) {  /* no room to write a block */
00826       if (o->w_errors++ == 0 && (usbradio_debug & 0x4))
00827          ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
00828       return 0;
00829    }
00830    o->w_errors = 0;
00831 
00832    return write(o->sounddev, ((void *) data), FRAME_SIZE * 2 * 12);
00833 }

static struct chan_usbradio_pvt* store_config ( struct ast_config cfg,
char *  ctg 
) [static, read]

Definition at line 2199 of file chan_usbradio.c.

References amixer_max(), ast_calloc, ast_config_destroy(), ast_config_load, ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), ast_jb_read_conf(), ast_log(), ast_strdup, ast_tvnow(), ast_variable_browse(), CV_BOOL, CV_END, CV_F, CV_START, CV_UINT, chan_usbradio_pvt::debuglevel, chan_usbradio_pvt::devicenum, chan_usbradio_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, chan_usbradio_pvt::frags, FRAME_SIZE, global_jbconf, chan_usbradio_pvt::hdwtype, hidhdwconfig(), chan_usbradio_pvt::invertptt, chan_usbradio_pvt::lastopen, LOG_ERROR, LOG_WARNING, 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::pmrChan, chan_usbradio_pvt::queuesize, chan_usbradio_pvt::radioduplex, RX_AUDIO_SPEAKER, chan_usbradio_pvt::rxboostset, chan_usbradio_pvt::rxcdtype, chan_usbradio_pvt::rxcpusaver, chan_usbradio_pvt::rxctcssadj, chan_usbradio_pvt::rxctcssfreq, chan_usbradio_pvt::rxctcssrelax, chan_usbradio_pvt::rxdemod, chan_usbradio_pvt::rxmixerset, chan_usbradio_pvt::rxsquelchadj, chan_usbradio_pvt::rxvoiceadj, set_txctcss_level(), chan_usbradio_pvt::spkrmax, store_rxcdtype(), store_rxctcssadj(), store_rxctcssfreq(), store_rxdemod(), store_rxgain(), store_rxsdtype(), store_rxvoiceadj(), store_txctcssfreq(), store_txmixa(), store_txmixb(), store_txtoctype(), traceusb1, TX_OUT_COMPOSITE, TX_OUT_LSD, TX_OUT_VOICE, chan_usbradio_pvt::txcpusaver, chan_usbradio_pvt::txctcssadj, chan_usbradio_pvt::txctcssfreq, chan_usbradio_pvt::txmixa, chan_usbradio_pvt::txmixaset, chan_usbradio_pvt::txmixb, chan_usbradio_pvt::txmixbset, chan_usbradio_pvt::txprelim, chan_usbradio_pvt::txtoctype, and ast_variable::value.

02200 {
02201    struct ast_variable *v;
02202    struct chan_usbradio_pvt *o;
02203    struct ast_config *cfg1;
02204    struct ast_flags config_flags = { 0 };
02205 
02206    if (ctg == NULL) {
02207       traceusb1(" store_config() ctg == NULL\n");
02208       o = &usbradio_default;
02209       ctg = "general";
02210    } else {
02211       if (!(o = ast_calloc(1, sizeof(*o)))){
02212          return NULL;
02213       }
02214       *o = usbradio_default;
02215       /* "general" is also the default thing */
02216       if (strcmp(ctg, "general") == 0) {
02217          o->name = ast_strdup("dsp");
02218          usbradio_active = o->name;
02219       } else
02220          o->name = ast_strdup(ctg);
02221    }
02222 
02223    strcpy(o->mohinterpret, "default");
02224    o->micmax = amixer_max(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL);
02225    o->spkrmax = amixer_max(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL);
02226    /* fill other fields from configuration */
02227    for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
02228 
02229       /* handle jb conf */
02230       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
02231          continue;
02232       CV_START(v->name, v->value);
02233 
02234       CV_UINT("frags", o->frags);
02235       CV_UINT("queuesize", o->queuesize);
02236       CV_UINT("devicenum", o->devicenum);
02237       CV_UINT("debug", usbradio_debug);
02238       CV_BOOL("rxcpusaver", o->rxcpusaver);
02239       CV_BOOL("txcpusaver", o->txcpusaver);
02240       CV_BOOL("invertptt", o->invertptt);
02241       CV_F("rxdemod", store_rxdemod(o, v->value));
02242       CV_BOOL("txprelim", o->txprelim);;
02243       CV_F("txmixa", store_txmixa(o, v->value));
02244       CV_F("txmixb", store_txmixb(o, v->value));
02245       CV_F("carrierfrom", store_rxcdtype(o, v->value));
02246       CV_F("rxsdtype", store_rxsdtype(o, v->value));
02247       CV_F("rxctcssfreq", store_rxctcssfreq(o, v->value));
02248       CV_F("txctcssfreq", store_txctcssfreq(o, v->value));
02249       CV_F("rxgain", store_rxgain(o, v->value));
02250       CV_BOOL("rxboostset", o->rxboostset);
02251       CV_UINT("rxctcssrelax", o->rxctcssrelax);
02252       CV_F("txtoctype", store_txtoctype(o, v->value));
02253       CV_UINT("hdwtype", o->hdwtype);
02254       CV_UINT("duplex", o->radioduplex);
02255 
02256       CV_END;
02257    }
02258    
02259    cfg1 = ast_config_load(config1, config_flags);
02260    if (!cfg1) {
02261       o->rxmixerset = 500;
02262       o->txmixaset = 500;
02263       o->txmixbset = 500;
02264       o->rxvoiceadj = 0.5;
02265       o->rxctcssadj = 0.5;
02266       o->txctcssadj = 200;
02267       o->rxsquelchadj = 500;
02268       ast_log(LOG_WARNING, "File %s not found, using default parameters.\n", config1);
02269    } else  {
02270       for (v = ast_variable_browse(cfg1, ctg); v; v = v->next) {
02271    
02272          CV_START(v->name, v->value);
02273          CV_UINT("rxmixerset", o->rxmixerset);
02274          CV_UINT("txmixaset", o->txmixaset);
02275          CV_UINT("txmixbset", o->txmixbset);
02276          CV_F("rxvoiceadj", store_rxvoiceadj(o, v->value));
02277          CV_F("rxctcssadj", store_rxctcssadj(o, v->value));
02278          CV_UINT("txctcssadj", o->txctcssadj);
02279          CV_UINT("rxsquelchadj", o->rxsquelchadj);
02280          CV_END;
02281       }
02282       ast_config_destroy(cfg1);
02283    }
02284 
02285    o->debuglevel = 0;
02286 
02287    if (o == &usbradio_default)      /* we are done with the default */
02288       return NULL;
02289 
02290    o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
02291    o->dsp = ast_dsp_new();
02292    if (o->dsp) {
02293       ast_dsp_set_features(o->dsp, DSP_FEATURE_DTMF_DETECT);
02294       ast_dsp_digitmode(o->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_RELAXDTMF);
02295    }
02296 
02297    if (o->rxctcssfreq != 0 && o->rxdemod == RX_AUDIO_SPEAKER)
02298       ast_log(LOG_ERROR, "Incompatable Options  o->rxctcssfreq=%f and o->rxdemod=speaker\n", o->rxctcssfreq);  
02299 
02300    if (o->pmrChan == NULL) {
02301       t_pmr_chan tChan;
02302 
02303       memset(&tChan, 0, sizeof(tChan));
02304 
02305       tChan.rxDemod = o->rxdemod;
02306       tChan.rxCdType = o->rxcdtype;
02307 
02308       tChan.txMod = o->txprelim;
02309 
02310       tChan.txMixA = o->txmixa;
02311       tChan.txMixB = o->txmixb;
02312 
02313       tChan.rxCpuSaver = o->rxcpusaver;
02314       tChan.txCpuSaver = o->txcpusaver;
02315 
02316       tChan.rxCtcssFreq = o->rxctcssfreq;
02317       tChan.txCtcssFreq = o->txctcssfreq;
02318 
02319       o->pmrChan = createPmrChannel(&tChan, FRAME_SIZE);
02320 
02321       o->pmrChan->radioDuplex = o->radioduplex;
02322 
02323       o->pmrChan->rxCpuSaver = o->rxcpusaver;
02324       o->pmrChan->txCpuSaver = o->txcpusaver;
02325 
02326       *(o->pmrChan->prxSquelchAdjust) = 
02327          ((999 - o->rxsquelchadj) * 32767) / 1000;
02328 
02329       o->pmrChan->spsRx->outputGain = o->rxvoiceadj*M_Q8;
02330 
02331       o->pmrChan->txTocType = o->txtoctype;
02332 
02333       if ((o->txmixa == TX_OUT_LSD) ||
02334          (o->txmixa == TX_OUT_COMPOSITE) ||
02335          (o->txmixb == TX_OUT_LSD) ||
02336          (o->txmixb == TX_OUT_COMPOSITE)) {
02337          *(o->pmrChan->prxCtcssAdjust) = o->rxctcssadj * M_Q8;
02338          set_txctcss_level(o);
02339       }
02340 
02341       o->pmrChan->rxCtcss->relax = o->rxctcssrelax;
02342 
02343    }
02344 
02345    if ((o->txmixa != TX_OUT_VOICE) && (o->txmixb != TX_OUT_VOICE) &&
02346       (o->txmixa != TX_OUT_COMPOSITE) && (o->txmixb != TX_OUT_COMPOSITE))
02347       ast_log(LOG_ERROR, "No txvoice output configured.\n");
02348 
02349    if (o->txctcssfreq && 
02350        o->txmixa != TX_OUT_LSD && o->txmixa != TX_OUT_COMPOSITE  &&
02351       o->txmixb != TX_OUT_LSD && o->txmixb != TX_OUT_COMPOSITE)
02352       ast_log(LOG_ERROR, "No txtone output configured.\n");
02353 
02354    if (o->rxctcssfreq && o->pmrChan->rxCtcssIndex < 0)
02355       ast_log(LOG_ERROR, "Invalid CTCSS Frequency.\n");
02356 
02357    /* RxTestIt(o); */
02358 
02359    mixer_write(o);
02360    mult_set(o);    
02361    hidhdwconfig(o);
02362 
02363    /* pmrdump(o); */
02364 
02365    /* link into list of devices */
02366    if (o != &usbradio_default) {
02367       o->next = usbradio_default.next;
02368       usbradio_default.next = o;
02369    }
02370    return o;
02371 }

static void store_rxcdtype ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1763 of file chan_usbradio.c.

References ast_debug, 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().

01764 {
01765    if (!strcasecmp(s, "no"))
01766       o->rxcdtype = CD_IGNORE;
01767    else if (!strcasecmp(s, "usb"))
01768       o->rxcdtype = CD_HID;
01769    else if (!strcasecmp(s, "dsp"))
01770       o->rxcdtype = CD_XPMR_NOISE;
01771    else if (!strcasecmp(s, "vox"))
01772       o->rxcdtype = CD_XPMR_VOX;
01773    else if (!strcasecmp(s, "usbinvert"))
01774       o->rxcdtype = CD_HID_INVERT;
01775    else
01776       ast_log(LOG_WARNING, "Unrecognized rxcdtype parameter: %s\n", s);
01777 
01778    ast_debug(4, "set rxcdtype = %s\n", s);
01779 }

static void store_rxctcssadj ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1813 of file chan_usbradio.c.

References ast_debug, f, and chan_usbradio_pvt::rxctcssadj.

Referenced by store_config().

01814 {
01815    float f;
01816    if (sscanf(s, "%30f", &f) == 1)
01817       o->rxctcssadj = f;
01818    ast_debug(4, "set rxctcssadj = %f\n", f);
01819 }

static void store_rxctcssfreq ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1835 of file chan_usbradio.c.

References ast_debug, f, and chan_usbradio_pvt::rxctcssfreq.

Referenced by store_config().

01836 {
01837    float f;
01838    if (sscanf(s, "%f", &f) == 1)
01839       o->rxctcssfreq = f;
01840    ast_debug(4, "set rxctcss = %f\n", f);
01841 }

static void store_rxdemod ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1710 of file chan_usbradio.c.

References ast_debug, ast_log(), LOG_WARNING, RX_AUDIO_FLAT, RX_AUDIO_NONE, RX_AUDIO_SPEAKER, and chan_usbradio_pvt::rxdemod.

Referenced by store_config().

01711 {
01712    if (!strcasecmp(s, "no")) {
01713       o->rxdemod = RX_AUDIO_NONE;
01714    } else if (!strcasecmp(s, "speaker")) {
01715       o->rxdemod = RX_AUDIO_SPEAKER;
01716    } else if (!strcasecmp(s, "flat")) {
01717          o->rxdemod = RX_AUDIO_FLAT;
01718    } else {
01719       ast_log(LOG_WARNING, "Unrecognized rxdemod parameter: %s\n", s);
01720    }
01721 
01722    ast_debug(4, "set rxdemod = %s\n", s);
01723 }

static void store_rxgain ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1797 of file chan_usbradio.c.

References ast_debug, f, and chan_usbradio_pvt::rxgain.

Referenced by store_config().

01798 {
01799    float f;
01800    if (sscanf(s, "%30f", &f) == 1)
01801       o->rxgain = f;
01802    ast_debug(4, "set rxgain = %f\n", f);
01803 }

static void store_rxsdtype ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1781 of file chan_usbradio.c.

References ast_debug, ast_log(), LOG_WARNING, chan_usbradio_pvt::rxsdtype, SD_HID, SD_HID_INVERT, SD_IGNORE, and SD_XPMR.

Referenced by store_config().

01782 {
01783    if (!strcasecmp(s, "no") || !strcasecmp(s, "SD_IGNORE"))
01784       o->rxsdtype = SD_IGNORE;
01785    else if (!strcasecmp(s, "usb") || !strcasecmp(s, "SD_HID"))
01786       o->rxsdtype = SD_HID;
01787    else if (!strcasecmp(s, "usbinvert") || !strcasecmp(s, "SD_HID_INVERT"))
01788       o->rxsdtype = SD_HID_INVERT;
01789    else if (!strcasecmp(s, "software") || !strcasecmp(s, "SD_XPMR"))
01790       o->rxsdtype = SD_XPMR;
01791    else
01792       ast_log(LOG_WARNING, "Unrecognized rxsdtype parameter: %s\n", s);
01793 
01794    ast_debug(4, "set rxsdtype = %s\n", s);
01795 }

static void store_rxvoiceadj ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1805 of file chan_usbradio.c.

References ast_debug, f, and chan_usbradio_pvt::rxvoiceadj.

Referenced by store_config().

01806 {
01807    float f;
01808    if (sscanf(s, "%30f", &f) == 1)
01809       o->rxvoiceadj = f;
01810    ast_debug(4, "set rxvoiceadj = %f\n", f);
01811 }

static void store_txctcssfreq ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1843 of file chan_usbradio.c.

References ast_debug, f, and chan_usbradio_pvt::txctcssfreq.

Referenced by store_config().

01844 {
01845    float f;
01846    if (sscanf(s, "%f", &f) == 1)
01847       o->txctcssfreq = f;
01848    ast_debug(4, "set txctcss = %f\n", f);
01849 }

static void store_txmixa ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1726 of file chan_usbradio.c.

References ast_debug, ast_log(), LOG_WARNING, TX_OUT_AUX, TX_OUT_COMPOSITE, TX_OUT_LSD, TX_OUT_OFF, TX_OUT_VOICE, chan_usbradio_pvt::txmixa, and chan_usbradio_pvt::txmixb.

Referenced by store_config().

01727 {
01728    if (!strcasecmp(s, "no"))
01729       o->txmixa = TX_OUT_OFF;
01730 
01731    else if (!strcasecmp(s, "voice"))
01732       o->txmixa = TX_OUT_VOICE;
01733    else if (!strcasecmp(s, "tone"))
01734          o->txmixa = TX_OUT_LSD;
01735    else if (!strcasecmp(s, "composite"))
01736       o->txmixa = TX_OUT_COMPOSITE;
01737    else if (!strcasecmp(s, "auxvoice"))
01738       o->txmixb = TX_OUT_AUX;
01739    else
01740       ast_log(LOG_WARNING, "Unrecognized txmixa parameter: %s\n", s);
01741 
01742    ast_debug(4, "set txmixa = %s\n", s);
01743 }

static void store_txmixb ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1745 of file chan_usbradio.c.

References ast_debug, 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().

01746 {
01747    if (!strcasecmp(s, "no"))
01748       o->txmixb = TX_OUT_OFF;
01749    else if (!strcasecmp(s, "voice"))
01750       o->txmixb = TX_OUT_VOICE;
01751    else if (!strcasecmp(s, "tone"))
01752          o->txmixb = TX_OUT_LSD;
01753    else if (!strcasecmp(s, "composite"))
01754       o->txmixb = TX_OUT_COMPOSITE;
01755    else if (!strcasecmp(s, "auxvoice"))
01756       o->txmixb = TX_OUT_AUX;
01757    else
01758       ast_log(LOG_WARNING, "Unrecognized txmixb parameter: %s\n", s);
01759 
01760    ast_debug(4, "set txmixb = %s\n", s);
01761 }

static void store_txtoctype ( struct chan_usbradio_pvt o,
const char *  s 
) [static]

Definition at line 1821 of file chan_usbradio.c.

References ast_debug, ast_log(), LOG_WARNING, TOC_NONE, TOC_NOTONE, TOC_PHASE, and chan_usbradio_pvt::txtoctype.

Referenced by store_config().

01822 {
01823    if (!strcasecmp(s, "no") || !strcasecmp(s, "TOC_NONE"))
01824       o->txtoctype = TOC_NONE;
01825    else if (!strcasecmp(s, "phase") || !strcasecmp(s, "TOC_PHASE"))
01826       o->txtoctype = TOC_PHASE;
01827    else if (!strcasecmp(s, "notone") || !strcasecmp(s, "TOC_NOTONE"))
01828       o->txtoctype = TOC_NOTONE;
01829    else
01830       ast_log(LOG_WARNING, "Unrecognized txtoctype parameter: %s\n", s);
01831 
01832    ast_debug(4, "set txtoctype = %s\n", s);
01833 }

static void tune_rxctcss ( struct chan_usbradio_pvt o  )  [static]

Definition at line 2008 of file chan_usbradio.c.

References ast_debug, ast_log(), LOG_ERROR, LOG_NOTICE, chan_usbradio_pvt::pmrChan, and chan_usbradio_pvt::rxctcssadj.

Referenced by handle_cli_radio_tune().

02009 {
02010    const int target = 4096;
02011    const int tolerance = 100;
02012    const float settingmin = 0.1;
02013    const float settingmax = 4;
02014    const float settingstart = 1;
02015    const int maxtries = 12;
02016 
02017    float setting;
02018    int tries = 0, meas;
02019 
02020    ast_log(LOG_NOTICE, "RX CTCSS ADJUST START.\n");   
02021    ast_log(LOG_NOTICE, "target=%d tolerance=%d \n", target, tolerance);
02022 
02023    o->pmrChan->spsMeasure->source = o->pmrChan->prxCtcssMeasure;
02024    o->pmrChan->spsMeasure->discfactor = 400;
02025    o->pmrChan->spsMeasure->enabled = 1;
02026 
02027    setting = settingstart;
02028 
02029    while (tries < maxtries) {
02030       *(o->pmrChan->prxCtcssAdjust) = setting * M_Q8;
02031       usleep(10000);
02032       o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
02033       usleep(500000);
02034       meas = o->pmrChan->spsMeasure->apeak;
02035       ast_debug(4, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
02036 
02037       if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
02038          setting = setting * target / meas;
02039       else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
02040          break;
02041       if (setting < settingmin)
02042          setting = settingmin;
02043       else if (setting > settingmax)
02044          setting = settingmax;
02045 
02046       tries++;
02047    }
02048    o->pmrChan->spsMeasure->enabled = 0;
02049    ast_debug(4, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
02050    if (meas < (target - tolerance) || meas > (target + tolerance))
02051       ast_log(LOG_ERROR, "RX CTCSS GAIN ADJUST FAILED.\n");
02052    else {
02053       ast_log(LOG_NOTICE, "RX CTCSS GAIN ADJUST SUCCESS.\n");
02054       o->rxctcssadj = setting;
02055    }
02056 }

static void tune_rxinput ( struct chan_usbradio_pvt o  )  [static]

Definition at line 1875 of file chan_usbradio.c.

References ast_debug, ast_log(), CD_XPMR_VOX, chan_usbradio_pvt::devicenum, LOG_NOTICE, 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 handle_cli_radio_tune().

01876 {
01877    const int target = 23000;
01878    const int tolerance = 2000;
01879    const int settingmin = 1;
01880    const int settingstart = 2;
01881    const int maxtries = 12;
01882 
01883    float settingmax;
01884    
01885    int setting = 0, tries = 0, tmpdiscfactor, meas;
01886    int tunetype = 0;
01887 
01888    settingmax = o->micmax;
01889 
01890    if (o->pmrChan->rxDemod)
01891       tunetype = 1;
01892 
01893    setting = settingstart;
01894 
01895    while (tries < maxtries) {
01896       setamixer(o->devicenum, MIXER_PARAM_MIC_CAPTURE_VOL, setting, 0);
01897       setamixer(o->devicenum, MIXER_PARAM_MIC_BOOST, o->rxboostset, 0);
01898       usleep(100000);
01899       if (o->rxcdtype == CD_XPMR_VOX || o->rxdemod == RX_AUDIO_SPEAKER) {
01900          ast_debug(4, "Measure Direct Input\n");
01901          o->pmrChan->spsMeasure->source = o->pmrChan->spsRx->source;
01902          o->pmrChan->spsMeasure->discfactor = 1000;
01903          o->pmrChan->spsMeasure->enabled = 1;
01904          o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
01905          usleep(400000);   
01906          meas = o->pmrChan->spsMeasure->apeak;
01907          o->pmrChan->spsMeasure->enabled = 0;   
01908       } else {
01909          ast_debug(4, "Measure HF Noise\n");
01910          tmpdiscfactor = o->pmrChan->spsRx->discfactor;
01911          o->pmrChan->spsRx->discfactor = (i16)1000;
01912          o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
01913          o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
01914          usleep(200000);
01915          meas = o->pmrChan->rxRssi;
01916          o->pmrChan->spsRx->discfactor = tmpdiscfactor;
01917          o->pmrChan->spsRx->discounteru = o->pmrChan->spsRx->discounterl = 0;
01918          o->pmrChan->spsRx->amax = o->pmrChan->spsRx->amin = 0;
01919       }
01920         if (!meas)
01921          meas++;
01922       ast_log(LOG_NOTICE, "tries=%d, setting=%d, meas=%i\n", tries, setting, meas);
01923 
01924       if ( meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
01925          setting = setting * target / meas;
01926       else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance) )
01927          break;
01928 
01929       if (setting < settingmin)
01930          setting = settingmin;
01931       else if (setting > settingmax)
01932          setting = settingmax;
01933 
01934       tries++;
01935    }
01936    ast_log(LOG_NOTICE, "DONE tries=%d, setting=%d, meas=%i\n", tries,
01937       (setting * 1000) / o->micmax, meas);
01938    if (meas < (target - tolerance) || meas > (target + tolerance))
01939       ast_log(LOG_NOTICE, "ERROR: RX INPUT ADJUST FAILED.\n");
01940    else {
01941       ast_log(LOG_NOTICE, "INFO: RX INPUT ADJUST SUCCESS.\n"); 
01942       o->rxmixerset = (setting * 1000) / o->micmax;
01943    }
01944 }

static void tune_rxvoice ( struct chan_usbradio_pvt o  )  [static]

Definition at line 1947 of file chan_usbradio.c.

References ast_debug, ast_log(), LOG_ERROR, LOG_NOTICE, chan_usbradio_pvt::pmrChan, and chan_usbradio_pvt::rxvoiceadj.

Referenced by handle_cli_radio_tune().

01948 {
01949    const int target = 7200;        /* peak */
01950    const int tolerance = 360;      /* peak to peak */
01951    const float settingmin = 0.1;
01952    const float settingmax = 4;
01953    const float settingstart = 1;
01954    const int maxtries = 12;
01955 
01956    float setting;
01957 
01958    int tries = 0, meas;
01959 
01960    ast_log(LOG_NOTICE, "INFO: RX VOICE ADJUST START.\n");   
01961    ast_log(LOG_NOTICE, "target=%d tolerance=%d\n", target, tolerance);
01962 
01963    if (!o->pmrChan->spsMeasure)
01964       ast_log(LOG_ERROR, "NO MEASURE BLOCK.\n");
01965 
01966    if (!o->pmrChan->spsMeasure->source || !o->pmrChan->prxVoiceAdjust )
01967       ast_log(LOG_ERROR, "NO SOURCE OR MEASURE SETTING.\n");
01968 
01969    o->pmrChan->spsMeasure->source = o->pmrChan->spsRxOut->sink;
01970    o->pmrChan->spsMeasure->enabled = 1;
01971    o->pmrChan->spsMeasure->discfactor = 1000;
01972 
01973    setting=settingstart;
01974 
01975    ast_debug(4, "ERROR: NO MEASURE BLOCK.\n");
01976 
01977    while (tries < maxtries) {
01978       *(o->pmrChan->prxVoiceAdjust) = setting * M_Q8;
01979       usleep(10000);
01980       o->pmrChan->spsMeasure->amax = o->pmrChan->spsMeasure->amin = 0;
01981       usleep(1000000);
01982       meas = o->pmrChan->spsMeasure->apeak;
01983       ast_log(LOG_NOTICE, "tries=%d, setting=%f, meas=%i\n", tries, setting, meas);
01984 
01985       if (meas < (target - tolerance) || meas > (target + tolerance) || tries < 3)
01986          setting = setting * target / meas;
01987       else if (tries > 4 && meas > (target - tolerance) && meas < (target + tolerance))
01988          break;
01989       if (setting < settingmin)
01990          setting = settingmin;
01991       else if (setting > settingmax)
01992          setting = settingmax;
01993 
01994       tries++;
01995    }
01996 
01997    o->pmrChan->spsMeasure->enabled = 0;
01998 
01999    ast_log(LOG_NOTICE, "DONE tries=%d, setting=%f, meas=%f\n", tries, setting, (float)meas);
02000    if (meas < (target - tolerance) || meas > (target + tolerance))
02001       ast_log(LOG_ERROR, "RX VOICE GAIN ADJUST FAILED.\n");
02002    else {
02003       ast_log(LOG_NOTICE, "RX VOICE GAIN ADJUST SUCCESS.\n");
02004       o->rxvoiceadj = setting;
02005    }
02006 }

static void tune_txoutput ( struct chan_usbradio_pvt o,
int  value 
) [static]

Definition at line 1851 of file chan_usbradio.c.

References chan_usbradio_pvt::pmrChan, and chan_usbradio_pvt::txtestkey.

Referenced by handle_cli_radio_tune().

01852 {
01853    o->txtestkey = 1;
01854    o->pmrChan->txPttIn = 1;
01855 
01856 #if 0
01857    /* generate 1KHz tone at 7200 peak */
01858    o->pmrChan->spsSigGen1->freq = 10000;
01859    o->pmrChan->spsSigGen1->outputGain = (float)(0.22 * M_Q8);
01860    o->pmrChan->b.startSpecialTone = 1;
01861 #endif
01862 
01863    TxTestTone(o->pmrChan, 1);
01864 
01865    usleep(5000000);
01866    /* o->pmrChan->b.stopSpecialTone = 1; */
01867    usleep(100000);
01868 
01869    TxTestTone(o->pmrChan, 0);
01870 
01871    o->pmrChan->txPttIn = 0;
01872    o->txtestkey = 0;
01873 }

static void tune_write ( struct chan_usbradio_pvt o  )  [static]

Definition at line 2061 of file chan_usbradio.c.

References chan_usbradio_pvt::devicenum, chan_usbradio_pvt::name, chan_usbradio_pvt::rxboostset, chan_usbradio_pvt::rxctcssadj, chan_usbradio_pvt::rxmixerset, chan_usbradio_pvt::rxsquelchadj, chan_usbradio_pvt::rxvoiceadj, chan_usbradio_pvt::txctcssadj, chan_usbradio_pvt::txmixaset, and chan_usbradio_pvt::txmixbset.

Referenced by handle_cli_radio_tune().

02062 {
02063    FILE *fp;
02064    
02065    fp = fopen("/etc/asterisk/usbradio_tune.conf", "w");
02066  
02067    if (!strcmp(o->name, "dsp"))
02068       fprintf(fp, "[general]\n");
02069    else
02070       fprintf(fp, "[%s]\n", o->name);
02071 
02072    fprintf(fp, "; name=%s\n", o->name);
02073    fprintf(fp, "; devicenum=%d\n", o->devicenum);
02074 
02075    fprintf(fp, "rxmixerset=%d\n", o->rxmixerset);
02076    fprintf(fp, "rxboostset=%d\n", o->rxboostset);
02077    fprintf(fp, "txmixaset=%d\n", o->txmixaset);
02078    fprintf(fp, "txmixbset=%d\n", o->txmixbset);
02079 
02080    fprintf(fp, "rxvoiceadj=%f\n", o->rxvoiceadj);
02081    fprintf(fp, "rxctcssadj=%f\n", o->rxctcssadj);
02082    fprintf(fp, "txctcssadj=%d\n", o->txctcssadj);
02083 
02084    fprintf(fp, "rxsquelchadj=%d\n", o->rxsquelchadj);
02085    fclose(fp);
02086 }

static int unload_module ( void   )  [static]

Definition at line 2492 of file chan_usbradio.c.

References 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, and chan_usbradio_pvt::sounddev.

02493 {
02494    struct chan_usbradio_pvt *o;
02495 
02496    ast_log(LOG_WARNING, "unload_module() called\n");
02497 
02498    ast_channel_unregister(&usbradio_tech);
02499    ast_cli_unregister_multiple(cli_usbradio, sizeof(cli_usbradio) / sizeof(struct ast_cli_entry));
02500 
02501    for (o = usbradio_default.next; o; o = o->next) {
02502 
02503       ast_log(LOG_WARNING, "destroyPmrChannel() called\n");
02504       if (o->pmrChan)
02505          destroyPmrChannel(o->pmrChan);
02506       
02507       #if DEBUG_CAPTURES == 1
02508       if (frxcapraw) { fclose(frxcapraw); frxcapraw = NULL; }
02509       if (frxcaptrace) { fclose(frxcaptrace); frxcaptrace = NULL; }
02510       if (frxoutraw) { fclose(frxoutraw); frxoutraw = NULL; }
02511       if (ftxcapraw) { fclose(ftxcapraw); ftxcapraw = NULL; }
02512       if (ftxcaptrace) { fclose(ftxcaptrace); ftxcaptrace = NULL; }
02513       if (ftxoutraw) { fclose(ftxoutraw); ftxoutraw = NULL; }
02514       #endif
02515 
02516       close(o->sounddev);
02517       if (o->dsp)
02518          ast_dsp_free(o->dsp);
02519       if (o->owner)
02520          ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
02521       if (o->owner)        /* XXX how ??? */
02522          return -1;
02523       /* XXX what about the thread ? */
02524       /* XXX what about the memory allocated ? */
02525    }
02526    return 0;
02527 }

static int usbradio_answer ( struct ast_channel c  )  [static]

Definition at line 977 of file chan_usbradio.c.

References ast_setstate(), and AST_STATE_UP.

00978 {
00979    ast_setstate(c, AST_STATE_UP);
00980 
00981    return 0;
00982 }

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 941 of file chan_usbradio.c.

00942 {
00943    return 0;
00944 }

static int usbradio_digit_end ( struct ast_channel c,
char  digit,
unsigned int  duration 
) [static]

Definition at line 946 of file chan_usbradio.c.

References ast_verb.

00947 {
00948    /* no better use for received digits than print them */
00949    ast_verb(0, " << Console Received digit %c of duration %u ms >> \n", 
00950       digit, duration);
00951    return 0;
00952 }

static int usbradio_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

Definition at line 1229 of file chan_usbradio.c.

References ast_log(), LOG_WARNING, chan_usbradio_pvt::owner, and ast_channel::tech_pvt.

01230 {
01231    struct chan_usbradio_pvt *o = newchan->tech_pvt;
01232    ast_log(LOG_WARNING,"usbradio_fixup()\n");
01233    o->owner = newchan;
01234    return 0;
01235 }

static int usbradio_hangup ( struct ast_channel c  )  [static]

Definition at line 984 of file chan_usbradio.c.

References ast_module_unref(), chan_usbradio_pvt::autoanswer, chan_usbradio_pvt::autohangup, chan_usbradio_pvt::hidthread, chan_usbradio_pvt::hookstate, O_CLOSE, chan_usbradio_pvt::owner, setformat(), chan_usbradio_pvt::stophid, and ast_channel::tech_pvt.

00985 {
00986    struct chan_usbradio_pvt *o = c->tech_pvt;
00987 
00988    c->tech_pvt = NULL;
00989    o->owner = NULL;
00990    ast_module_unref(ast_module_info->self);
00991    if (o->hookstate) {
00992       if (o->autoanswer || o->autohangup) {
00993          /* Assume auto-hangup too */
00994          o->hookstate = 0;
00995          setformat(o, O_CLOSE);
00996       }
00997    }
00998    o->stophid = 1;
00999    pthread_join(o->hidthread, NULL);
01000    return 0;
01001 }

static int usbradio_indicate ( struct ast_channel chan,
int  cond,
const void *  data,
size_t  datalen 
) [static]

Definition at line 1237 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_verb, chan_usbradio_pvt::debuglevel, LOG_WARNING, chan_usbradio_pvt::mohinterpret, ast_channel::name, ast_channel::tech_pvt, and chan_usbradio_pvt::txkeyed.

01238 {
01239    struct chan_usbradio_pvt *o = c->tech_pvt;
01240    int res = 0;
01241 
01242    switch (cond) {
01243    case AST_CONTROL_BUSY:
01244    case AST_CONTROL_CONGESTION:
01245    case AST_CONTROL_RINGING:
01246    case -1:
01247       res = -1;
01248       break;
01249    case AST_CONTROL_PROGRESS:
01250    case AST_CONTROL_PROCEEDING:
01251    case AST_CONTROL_VIDUPDATE:
01252       break;
01253    case AST_CONTROL_HOLD:
01254       ast_verb(0, " << Console Has Been Placed on Hold >> \n");
01255       ast_moh_start(c, data, o->mohinterpret);
01256       break;
01257    case AST_CONTROL_UNHOLD:
01258       ast_verb(0, " << Console Has Been Retrieved from Hold >> \n");
01259       ast_moh_stop(c);
01260       break;
01261    case AST_CONTROL_RADIO_KEY:
01262       o->txkeyed = 1;
01263       if (o->debuglevel)
01264          ast_verb(0, " << Radio Transmit On. >> \n");
01265       break;
01266    case AST_CONTROL_RADIO_UNKEY:
01267       o->txkeyed = 0;
01268       if (o->debuglevel)
01269          ast_verb(0, " << Radio Transmit Off. >> \n");
01270       break;
01271    default:
01272       ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
01273       return -1;
01274    }
01275 
01276    return res;
01277 }

static struct ast_channel* usbradio_new ( struct chan_usbradio_pvt o,
char *  ext,
char *  ctx,
int  state 
) [static, read]

Definition at line 1282 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, chan_usbradio_pvt::devicenum, ast_channel::fds, global_jbconf, language, chan_usbradio_pvt::language, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, chan_usbradio_pvt::owner, ast_channel::readformat, setformat(), chan_usbradio_pvt::sounddev, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by usbradio_request().

01283 {
01284    struct ast_channel *c;
01285    char device[15] = "dsp";
01286 
01287    if (o->devicenum)
01288       snprintf(device + 3, sizeof(device) - 3, "%d", o->devicenum);
01289    c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "usbRadio/%s", device);
01290    if (c == NULL)
01291       return NULL;
01292    c->tech = &usbradio_tech;
01293    if (o->sounddev < 0)
01294       setformat(o, O_RDWR);
01295    c->fds[0] = o->sounddev;   /* -1 if device closed, override later */
01296    c->nativeformats = AST_FORMAT_SLINEAR;
01297    c->readformat = AST_FORMAT_SLINEAR;
01298    c->writeformat = AST_FORMAT_SLINEAR;
01299    c->tech_pvt = o;
01300 
01301    if (!ast_strlen_zero(o->language))
01302       ast_string_field_set(c, language, o->language);
01303    /* Don't use ast_set_callerid() here because it will
01304     * generate a needless NewCallerID event */
01305    c->cid.cid_num = ast_strdup(o->cid_num);
01306    c->cid.cid_ani = ast_strdup(o->cid_num);
01307    c->cid.cid_name = ast_strdup(o->cid_name);
01308    if (!ast_strlen_zero(ext))
01309       c->cid.cid_dnid = ast_strdup(ext);
01310 
01311    o->owner = c;
01312    ast_module_ref(ast_module_info->self);
01313    ast_jb_configure(c, &global_jbconf);
01314    if (state != AST_STATE_DOWN) {
01315       if (ast_pbx_start(c)) {
01316          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
01317          ast_hangup(c);
01318          o->owner = c = NULL;
01319          /* XXX what about the channel itself ? */
01320          /* XXX what about usecnt ? */
01321       }
01322    }
01323 
01324    return c;
01325 }

static struct ast_frame * usbradio_read ( struct ast_channel chan  )  [static, read]

Definition at line 1072 of file chan_usbradio.c.

References ast_channel::_state, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_debug, 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, chan_usbradio_pvt::lasthidtime, chan_usbradio_pvt::lastrx, LOG_ERROR, LOG_NOTICE, chan_usbradio_pvt::mute, ast_frame::offset, chan_usbradio_pvt::owner, chan_usbradio_pvt::pmrChan, chan_usbradio_pvt::read_f, 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::rxhidsq, chan_usbradio_pvt::rxkeyed, ast_frame::samples, chan_usbradio_pvt::sounddev, ast_frame::src, ast_frame::subclass, ast_channel::tech_pvt, traceusb2, ast_channel_tech::type, chan_usbradio_pvt::usbradio_read_buf, and chan_usbradio_pvt::usbradio_read_buf_8k.

01073 {
01074    int res;
01075    struct chan_usbradio_pvt *o = c->tech_pvt;
01076    struct ast_frame *f = &o->read_f, *f1;
01077    struct ast_frame wf = { AST_FRAME_CONTROL };
01078    time_t now;
01079 
01080    traceusb2("usbradio_read()\n");  /* sph maw asdf */
01081 
01082    if (o->lasthidtime) {
01083       time(&now);
01084       if ((now - o->lasthidtime) > 3) {
01085          ast_log(LOG_ERROR, "HID process has died or something!!\n");
01086          return NULL;
01087       }
01088    }
01089    if (o->lastrx && (!o->rxkeyed)) {
01090       o->lastrx = 0;
01091       wf.subclass = AST_CONTROL_RADIO_UNKEY;
01092       ast_queue_frame(o->owner, &wf);
01093    } else if ((!o->lastrx) && (o->rxkeyed)) {
01094       o->lastrx = 1;
01095       wf.subclass = AST_CONTROL_RADIO_KEY;
01096       ast_queue_frame(o->owner, &wf);
01097    }
01098    /* XXX can be simplified returning &ast_null_frame */
01099    /* prepare a NULL frame in case we don't have enough data to return */
01100    memset(f, 0, sizeof(struct ast_frame));
01101    f->frametype = AST_FRAME_NULL;
01102    f->src = usbradio_tech.type;
01103 
01104    res = read(o->sounddev, o->usbradio_read_buf + o->readpos, 
01105       sizeof(o->usbradio_read_buf) - o->readpos);
01106    if (res < 0)            /* audio data not ready, return a NULL frame */
01107       return f;
01108 
01109    o->readpos += res;
01110    if (o->readpos < sizeof(o->usbradio_read_buf))  /* not enough samples */
01111       return f;
01112 
01113    if (o->mute)
01114       return f;
01115 
01116    #if DEBUG_CAPTURES == 1
01117    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)) {
01118       ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
01119    }
01120    #endif
01121 
01122    #if 1
01123    PmrRx(         o->pmrChan,
01124          (i16 *)(o->usbradio_read_buf + AST_FRIENDLY_OFFSET),
01125          (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
01126 
01127    #else
01128    static FILE *hInput;
01129    i16 iBuff[FRAME_SIZE * 2 * 6];
01130 
01131    o->pmrChan->b.rxCapture = 1;
01132 
01133    if(!hInput) {
01134       hInput = fopen("/usr/src/xpmr/testdata/rx_in.pcm", "r");
01135       if(!hInput) {
01136          ast_log(LOG_ERROR, " Input Data File Not Found.\n");
01137          return 0;
01138       }
01139    }
01140 
01141    if (0 == fread((void *)iBuff, 2, FRAME_SIZE * 2 * 6, hInput))
01142       exit;
01143 
01144    PmrRx(         o->pmrChan, 
01145          (i16 *)iBuff,
01146          (i16 *)(o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET));
01147 
01148    #endif
01149 
01150    #if 0
01151    if (!frxoutraw) frxoutraw = fopen(RX_CAP_OUT_FILE, "w");
01152     if (frxoutraw) fwrite((o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET), 1, FRAME_SIZE * 2, frxoutraw);
01153    #endif
01154 
01155    #if DEBUG_CAPTURES == 1
01156     if ((frxcaptrace && o->b.rxcap2) && (fwrite((o->pmrChan->prxDebug), 1, FRAME_SIZE * 2 * 16, frxcaptrace) != FRAME_SIZE * 2 * 16)) {
01157       ast_log(LOG_ERROR, "fwrite() error: %s\n", strerror(errno));
01158    }
01159    #endif
01160 
01161    if (o->rxcdtype == CD_HID && (o->pmrChan->rxExtCarrierDetect != o->rxhidsq))
01162       o->pmrChan->rxExtCarrierDetect = o->rxhidsq;
01163    if (o->rxcdtype == CD_HID_INVERT && (o->pmrChan->rxExtCarrierDetect == o->rxhidsq))
01164       o->pmrChan->rxExtCarrierDetect = !o->rxhidsq;
01165       
01166    if ( (o->rxcdtype == CD_HID && o->rxhidsq) ||
01167        (o->rxcdtype == CD_HID_INVERT && !o->rxhidsq) ||
01168        (o->rxcdtype == CD_XPMR_NOISE && o->pmrChan->rxCarrierDetect) ||
01169        (o->rxcdtype == CD_XPMR_VOX && o->pmrChan->rxCarrierDetect) )
01170       res = 1;
01171    else
01172       res = 0;
01173 
01174    if (res != o->rxcarrierdetect) {
01175       o->rxcarrierdetect = res;
01176       if (o->debuglevel)
01177          ast_debug(4, "rxcarrierdetect = %d\n", res);
01178    }
01179 
01180    if (o->pmrChan->rxCtcss->decode != o->rxctcssdecode) {
01181       if (o->debuglevel)
01182          ast_debug(4, "rxctcssdecode = %d\n", o->pmrChan->rxCtcss->decode);
01183       o->rxctcssdecode = o->pmrChan->rxCtcss->decode;
01184    }
01185 
01186    if ( (  o->rxctcssfreq && (o->rxctcssdecode == o->pmrChan->rxCtcssIndex)) || 
01187        ( !o->rxctcssfreq && o->rxcarrierdetect) ) 
01188       o->rxkeyed = 1;
01189    else
01190       o->rxkeyed = 0;
01191 
01192 
01193    o->readpos = AST_FRIENDLY_OFFSET;   /* reset read pointer for next frame */
01194    if (c->_state != AST_STATE_UP)   /* drop data if frame is not up */
01195       return f;
01196    /* ok we can build and deliver the frame to the caller */
01197    f->frametype = AST_FRAME_VOICE;
01198    f->subclass = AST_FORMAT_SLINEAR;
01199    f->samples = FRAME_SIZE;
01200    f->datalen = FRAME_SIZE * 2;
01201    f->data = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
01202    if (o->boost != BOOST_SCALE) {   /* scale and clip values */
01203       int i, x;
01204       int16_t *p = (int16_t *) f->data;
01205       for (i = 0; i < f->samples; i++) {
01206          x = (p[i] * o->boost) / BOOST_SCALE;
01207          if (x > 32767)
01208             x = 32767;
01209          else if (x < -32768)
01210             x = -32768;
01211          p[i] = x;
01212       }
01213    }
01214 
01215    f->offset = AST_FRIENDLY_OFFSET;
01216    if (o->dsp) {
01217       f1 = ast_dsp_process(c, o->dsp, f);
01218       if ((f1->frametype == AST_FRAME_DTMF_END) || (f1->frametype == AST_FRAME_DTMF_BEGIN)) {
01219          if ((f1->subclass == 'm') || (f1->subclass == 'u'))
01220              f1->frametype = AST_FRAME_DTMF_BEGIN;
01221          if (f1->frametype == AST_FRAME_DTMF_END)
01222              ast_log(LOG_NOTICE,"Got DTMF char %c\n",f1->subclass);
01223          return f1;
01224       }
01225    }
01226    return f;
01227 }

static struct ast_channel * usbradio_request ( const char *  type,
int  format,
void *  data,
int *  cause 
) [static, read]

Definition at line 1327 of file chan_usbradio.c.

References AST_CAUSE_BUSY, ast_debug, AST_FORMAT_SLINEAR, ast_log(), AST_STATE_DOWN, find_desc(), LOG_NOTICE, LOG_WARNING, chan_usbradio_pvt::owner, and usbradio_new().

01328 {
01329    struct ast_channel *c;
01330    struct chan_usbradio_pvt *o = find_desc(data);
01331 
01332    ast_debug(4, "usbradio_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data);
01333    if (o == NULL) {
01334       ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
01335       /* XXX we could default to 'dsp' perhaps ? */
01336       return NULL;
01337    }
01338    if ((format & AST_FORMAT_SLINEAR) == 0) {
01339       ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
01340       return NULL;
01341    }
01342    if (o->owner) {
01343       ast_log(LOG_NOTICE, "Already have a call (chan %p) on the usb channel\n", o->owner);
01344       *cause = AST_CAUSE_BUSY;
01345       return NULL;
01346    }
01347    c = usbradio_new(o, NULL, NULL, AST_STATE_DOWN);
01348    if (c == NULL) {
01349       ast_log(LOG_WARNING, "Unable to create new usb channel\n");
01350       return NULL;
01351    }
01352    return c;
01353 }

static int usbradio_text ( struct ast_channel c,
const char *  text 
) [static]

Definition at line 954 of file chan_usbradio.c.

References ast_verb.

00955 {
00956    /* print received messages */
00957    ast_verb(0, " << Console Received text %s >> \n", text);
00958    return 0;
00959 }

static int usbradio_write ( struct ast_channel chan,
struct ast_frame f 
) [static]

Definition at line 1005 of file chan_usbradio.c.

References ast_log(), chan_usbradio_pvt::b, ast_frame::data, ast_frame::datalen, errno, FRAME_SIZE, LOG_ERROR, chan_usbradio_pvt::pmrChan, soundcard_writeframe(), ast_channel::tech_pvt, traceusb2, TX_CAP_OUT_FILE, chan_usbradio_pvt::txcap2, chan_usbradio_pvt::txcapraw, chan_usbradio_pvt::txkeyed, chan_usbradio_pvt::txtestkey, chan_usbradio_pvt::usbradio_write_buf, chan_usbradio_pvt::usbradio_write_buf_1, and chan_usbradio_pvt::usbradio_write_dst.

01006 {
01007    int src,datalen;
01008    struct chan_usbradio_pvt *o = c->tech_pvt;
01009 
01010    traceusb2("usbradio_write() o->nosound=%d\n", o->nosound);  /*sph maw asdf */
01011 
01012    /*
01013     * we could receive a block which is not a multiple of our
01014     * FRAME_SIZE, so buffer it locally and write to the device
01015     * in FRAME_SIZE chunks.
01016     * Keep the residue stored for future use.
01017     */
01018 
01019    if (o->txkeyed || o->txtestkey)
01020       o->pmrChan->txPttIn = 1;
01021    else
01022       o->pmrChan->txPttIn = 0;
01023 
01024    #if DEBUG_CAPTURES == 1 /* to write input data to a file   datalen=320 */
01025    if (ftxcapraw && o->b.txcapraw) {
01026       i16 i, tbuff[f->datalen];
01027       for (i = 0; i < f->datalen; i += 2) {
01028          tbuff[i] = ((i16 *)(f->data))[i / 2];
01029          tbuff[i + 1] = o->txkeyed * M_Q13;
01030       }
01031       if (fwrite(tbuff, 2, f->datalen, ftxcapraw) != f->datalen) {
01032          ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
01033       }
01034       /*fwrite(f->data,1,f->datalen,ftxcapraw); */
01035    }
01036    #endif
01037 
01038    PmrTx(o->pmrChan,(i16*)f->data,(i16*)o->usbradio_write_buf_1);
01039 
01040    #if 0 /* to write 48KS/s stereo data to a file */
01041    if (!ftxoutraw) ftxoutraw = fopen(TX_CAP_OUT_FILE,"w");
01042    if (ftxoutraw) fwrite(o->usbradio_write_buf_1,1,f->datalen * 2 * 6,ftxoutraw);
01043    #endif
01044 
01045    #if DEBUG_CAPTURES == 1
01046     if ((o->b.txcap2 && ftxcaptrace) && (fwrite((o->pmrChan->ptxDebug), 1, FRAME_SIZE * 2 * 16, ftxcaptrace) != FRAME_SIZE * 2 * 16)) {
01047       ast_log(LOG_ERROR, "fwrite() failed: %s\n", strerror(errno));
01048    }
01049    #endif
01050 
01051    src = 0;             /* read position into f->data */
01052    datalen = f->datalen * 12;
01053    while (src < datalen) {
01054       /* Compute spare room in the buffer */
01055       int l = sizeof(o->usbradio_write_buf) - o->usbradio_write_dst;
01056 
01057       if (datalen - src >= l) {  /* enough to fill a frame */
01058          memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
01059          soundcard_writeframe(o, (short *) o->usbradio_write_buf);
01060          src += l;
01061          o->usbradio_write_dst = 0;
01062       } else {          /* copy residue */
01063          l = datalen - src;
01064          memcpy(o->usbradio_write_buf + o->usbradio_write_dst, o->usbradio_write_buf_1 + src, l);
01065          src += l;         /* but really, we are done */
01066          o->usbradio_write_dst += l;
01067       }
01068    }
01069    return 0;
01070 }

static int used_blocks ( struct chan_usbradio_pvt o  )  [static]

split a string in extension-context, returns pointers to malloc'ed strings. If we do not have 'overridecontext' then the last @ is considered as a context separator, and the context is overridden. This is usually not very necessary as you can play with the dialplan, and it is nice not to need it because you have '@' in SIP addresses. Return value is the buffer address.

Returns the number of blocks used in the audio output channel

Definition at line 789 of file chan_usbradio.c.

References ast_debug, ast_log(), LOG_WARNING, chan_usbradio_pvt::sounddev, chan_usbradio_pvt::total_blocks, WARN_used_blocks, and chan_usbradio_pvt::warned.

00790 {
00791    struct audio_buf_info info;
00792 
00793    if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
00794       if (!(o->warned & WARN_used_blocks)) {
00795          ast_log(LOG_WARNING, "Error reading output space\n");
00796          o->warned |= WARN_used_blocks;
00797       }
00798       return 1;
00799    }
00800 
00801    if (o->total_blocks == 0) {
00802       ast_debug(4, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
00803       o->total_blocks = info.fragments;
00804    }
00805 
00806    return o->total_blocks - info.fragments;
00807 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "usb Console Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 2529 of file chan_usbradio.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 2529 of file chan_usbradio.c.

struct ast_cli_entry cli_radio_set_debug_deprecated = AST_CLI_DEFINE(handle_cli_radio_set_debug_deprecated, "Enable/Disable Radio Debugging") [static]

Definition at line 1692 of file chan_usbradio.c.

struct ast_cli_entry cli_usbradio[] [static]

Definition at line 1693 of file chan_usbradio.c.

const char* config = "usbradio.conf" [static]

Definition at line 262 of file chan_usbradio.c.

const char* config1 = "usbradio_tune.conf" [static]

Definition at line 263 of file chan_usbradio.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled

Definition at line 128 of file chan_usbradio.c.

FILE* frxcapraw = NULL [static]

Definition at line 265 of file chan_usbradio.c.

FILE * frxcaptrace = NULL [static]

Definition at line 265 of file chan_usbradio.c.

FILE * frxoutraw = NULL [static]

Definition at line 265 of file chan_usbradio.c.

FILE* ftxcapraw = NULL [static]

Definition at line 266 of file chan_usbradio.c.

FILE * ftxcaptrace = NULL [static]

Definition at line 266 of file chan_usbradio.c.

FILE * ftxoutraw = NULL [static]

Definition at line 266 of file chan_usbradio.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 135 of file chan_usbradio.c.

char tdesc[] = "USB (CM108) Radio Channel Driver" [static]

Definition at line 470 of file chan_usbradio.c.

char* usbradio_active [static]

Definition at line 449 of file chan_usbradio.c.

int usbradio_debug [static]

Definition at line 268 of file chan_usbradio.c.

Definition at line 420 of file chan_usbradio.c.

Definition at line 472 of file chan_usbradio.c.


Generated on Wed Oct 28 11:46:05 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6