#include <stdio.h>
#include <string.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/callerid.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include <sys/socket.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <vpbapi.h>
#include <assert.h>
Include dependency graph for chan_vpb.c:
Go to the source code of this file.
Data Structures | |
struct | vpb_bridge_t |
struct | vpb_pvt |
Defines | |
#define | BAD_V4PCI_BRIDGE |
#define | CID_MSECS 2000 |
#define | DEFAULT_ECHO_CANCEL 1 |
#define | DEFAULT_GAIN 0 |
#define | DTMF_CALLERID |
#define | DTMF_CID_START 'D' |
#define | DTMF_CID_STOP 'C' |
#define | MAX_BRIDGES_V12PCI 128 |
#define | MAX_BRIDGES_V4PCI 2 |
#define | MAX_VPB_GAIN 12.0 |
#define | MIN_VPB_GAIN -12.0 |
#define | MODE_DIALTONE 1 |
#define | MODE_FXO 3 |
#define | MODE_IMMEDIATE 2 |
#define | RING_SKIP 300 |
#define | TIMER_PERIOD_BUSY 700 |
#define | TIMER_PERIOD_NOANSWER 120000 |
#define | TIMER_PERIOD_RING 4000 |
#define | TIMER_PERIOD_RINGBACK 2000 |
#define | TONES_AU |
#define | VPB_CONNECTED_WAIT 4000 |
#define | VPB_DIALTONE_WAIT 2000 |
#define | VPB_EVENTS_ALL |
#define | VPB_EVENTS_NODROP |
#define | VPB_EVENTS_NODTMF |
#define | VPB_EVENTS_STAT |
#define | VPB_GOT_RXHWG 1 |
#define | VPB_GOT_RXSWG 4 |
#define | VPB_GOT_TXHWG 2 |
#define | VPB_GOT_TXSWG 8 |
#define | VPB_MAX_BUF VPB_SAMPLES*4 + AST_FRIENDLY_OFFSET |
#define | VPB_NULL_EVENT 200 |
#define | VPB_RINGWAIT 4000 |
#define | VPB_SAMPLES 160 |
#define | VPB_STATE_DIALLING 2 |
#define | VPB_STATE_GETDTMF 4 |
#define | VPB_STATE_JOINED 3 |
#define | VPB_STATE_OFFHOOK 1 |
#define | VPB_STATE_ONHOOK 0 |
#define | VPB_STATE_PLAYBUSY 6 |
#define | VPB_STATE_PLAYDIAL 5 |
#define | VPB_STATE_PLAYRING 7 |
#define | VPB_WAIT_TIMEOUT 4000 |
Enumerations | |
enum | vpb_model_t { vpb_model_unknown = 0, vpb_model_v4pci, vpb_model_v12pci } |
Functions | |
int | a_gain_vector (float g, short *v, int n) |
static int | ast2vpbformat (int ast_format) |
static char * | ast2vpbformatname (int ast_format) |
AST_MUTEX_DEFINE_STATIC (bridge_lock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
static int | astformatbits (int ast_format) |
char * | description () |
Provides a description of the module. | |
static void * | do_chanreads (void *pvt) |
static void * | do_monitor (void *unused) |
static void | get_callerid (struct vpb_pvt *p) |
static void | get_callerid_ast (struct vpb_pvt *p) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module () |
Initialize the module. | |
static void | mkbrd (vpb_model_t model, int echo_cancel) |
static struct vpb_pvt * | mkif (int board, int channel, int mode, int gains, float txgain, float rxgain, float txswgain, float rxswgain, int bal1, int bal2, int bal3, char *callerid, int echo_cancel, int group, ast_group_t callgroup, ast_group_t pickupgroup) |
static int | monitor_handle_notowned (struct vpb_pvt *p, VPB_EVENT *e) |
static int | monitor_handle_owned (struct vpb_pvt *p, VPB_EVENT *e) |
static float | parse_gain_value (char *gain_type, char *value) |
static int | playtone (int handle, VPB_TONE *tone) |
static int | restart_monitor (void) |
static void | stoptone (int handle) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
int | usecount () |
Provides a usecount. | |
static int | vpb_answer (struct ast_channel *ast) |
static enum ast_bridge_result | vpb_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | vpb_call (struct ast_channel *ast, char *dest, int timeout) |
static int | vpb_digit (struct ast_channel *ast, char digit) |
static int | vpb_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | vpb_hangup (struct ast_channel *ast) |
static int | vpb_indicate (struct ast_channel *ast, int condition) |
static struct ast_channel * | vpb_new (struct vpb_pvt *i, int state, char *context) |
static struct ast_frame * | vpb_read (struct ast_channel *ast) |
static struct ast_channel * | vpb_request (const char *type, int format, void *data, int *cause) |
static int | vpb_write (struct ast_channel *ast, struct ast_frame *frame) |
Variables | |
static int | break_for_dtmf = 1 |
static vpb_bridge_t * | bridges |
static VPB_TONE | Busytone = {470, 0, 0, -10, -100, -100, 5000, 0 } |
static const char | config [] = "vpb.conf" |
static char | context [AST_MAX_EXTENSION] = "default" |
static const char | desc [] = "VoiceTronix V6PCI/V12PCI/V4PCI API Support" |
static VPB_TONE | Dialtone = {440, 440, 440, -10, -10, -10, 5000, 0 } |
VPB_TONE_MAP | DialToneMap [] |
static int | dtmf_idd = 3000 |
static int | ec_supp_threshold = -1 |
static int | gruntdetect_timeout = 3600000 |
static struct vpb_pvt * | iflist |
static char | language [MAX_LANGUAGE] = "" |
static int | max_bridges = MAX_BRIDGES_V4PCI |
static pthread_t | monitor_thread |
static int | mthreadactive = -1 |
static const int | prefformat = AST_FORMAT_SLINEAR |
static int | relaxdtmf = 0 |
static VPB_TONE | Ringbacktone = {400, 50, 440, -10, -10, -10, 1400, 800 } |
static const char | tdesc [] = "Standard VoiceTronix API Driver" |
static int | timer_period_ring = TIMER_PERIOD_RING |
static VPB_DETECT | toned_grunt = { 3, VPB_GRUNT, 1, 2000, 3000, 0, 0, -40, 0, 0, 0, 40, { { VPB_DELAY, 1000, 0, 0 }, { VPB_RISING, 0, 40, 0 }, { 0, 100, 0, 0 } } } |
static VPB_DETECT | toned_ungrunt = { 2, VPB_GRUNT, 1, 2000, 1, 0, 0, -40, 0, 0, 30, 40, { { 0, 0, 0, 0 } } } |
static const char | type [] = "vpb" |
static int | use_ast_dtmf = 0 |
static int | use_ast_dtmfdet = 0 |
static int | use_ast_ind = 0 |
static int | usecnt = 0 |
static int | UseLoopDrop = 1 |
static int | UseNativeBridge = 1 |
static int | UsePolarityCID = 0 |
static struct ast_channel_tech | vpb_tech |
static struct ast_channel_tech | vpb_tech_indicate |
Definition in file chan_vpb.c.
|
Definition at line 409 of file chan_vpb.c. |
|
Definition at line 614 of file chan_vpb.c. Referenced by get_callerid(). |
|
Definition at line 73 of file chan_vpb.c. Referenced by load_module(). |
|
Definition at line 72 of file chan_vpb.c. |
|
Definition at line 85 of file chan_vpb.c. |
|
Definition at line 86 of file chan_vpb.c. Referenced by monitor_handle_notowned(). |
|
Definition at line 87 of file chan_vpb.c. Referenced by monitor_handle_notowned(). |
|
Definition at line 218 of file chan_vpb.c. |
|
Definition at line 217 of file chan_vpb.c. Referenced by mkbrd(). |
|
Definition at line 82 of file chan_vpb.c. Referenced by do_chanreads(), mkif(), and vpb_write(). |
|
Definition at line 83 of file chan_vpb.c. Referenced by mkif(). |
|
Definition at line 132 of file chan_vpb.c. |
|
Definition at line 134 of file chan_vpb.c. |
|
Definition at line 133 of file chan_vpb.c. |
|
Definition at line 613 of file chan_vpb.c. Referenced by get_callerid(). |
|
Definition at line 186 of file chan_vpb.c. Referenced by mkif(). |
|
Definition at line 215 of file chan_vpb.c. |
|
Definition at line 187 of file chan_vpb.c. |
|
Definition at line 185 of file chan_vpb.c. Referenced by mkif(). |
|
Definition at line 138 of file chan_vpb.c. |
|
Definition at line 214 of file chan_vpb.c. |
|
Definition at line 212 of file chan_vpb.c. |
|
Value: (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \ |VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \ |VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH) Definition at line 190 of file chan_vpb.c. Referenced by do_chanreads(), and mkif(). |
|
Value: (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \ |VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \ |VPB_MRING_OFF|VPB_MSTATION_FLASH) Definition at line 193 of file chan_vpb.c. |
|
Value: (VPB_MRING|VPB_MDIGIT|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \ |VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \ |VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH) Definition at line 196 of file chan_vpb.c. Referenced by do_chanreads(), and mkif(). |
|
Value: (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \ |VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \ |VPB_MRING_OFF|VPB_MSTATION_FLASH) Definition at line 199 of file chan_vpb.c. Referenced by mkif(). |
|
Definition at line 230 of file chan_vpb.c. Referenced by load_module(), and mkif(). |
|
Definition at line 232 of file chan_vpb.c. Referenced by load_module(), and mkif(). |
|
Definition at line 231 of file chan_vpb.c. Referenced by load_module(), and mkif(). |
|
Definition at line 233 of file chan_vpb.c. Referenced by load_module(), and mkif(). |
|
Definition at line 76 of file chan_vpb.c. |
|
Definition at line 78 of file chan_vpb.c. Referenced by do_monitor(), and restart_monitor(). |
|
Definition at line 213 of file chan_vpb.c. |
|
Definition at line 75 of file chan_vpb.c. Referenced by do_chanreads(), and vpb_write(). |
|
Definition at line 223 of file chan_vpb.c. |
|
Definition at line 225 of file chan_vpb.c. Referenced by monitor_handle_notowned(). |
|
Definition at line 224 of file chan_vpb.c. |
|
Definition at line 222 of file chan_vpb.c. Referenced by vpb_answer(). |
|
Definition at line 221 of file chan_vpb.c. Referenced by monitor_handle_notowned(), and vpb_hangup(). |
|
Definition at line 227 of file chan_vpb.c. Referenced by monitor_handle_notowned(), monitor_handle_owned(), and vpb_indicate(). |
|
Definition at line 226 of file chan_vpb.c. Referenced by monitor_handle_notowned(). |
|
Definition at line 228 of file chan_vpb.c. Referenced by vpb_indicate(). |
|
Definition at line 80 of file chan_vpb.c. Referenced by do_monitor(). |
|
Definition at line 250 of file chan_vpb.c. 00250 { 00251 vpb_model_unknown = 0, 00252 vpb_model_v4pci, 00253 vpb_model_v12pci 00254 } vpb_model_t;
|
|
Definition at line 2235 of file chan_vpb.c. Referenced by do_chanreads(), and vpb_write(). 02236 { 02237 int i; 02238 float tmp; 02239 for ( i = 0; i<n; i++) { 02240 tmp = g*v[i]; 02241 if (tmp > 32767.0) 02242 tmp = 32767.0; 02243 if (tmp < -32768.0) 02244 tmp = -32768.0; 02245 v[i] = (short)tmp; 02246 } 02247 return(i); 02248 }
|
|
Definition at line 2188 of file chan_vpb.c. References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, and AST_FORMAT_ULAW. Referenced by do_chanreads(), and vpb_write(). 02189 { 02190 switch(ast_format) { 02191 case AST_FORMAT_ALAW: 02192 return VPB_ALAW; 02193 case AST_FORMAT_SLINEAR: 02194 return VPB_LINEAR; 02195 case AST_FORMAT_ULAW: 02196 return VPB_MULAW; 02197 case AST_FORMAT_ADPCM: 02198 return VPB_OKIADPCM; 02199 default: 02200 return -1; 02201 } 02202 }
|
|
Definition at line 2204 of file chan_vpb.c. References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, and AST_FORMAT_ULAW. Referenced by do_chanreads(), and vpb_write(). 02205 { 02206 switch(ast_format) { 02207 case AST_FORMAT_ALAW: 02208 return "AST_FORMAT_ALAW:VPB_ALAW"; 02209 case AST_FORMAT_SLINEAR: 02210 return "AST_FORMAT_SLINEAR:VPB_LINEAR"; 02211 case AST_FORMAT_ULAW: 02212 return "AST_FORMAT_ULAW:VPB_MULAW"; 02213 case AST_FORMAT_ADPCM: 02214 return "AST_FORMAT_ADPCM:VPB_OKIADPCM"; 02215 default: 02216 return "UNKN:UNKN"; 02217 } 02218 }
|
|
|
|
|
|
|
|
|
|
Definition at line 2220 of file chan_vpb.c. References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, and AST_FORMAT_ULAW. Referenced by do_chanreads(). 02221 { 02222 switch(ast_format) { 02223 case AST_FORMAT_ALAW: 02224 case AST_FORMAT_ULAW: 02225 return 8; 02226 case AST_FORMAT_SLINEAR: 02227 return 16; 02228 case AST_FORMAT_ADPCM: 02229 return 4; 02230 default: 02231 return 8; 02232 } 02233 }
|
|
Provides a description of the module.
Definition at line 3037 of file chan_vpb.c. 03038 { 03039 return (char *) desc; 03040 }
|
|
Definition at line 2353 of file chan_vpb.c. References ast_channel::_bridge, ast_channel::_state, a_gain_vector(), ast2vpbformat(), ast2vpbformatname(), AST_BRIDGE_REC_CHANNEL_0, AST_BRIDGE_REC_CHANNEL_1, ast_dsp_process(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), AST_STATE_UP, ast_verbose(), astformatbits(), vpb_pvt::bridge, vpb_pvt::buf, vpb_bridge_t::c0, vpb_bridge_t::c1, ast_frame::data, ast_frame::datalen, ast_frame::delivery, vpb_pvt::dev, vpb_bridge_t::flags, fmt, vpb_pvt::fr, ast_frame::frametype, vpb_pvt::handle, vpb_pvt::last_ignore_dtmf, vpb_pvt::lastinput, ast_channel::lock, LOG_DEBUG, ast_frame::mallocd, MAX_VPB_GAIN, ast_channel::name, ast_frame::offset, option_verbose, vpb_pvt::owner, pbx_builtin_getvar_helper(), vpb_pvt::play_dtmf, vpb_pvt::play_dtmf_lock, ast_channel::rawreadformat, vpb_pvt::read_state, vpb_pvt::record_lock, vpb_pvt::rxswgain, ast_frame::samples, ast_frame::src, vpb_pvt::stopreads, ast_frame::subclass, vpb_pvt::vad, VERBOSE_PREFIX_2, VPB_EVENTS_ALL, VPB_EVENTS_NODTMF, and VPB_SAMPLES. Referenced by vpb_answer(). 02354 { 02355 struct vpb_pvt *p = (struct vpb_pvt *)pvt; 02356 struct ast_frame *fr = &p->fr; 02357 char *readbuf = ((char *)p->buf) + AST_FRIENDLY_OFFSET; 02358 int bridgerec = 0; 02359 int afmt, readlen, res, fmt, trycnt=0; 02360 int ignore_dtmf; 02361 char * getdtmf_var = NULL; 02362 02363 fr->frametype = AST_FRAME_VOICE; 02364 fr->src = (char *)type; 02365 fr->mallocd = 0; 02366 fr->delivery.tv_sec = 0; 02367 fr->delivery.tv_usec = 0; 02368 fr->samples = VPB_SAMPLES; 02369 fr->offset = AST_FRIENDLY_OFFSET; 02370 memset(p->buf, 0, sizeof p->buf); 02371 02372 if (option_verbose > 2) { 02373 ast_verbose("%s: chanreads: starting thread\n", p->dev); 02374 } 02375 ast_mutex_lock(&p->record_lock); 02376 02377 p->stopreads = 0; 02378 p->read_state = 1; 02379 while (!p->stopreads && p->owner) { 02380 02381 if (option_verbose > 4) 02382 ast_verbose("%s: chanreads: Starting cycle ...\n", p->dev); 02383 if (option_verbose > 4) 02384 ast_verbose("%s: chanreads: Checking bridge \n", p->dev); 02385 if (p->bridge) { 02386 if (p->bridge->c0 == p->owner && (p->bridge->flags & AST_BRIDGE_REC_CHANNEL_0)) 02387 bridgerec = 1; 02388 else if (p->bridge->c1 == p->owner && (p->bridge->flags & AST_BRIDGE_REC_CHANNEL_1)) 02389 bridgerec = 1; 02390 else 02391 bridgerec = 0; 02392 } else { 02393 if (option_verbose > 4) 02394 ast_verbose("%s: chanreads: No native bridge.\n", p->dev); 02395 if (p->owner->_bridge){ 02396 if (option_verbose > 4){ 02397 ast_verbose("%s: chanreads: Got Asterisk bridge with [%s].\n", p->dev,p->owner->_bridge->name); 02398 } 02399 bridgerec = 1; 02400 } 02401 else { 02402 bridgerec = 0; 02403 } 02404 } 02405 02406 /* if ( (p->owner->_state != AST_STATE_UP) || !bridgerec) */ 02407 if ( (p->owner->_state != AST_STATE_UP) ) 02408 { 02409 if (option_verbose > 4) { 02410 if (p->owner->_state != AST_STATE_UP) 02411 ast_verbose("%s: chanreads: Im not up[%d]\n", p->dev,p->owner->_state); 02412 else 02413 ast_verbose("%s: chanreads: No bridgerec[%d]\n", p->dev,bridgerec); 02414 } 02415 vpb_sleep(10); 02416 continue; 02417 } 02418 02419 /* Voicetronix DTMF detection can be triggered off ordinary speech 02420 * This leads to annoying beeps during the conversation 02421 * Avoid this problem by just setting VPB_GETDTMF when you want to listen for DTMF 02422 */ 02423 /* ignore_dtmf = 1; */ 02424 ignore_dtmf = 0; /* set this to 1 to turn this feature on */ 02425 getdtmf_var = pbx_builtin_getvar_helper(p->owner,"VPB_GETDTMF"); 02426 if( getdtmf_var && ( strcasecmp( getdtmf_var, "yes" ) == 0 ) ) 02427 ignore_dtmf = 0; 02428 02429 if(( ignore_dtmf != p->last_ignore_dtmf ) &&(!use_ast_dtmfdet)){ 02430 if(option_verbose>1) 02431 ast_verbose( VERBOSE_PREFIX_2 "%s:Now %s DTMF \n", 02432 p->dev, ignore_dtmf ? "ignoring" : "listening for"); 02433 vpb_set_event_mask(p->handle, ignore_dtmf ? VPB_EVENTS_NODTMF : VPB_EVENTS_ALL ); 02434 } 02435 p->last_ignore_dtmf = ignore_dtmf; 02436 02437 /* Play DTMF digits here to avoid problem you get if playing a digit during 02438 * a record operation 02439 */ 02440 if (option_verbose > 5) { 02441 ast_verbose("%s: chanreads: Checking dtmf's \n", p->dev); 02442 } 02443 ast_mutex_lock(&p->play_dtmf_lock); 02444 if( p->play_dtmf[0] ) { 02445 /* Try to ignore DTMF event we get after playing digit */ 02446 /* This DTMF is played by asterisk and leads to an annoying trailing beep on CISCO phones */ 02447 if( !ignore_dtmf) 02448 vpb_set_event_mask(p->handle, VPB_EVENTS_NODTMF ); 02449 if (p->bridge == NULL){ 02450 vpb_dial_sync(p->handle,p->play_dtmf); 02451 if(option_verbose>1) 02452 ast_verbose( VERBOSE_PREFIX_2 "%s: chanreads: Played DTMF %s\n",p->dev,p->play_dtmf); 02453 } 02454 else { 02455 if (option_verbose > 1) 02456 ast_verbose(VERBOSE_PREFIX_2 "%s: chanreads: Not playing DTMF frame on native bridge\n", p->dev); 02457 } 02458 p->play_dtmf[0] = '\0'; 02459 ast_mutex_unlock(&p->play_dtmf_lock); 02460 vpb_sleep(700); /* Long enough to miss echo and DTMF event */ 02461 if( !ignore_dtmf) 02462 vpb_set_event_mask(p->handle, VPB_EVENTS_ALL ); 02463 continue; 02464 } 02465 ast_mutex_unlock(&p->play_dtmf_lock); 02466 02467 /* afmt = (p->owner) ? p->owner->rawreadformat : AST_FORMAT_SLINEAR; */ 02468 if (p->owner){ 02469 afmt = p->owner->rawreadformat; 02470 /* ast_log(LOG_DEBUG,"%s: Record using owner format [%s]\n", p->dev, ast2vpbformatname(afmt)); */ 02471 } 02472 else { 02473 afmt = AST_FORMAT_SLINEAR; 02474 /* ast_log(LOG_DEBUG,"%s: Record using default format [%s]\n", p->dev, ast2vpbformatname(afmt)); */ 02475 } 02476 fmt = ast2vpbformat(afmt); 02477 if (fmt < 0) { 02478 ast_log(LOG_WARNING,"%s: Record failure (unsupported format %d)\n", p->dev, afmt); 02479 return NULL; 02480 } 02481 readlen = VPB_SAMPLES * astformatbits(afmt) / 8; 02482 02483 if (p->lastinput == -1) { 02484 vpb_record_buf_start(p->handle, fmt); 02485 vpb_reset_record_fifo_alarm(p->handle); 02486 p->lastinput = fmt; 02487 if(option_verbose>1) 02488 ast_verbose( VERBOSE_PREFIX_2 "%s: Starting record mode (codec=%d)[%s]\n",p->dev,fmt,ast2vpbformatname(afmt)); 02489 continue; 02490 } else if (p->lastinput != fmt) { 02491 vpb_record_buf_finish(p->handle); 02492 vpb_record_buf_start(p->handle, fmt); 02493 p->lastinput = fmt; 02494 if(option_verbose>1) 02495 ast_verbose( VERBOSE_PREFIX_2 "%s: Changed record format (%d=>%d)\n",p->dev,p->lastinput,fmt); 02496 continue; 02497 } 02498 02499 /* Read only if up and not bridged, or a bridge for which we can read. */ 02500 if (option_verbose > 5) { 02501 ast_verbose("%s: chanreads: getting buffer!\n", p->dev); 02502 } 02503 if( (res = vpb_record_buf_sync(p->handle, readbuf, readlen) ) == VPB_OK ) { 02504 if (option_verbose > 5) { 02505 ast_verbose("%s: chanreads: got buffer!\n", p->dev); 02506 } 02507 /* Apply extra gain ! */ 02508 if( p->rxswgain > MAX_VPB_GAIN ) 02509 a_gain_vector(p->rxswgain - MAX_VPB_GAIN , (short*)readbuf, readlen/sizeof(short)); 02510 if (option_verbose > 5) { 02511 ast_verbose("%s: chanreads: applied gain\n", p->dev); 02512 } 02513 02514 fr->subclass = afmt; 02515 fr->data = readbuf; 02516 fr->datalen = readlen; 02517 fr->frametype = AST_FRAME_VOICE; 02518 02519 if ((use_ast_dtmfdet)&&(p->vad)){ 02520 fr = ast_dsp_process(p->owner,p->vad,fr); 02521 if (fr && (fr->frametype == AST_FRAME_DTMF)) 02522 ast_log(LOG_DEBUG, "%s: chanreads: Detected DTMF '%c'\n",p->dev, fr->subclass); 02523 if (fr->subclass == 'm'){ 02524 /* conf mute request */ 02525 fr->frametype = AST_FRAME_NULL; 02526 fr->subclass = 0; 02527 } 02528 else if (fr->subclass == 'u'){ 02529 /* Unmute */ 02530 fr->frametype = AST_FRAME_NULL; 02531 fr->subclass = 0; 02532 } 02533 else if (fr->subclass == 'f'){ 02534 } 02535 } 02536 /* Using trylock here to prevent deadlock when channel is hungup 02537 * (ast_hangup() immediately gets lock) 02538 */ 02539 if (p->owner && !p->stopreads ) { 02540 if (option_verbose > 5) { 02541 ast_verbose("%s: chanreads: queueing buffer on read frame q (state[%d])\n", p->dev,p->owner->_state); 02542 } 02543 do { 02544 res = ast_mutex_trylock(&p->owner->lock); 02545 trycnt++; 02546 } while((res !=0)&&(trycnt<300)); 02547 if (res==0) { 02548 ast_queue_frame(p->owner, fr); 02549 ast_mutex_unlock(&p->owner->lock); 02550 } else { 02551 if (option_verbose > 4) 02552 ast_verbose("%s: chanreads: Couldnt get lock after %d tries!\n", p->dev,trycnt); 02553 } 02554 trycnt=0; 02555 02556 /* 02557 res = ast_mutex_trylock(&p->owner->lock); 02558 if (res==0) { 02559 ast_queue_frame(p->owner, fr); 02560 ast_mutex_unlock(&p->owner->lock); 02561 } else { 02562 if (res == EINVAL ) 02563 if (option_verbose > 4) ast_verbose("%s: chanreads: try owner->lock gave me EINVAL[%d]\n", p->dev,res); 02564 else if (res == EBUSY ) 02565 if (option_verbose > 4) ast_verbose("%s: chanreads: try owner->lock gave me EBUSY[%d]\n", p->dev,res); 02566 while(res !=0){ 02567 res = ast_mutex_trylock(&p->owner->lock); 02568 } 02569 if (res==0) { 02570 ast_queue_frame(p->owner, fr); 02571 ast_mutex_unlock(&p->owner->lock); 02572 } 02573 else { 02574 if (res == EINVAL ) 02575 if (option_verbose > 4) ast_verbose("%s: chanreads: try owner->lock gave me EINVAL[%d]\n", p->dev,res); 02576 else if (res == EBUSY ) 02577 if (option_verbose > 4) ast_verbose("%s: chanreads: try owner->lock gave me EBUSY[%d]\n", p->dev,res); 02578 if (option_verbose > 4) ast_verbose("%s: chanreads: Couldnt get lock on owner[%s][%d][%d] channel to send frame!\n", p->dev,p->owner->name,(int)p->owner->lock.__m_owner,(int)p->owner->lock.__m_count); 02579 } 02580 } 02581 */ 02582 if (option_verbose > 6) { 02583 short * data = (short*)readbuf; 02584 ast_verbose("%s: Read channel (codec=%d) %d %d\n", p->dev, fmt, data[0], data[1] ); 02585 } 02586 } 02587 else { 02588 if (option_verbose > 4) { 02589 ast_verbose("%s: p->stopreads[%d] p->owner[%p]\n", p->dev, p->stopreads,(void *)p->owner); 02590 } 02591 } 02592 } 02593 if (option_verbose > 4) 02594 ast_verbose("%s: chanreads: Finished cycle...\n", p->dev); 02595 } 02596 p->read_state=0; 02597 02598 /* When stopreads seen, go away! */ 02599 vpb_record_buf_finish(p->handle); 02600 p->read_state=0; 02601 ast_mutex_unlock(&p->record_lock); 02602 02603 if (option_verbose > 1) 02604 ast_verbose(VERBOSE_PREFIX_2 "%s: Ending record mode (%d/%s)\n", 02605 p->dev, p->stopreads, p->owner? "yes" : "no"); 02606 return NULL; 02607 }
|
|
Definition at line 1320 of file chan_vpb.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), vpb_pvt::dev, vpb_pvt::golock, vpb_pvt::handle, iflist, LOG_ERROR, LOG_WARNING, monitor_handle_notowned(), monitor_handle_owned(), vpb_pvt::next, option_verbose, vpb_pvt::owner, VERBOSE_PREFIX_2, VERBOSE_PREFIX_4, VPB_NULL_EVENT, and VPB_WAIT_TIMEOUT. 01321 { 01322 01323 /* Monitor thread, doesn't die until explicitly killed. */ 01324 01325 if (option_verbose > 1) 01326 ast_verbose(VERBOSE_PREFIX_2 "Starting vpb monitor thread[%ld]\n", 01327 pthread_self()); 01328 01329 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 01330 01331 for(;;) { 01332 VPB_EVENT e; 01333 VPB_EVENT je; 01334 char str[VPB_MAX_STR]; 01335 struct vpb_pvt *p; 01336 01337 /* 01338 if (option_verbose > 3) 01339 ast_verbose(VERBOSE_PREFIX_4 "Monitor waiting for event\n"); 01340 */ 01341 01342 int res = vpb_get_event_sync(&e, VPB_WAIT_TIMEOUT); 01343 if( (res==VPB_NO_EVENTS) || (res==VPB_TIME_OUT) ){ 01344 /* 01345 if (option_verbose > 3){ 01346 if (res == VPB_NO_EVENTS){ 01347 ast_verbose(VERBOSE_PREFIX_4 "No events....\n"); 01348 } else { 01349 ast_verbose(VERBOSE_PREFIX_4 "No events, timed out....\n"); 01350 } 01351 } 01352 */ 01353 continue; 01354 } 01355 01356 if (res != VPB_OK) { 01357 ast_log(LOG_ERROR,"Monitor get event error %s\n", vpb_strerror(res) ); 01358 ast_verbose("Monitor get event error %s\n", vpb_strerror(res) ); 01359 continue; 01360 } 01361 01362 str[0] = 0; 01363 01364 p = NULL; 01365 01366 ast_mutex_lock(&monlock); { 01367 01368 if (e.type == VPB_NULL_EVENT) { 01369 if (option_verbose > 3) 01370 ast_verbose(VERBOSE_PREFIX_4 "Monitor got null event\n"); 01371 } 01372 else { 01373 vpb_translate_event(&e, str); 01374 if (strlen(str)>1){ 01375 str[(strlen(str)-1)]='\0'; 01376 } 01377 01378 ast_mutex_lock(&iflock); { 01379 p = iflist; 01380 while (p && p->handle != e.handle) 01381 p = p->next; 01382 } ast_mutex_unlock(&iflock); 01383 01384 if (p && (option_verbose > 3)) 01385 ast_verbose(VERBOSE_PREFIX_4 "%s: Event [%d=>%s] \n", 01386 p ? p->dev : "null", e.type, str ); 01387 } 01388 01389 } ast_mutex_unlock(&monlock); 01390 01391 if (!p) { 01392 if (e.type != VPB_NULL_EVENT){ 01393 ast_log(LOG_WARNING, "Got event [%s][%d], no matching iface!\n", str,e.type); 01394 if (option_verbose > 3){ 01395 ast_verbose(VERBOSE_PREFIX_4 "vpb/ERR: No interface for Event [%d=>%s] \n",e.type,str ); 01396 } 01397 } 01398 continue; 01399 } 01400 01401 /* flush the event from the channel event Q */ 01402 vpb_get_event_ch_async(e.handle,&je); 01403 if (option_verbose > 4){ 01404 vpb_translate_event(&je, str); 01405 ast_verbose("%s: Flushing event [%d]=>%s\n",p->dev,je.type,str); 01406 } 01407 01408 /* Check for ownership and locks */ 01409 if ((p->owner)&&(!p->golock)){ 01410 /* Need to get owner lock */ 01411 /* Safely grab both p->lock and p->owner->lock so that there 01412 cannot be a race with something from the other side */ 01413 /* 01414 ast_mutex_lock(&p->lock); 01415 while(ast_mutex_trylock(&p->owner->lock)) { 01416 ast_mutex_unlock(&p->lock); 01417 usleep(1); 01418 ast_mutex_lock(&p->lock); 01419 if (!p->owner) 01420 break; 01421 } 01422 if (p->owner) 01423 p->golock=1; 01424 */ 01425 } 01426 /* Two scenarios: Are you owned or not. */ 01427 if (p->owner) { 01428 monitor_handle_owned(p, &e); 01429 } else { 01430 monitor_handle_notowned(p, &e); 01431 } 01432 /* if ((!p->owner)&&(p->golock)){ 01433 ast_mutex_unlock(&p->owner->lock); 01434 ast_mutex_unlock(&p->lock); 01435 } 01436 */ 01437 01438 } 01439 01440 return NULL; 01441 }
|
|
Definition at line 616 of file chan_vpb.c. References ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_set_callerid(), ast_verbose(), vpb_pvt::buf, vpb_pvt::callerid, ast_channel::cid, CID_MSECS, ast_callerid::cid_name, vpb_pvt::cid_name, ast_callerid::cid_num, vpb_pvt::cid_num, vpb_pvt::dev, vpb_pvt::handle, LOG_ERROR, option_verbose, vpb_pvt::owner, vpb_pvt::record_lock, RING_SKIP, and VERBOSE_PREFIX_4. Referenced by monitor_handle_notowned(). 00617 { 00618 short buf[CID_MSECS*8]; /* 8kHz sampling rate */ 00619 struct timeval cid_record_time; 00620 int rc; 00621 struct ast_channel *owner = p->owner; 00622 /* 00623 char callerid[AST_MAX_EXTENSION] = ""; 00624 */ 00625 #ifdef ANALYSE_CID 00626 void * ws; 00627 char * file="cidsams.wav"; 00628 #endif 00629 00630 00631 if( ast_mutex_trylock(&p->record_lock) == 0 ) { 00632 00633 cid_record_time = ast_tvnow(); 00634 if (option_verbose>3) 00635 ast_verbose(VERBOSE_PREFIX_4 "CID record - start\n"); 00636 00637 /* Skip any trailing ringtone */ 00638 if (UsePolarityCID != 1){ 00639 vpb_sleep(RING_SKIP); 00640 } 00641 00642 if (option_verbose>3) 00643 ast_verbose(VERBOSE_PREFIX_4 "CID record - skipped %ldms trailing ring\n", 00644 ast_tvdiff_ms(ast_tvnow(), cid_record_time)); 00645 cid_record_time = ast_tvnow(); 00646 00647 /* Record bit between the rings which contains the callerid */ 00648 vpb_record_buf_start(p->handle, VPB_LINEAR); 00649 rc = vpb_record_buf_sync(p->handle, (char*)buf, sizeof(buf)); 00650 vpb_record_buf_finish(p->handle); 00651 #ifdef ANALYSE_CID 00652 vpb_wave_open_write(&ws, file, VPB_LINEAR); 00653 vpb_wave_write(ws,(char*)buf,sizeof(buf)); 00654 vpb_wave_close_write(ws); 00655 #endif 00656 00657 if (option_verbose>3) 00658 ast_verbose(VERBOSE_PREFIX_4 "CID record - recorded %ldms between rings\n", 00659 ast_tvdiff_ms(ast_tvnow(), cid_record_time)); 00660 00661 ast_mutex_unlock(&p->record_lock); 00662 00663 if( rc != VPB_OK ) { 00664 ast_log(LOG_ERROR, "Failed to record caller id sample on %s\n", p->dev ); 00665 return; 00666 } 00667 00668 VPB_CID *cli_struct = new VPB_CID; 00669 cli_struct->ra_cldn[0]=0; 00670 cli_struct->ra_cn[0]=0; 00671 /* This decodes FSK 1200baud type callerid */ 00672 if ((rc=vpb_cid_decode2(cli_struct, buf, CID_MSECS*8)) == VPB_OK ) { 00673 /* 00674 if (owner->cid.cid_num) 00675 free(owner->cid.cid_num); 00676 owner->cid.cid_num=NULL; 00677 if (owner->cid.cid_name) 00678 free(owner->cid.cid_name); 00679 owner->cid.cid_name=NULL; 00680 */ 00681 00682 if (cli_struct->ra_cldn[0]=='\0'){ 00683 /* 00684 owner->cid.cid_num = strdup(cli_struct->cldn); 00685 owner->cid.cid_name = strdup(cli_struct->cn); 00686 */ 00687 if (owner){ 00688 ast_set_callerid(owner, cli_struct->cldn, cli_struct->cn, cli_struct->cldn); 00689 } else { 00690 strcpy(p->cid_num, cli_struct->cldn); 00691 strcpy(p->cid_name, cli_struct->cn); 00692 00693 } 00694 if (option_verbose>3) 00695 ast_verbose(VERBOSE_PREFIX_4 "CID record - got [%s] [%s]\n",owner->cid.cid_num,owner->cid.cid_name ); 00696 snprintf(p->callerid,sizeof(p->callerid)-1,"%s %s",cli_struct->cldn,cli_struct->cn); 00697 } 00698 else { 00699 ast_log(LOG_ERROR,"CID record - No caller id avalable on %s \n", p->dev); 00700 } 00701 00702 } else { 00703 ast_log(LOG_ERROR, "CID record - Failed to decode caller id on %s - %s\n", p->dev, vpb_strerror(rc) ); 00704 strncpy(p->callerid,"unknown", sizeof(p->callerid) - 1); 00705 } 00706 delete cli_struct; 00707 00708 } else 00709 ast_log(LOG_ERROR, "CID record - Failed to set record mode for caller id on %s\n", p->dev ); 00710 }
|
|
Definition at line 712 of file chan_vpb.c. References AST_FORMAT_ULAW, ast_log(), ast_shrink_phone_number(), ast_strlen_zero(), ast_verbose(), vpb_pvt::callerid, callerid_feed(), callerid_free(), callerid_get(), callerid_new(), vpb_pvt::callerid_type, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, CID_SIG_BELL, CID_SIG_V23, vpb_pvt::dev, callerid_state::flags, free, vpb_pvt::handle, LOG_ERROR, name, callerid_state::number, option_verbose, vpb_pvt::owner, strdup, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_4. Referenced by monitor_handle_notowned(). 00713 { 00714 struct callerid_state *cs; 00715 char buf[1024]; 00716 char *name=NULL, *number=NULL; 00717 int flags; 00718 int rc=0,vrc; 00719 int sam_count=0; 00720 struct ast_channel *owner = p->owner; 00721 int which_cid; 00722 /* 00723 float old_gain; 00724 */ 00725 #ifdef ANALYSE_CID 00726 void * ws; 00727 char * file="cidsams.wav"; 00728 #endif 00729 00730 if(p->callerid_type == 1) { 00731 if (option_verbose>3) ast_verbose(VERBOSE_PREFIX_4 "Collected caller ID already\n"); 00732 return; 00733 } 00734 else if(p->callerid_type == 2 ) { 00735 which_cid=CID_SIG_V23; 00736 if (option_verbose>3) ast_verbose(VERBOSE_PREFIX_4 "Collecting Caller ID v23...\n"); 00737 } 00738 else if(p->callerid_type == 3) { 00739 which_cid=CID_SIG_BELL; 00740 if (option_verbose>3) ast_verbose(VERBOSE_PREFIX_4 "Collecting Caller ID bell...\n"); 00741 } 00742 else { 00743 if (option_verbose>3) 00744 ast_verbose(VERBOSE_PREFIX_4 "Caller ID disabled\n"); 00745 return; 00746 } 00747 /* vpb_sleep(RING_SKIP); */ 00748 /* vpb_record_get_gain(p->handle, &old_gain); */ 00749 cs = callerid_new(which_cid); 00750 if (cs){ 00751 #ifdef ANALYSE_CID 00752 vpb_wave_open_write(&ws, file, VPB_MULAW); 00753 vpb_record_set_gain(p->handle, 3.0); 00754 vpb_record_set_hw_gain(p->handle,12.0); 00755 #endif 00756 vpb_record_buf_start(p->handle, VPB_MULAW); 00757 while((rc == 0)&&(sam_count<8000*3)){ 00758 vrc = vpb_record_buf_sync(p->handle, (char*)buf, sizeof(buf)); 00759 if (vrc != VPB_OK) 00760 ast_log(LOG_ERROR, "%s: Caller ID couldnt read audio buffer!\n",p->dev); 00761 rc = callerid_feed(cs,(unsigned char *)buf,sizeof(buf),AST_FORMAT_ULAW); 00762 #ifdef ANALYSE_CID 00763 vpb_wave_write(ws,(char*)buf,sizeof(buf)); 00764 #endif 00765 sam_count+=sizeof(buf); 00766 if (option_verbose>3) ast_verbose(VERBOSE_PREFIX_4 "Collecting Caller ID samples [%d][%d]...\n",sam_count,rc); 00767 } 00768 vpb_record_buf_finish(p->handle); 00769 #ifdef ANALYSE_CID 00770 vpb_wave_close_write(ws); 00771 #endif 00772 if (rc == 1){ 00773 callerid_get(cs, &name, &number, &flags); 00774 if (option_verbose>0) 00775 ast_verbose(VERBOSE_PREFIX_1 "%s: Caller ID name [%s] number [%s] flags [%d]\n",p->dev,name, number,flags); 00776 } 00777 else { 00778 ast_log(LOG_ERROR, "%s: Failed to decode Caller ID \n", p->dev ); 00779 } 00780 /* vpb_record_set_gain(p->handle, old_gain); */ 00781 /* vpb_record_set_hw_gain(p->handle,6.0); */ 00782 } 00783 else { 00784 ast_log(LOG_ERROR, "%s: Failed to create Caller ID struct\n", p->dev ); 00785 } 00786 if (owner->cid.cid_num) { 00787 free(owner->cid.cid_num); 00788 owner->cid.cid_num = NULL; 00789 } 00790 if (owner->cid.cid_name) { 00791 free(owner->cid.cid_name); 00792 owner->cid.cid_name = NULL; 00793 } 00794 if (number) 00795 ast_shrink_phone_number(number); 00796 if (!ast_strlen_zero(number)) { 00797 owner->cid.cid_num = strdup(number); 00798 owner->cid.cid_ani = strdup(number); 00799 if (!ast_strlen_zero(name)){ 00800 owner->cid.cid_name = strdup(name); 00801 snprintf(p->callerid,(sizeof(p->callerid)-1),"%s %s",number,name); 00802 } 00803 else { 00804 snprintf(p->callerid,(sizeof(p->callerid)-1),"%s",number); 00805 } 00806 } 00807 00808 if (cs) 00809 callerid_free(cs); 00810 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 3042 of file chan_vpb.c. References ASTERISK_GPL_KEY. 03043 { 03044 return ASTERISK_GPL_KEY; 03045 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 2770 of file chan_vpb.c. References ast_channel_register(), ast_config_destroy(), ast_config_load(), ast_get_group(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), vpb_pvt::callerid, vpb_pvt::callgroup, cfg, DEFAULT_ECHO_CANCEL, DEFAULT_GAIN, error(), group, iflist, LOG_ERROR, LOG_NOTICE, mkbrd(), mkif(), vpb_pvt::mode, MODE_DIALTONE, MODE_FXO, MODE_IMMEDIATE, ast_variable::name, vpb_pvt::next, ast_variable::next, parse_gain_value(), vpb_pvt::pickupgroup, restart_monitor(), rxgain, vpb_pvt::rxswgain, strdup, txgain, vpb_pvt::txswgain, unload_module(), ast_variable::value, VPB_GOT_RXHWG, VPB_GOT_RXSWG, VPB_GOT_TXHWG, VPB_GOT_TXSWG, vpb_pvt::vpb_model, vpb_tech, and vpb_tech_indicate. 02771 { 02772 struct ast_config *cfg; 02773 struct ast_variable *v; 02774 struct vpb_pvt *tmp; 02775 int board = 0, group = 0; 02776 ast_group_t callgroup = 0; 02777 ast_group_t pickupgroup = 0; 02778 int mode = MODE_IMMEDIATE; 02779 float txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; 02780 float txswgain = 0, rxswgain = 0; 02781 int got_gain=0; 02782 int first_channel = 1; 02783 int echo_cancel = DEFAULT_ECHO_CANCEL; 02784 int error = 0; /* Error flag */ 02785 int bal1 = -1; /* Special value - means do not set */ 02786 int bal2 = -1; 02787 int bal3 = -1; 02788 char * callerid = NULL; 02789 02790 cfg = ast_config_load(config); 02791 02792 /* We *must* have a config file otherwise stop immediately */ 02793 if (!cfg) { 02794 ast_log(LOG_ERROR, "Unable to load config %s\n", config); 02795 return -1; 02796 } 02797 02798 vpb_seterrormode(VPB_ERROR_CODE); 02799 02800 ast_mutex_lock(&iflock); { 02801 v = ast_variable_browse(cfg, "general"); 02802 while (v){ 02803 if (strcasecmp(v->name, "cards") == 0) { 02804 ast_log(LOG_NOTICE,"VPB Driver configured to use [%d] cards\n",atoi(v->value)); 02805 } 02806 else if (strcasecmp(v->name, "indication") == 0) { 02807 use_ast_ind = 1; 02808 ast_log(LOG_NOTICE,"VPB driver using Asterisk Indication functions!\n"); 02809 } 02810 else if (strcasecmp(v->name, "break-for-dtmf") == 0) { 02811 if (ast_true(v->value)){ 02812 break_for_dtmf = 1; 02813 } 02814 else { 02815 break_for_dtmf = 0; 02816 ast_log(LOG_NOTICE,"VPB driver not stopping for DTMF's in native bridge\n"); 02817 } 02818 } 02819 else if (strcasecmp(v->name, "ast-dtmf") == 0) { 02820 use_ast_dtmf = 1; 02821 ast_log(LOG_NOTICE,"VPB driver using Asterisk DTMF play functions!\n"); 02822 } 02823 else if (strcasecmp(v->name, "ast-dtmf-det") == 0) { 02824 use_ast_dtmfdet = 1; 02825 ast_log(LOG_NOTICE,"VPB driver using Asterisk DTMF detection functions!\n"); 02826 } 02827 else if (strcasecmp(v->name, "relaxdtmf") == 0) { 02828 relaxdtmf = 1; 02829 ast_log(LOG_NOTICE,"VPB driver using Relaxed DTMF with Asterisk DTMF detections functions!\n"); 02830 } 02831 else if (strcasecmp(v->name, "timer_period_ring") ==0) { 02832 timer_period_ring = atoi(v->value); 02833 } 02834 else if (strcasecmp(v->name, "ecsuppthres") ==0) { 02835 ec_supp_threshold = atoi(v->value); 02836 } 02837 else if (strcasecmp(v->name, "dtmfidd") ==0) { 02838 dtmf_idd = atoi(v->value); 02839 ast_log(LOG_NOTICE,"VPB Driver setting DTMF IDD to [%d]ms\n",dtmf_idd); 02840 } 02841 v = v->next; 02842 } 02843 02844 v = ast_variable_browse(cfg, "interfaces"); 02845 while(v) { 02846 /* Create the interface list */ 02847 if (strcasecmp(v->name, "board") == 0) { 02848 board = atoi(v->value); 02849 } else if (strcasecmp(v->name, "group") == 0){ 02850 group = atoi(v->value); 02851 } else if (strcasecmp(v->name, "callgroup") == 0){ 02852 callgroup = ast_get_group(v->value); 02853 } else if (strcasecmp(v->name, "pickupgroup") == 0){ 02854 pickupgroup = ast_get_group(v->value); 02855 } else if (strcasecmp(v->name, "usepolaritycid") == 0){ 02856 UsePolarityCID = atoi(v->value); 02857 } else if (strcasecmp(v->name, "useloopdrop") == 0){ 02858 UseLoopDrop = atoi(v->value); 02859 } else if (strcasecmp(v->name, "usenativebridge") == 0){ 02860 UseNativeBridge = atoi(v->value); 02861 } else if (strcasecmp(v->name, "channel") == 0) { 02862 int channel = atoi(v->value); 02863 tmp = mkif(board, channel, mode, got_gain, txgain, rxgain, txswgain, rxswgain, bal1, bal2, bal3, callerid, echo_cancel,group,callgroup,pickupgroup); 02864 if (tmp) { 02865 if(first_channel) { 02866 mkbrd( tmp->vpb_model, echo_cancel ); 02867 first_channel = 0; 02868 } 02869 tmp->next = iflist; 02870 iflist = tmp; 02871 } else { 02872 ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value); 02873 error = -1; 02874 goto done; 02875 } 02876 } else if (strcasecmp(v->name, "language") == 0) { 02877 strncpy(language, v->value, sizeof(language)-1); 02878 } else if (strcasecmp(v->name, "callerid") == 0) { 02879 callerid = strdup(v->value); 02880 } else if (strcasecmp(v->name, "mode") == 0) { 02881 if (strncasecmp(v->value, "di", 2) == 0) 02882 mode = MODE_DIALTONE; 02883 else if (strncasecmp(v->value, "im", 2) == 0) 02884 mode = MODE_IMMEDIATE; 02885 else if (strncasecmp(v->value, "fx", 2) == 0) 02886 mode = MODE_FXO; 02887 else 02888 ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value); 02889 } else if (!strcasecmp(v->name, "context")) { 02890 strncpy(context, v->value, sizeof(context)-1); 02891 } else if (!strcasecmp(v->name, "echocancel")) { 02892 if (!strcasecmp(v->value, "off")) 02893 echo_cancel = 0; 02894 } else if (strcasecmp(v->name, "txgain") == 0) { 02895 txswgain = parse_gain_value(v->name, v->value); 02896 got_gain |=VPB_GOT_TXSWG; 02897 } else if (strcasecmp(v->name, "rxgain") == 0) { 02898 rxswgain = parse_gain_value(v->name, v->value); 02899 got_gain |=VPB_GOT_RXSWG; 02900 } else if (strcasecmp(v->name, "txhwgain") == 0) { 02901 txgain = parse_gain_value(v->name, v->value); 02902 got_gain |=VPB_GOT_TXHWG; 02903 } else if (strcasecmp(v->name, "rxhwgain") == 0) { 02904 rxgain = parse_gain_value(v->name, v->value); 02905 got_gain |=VPB_GOT_RXHWG; 02906 } else if (strcasecmp(v->name, "bal1") == 0) { 02907 bal1 = strtol(v->value, NULL, 16); 02908 if(bal1<0 || bal1>255) { 02909 ast_log(LOG_WARNING, "Bad bal1 value: %d\n", bal1); 02910 bal1 = -1; 02911 } 02912 } else if (strcasecmp(v->name, "bal2") == 0) { 02913 bal2 = strtol(v->value, NULL, 16); 02914 if(bal2<0 || bal2>255) { 02915 ast_log(LOG_WARNING, "Bad bal2 value: %d\n", bal2); 02916 bal2 = -1; 02917 } 02918 } else if (strcasecmp(v->name, "bal3") == 0) { 02919 bal3 = strtol(v->value, NULL, 16); 02920 if(bal3<0 || bal3>255) { 02921 ast_log(LOG_WARNING, "Bad bal3 value: %d\n", bal3); 02922 bal3 = -1; 02923 } 02924 } else if (strcasecmp(v->name, "grunttimeout") == 0) { 02925 gruntdetect_timeout = 1000*atoi(v->value); 02926 } 02927 v = v->next; 02928 } 02929 02930 if (gruntdetect_timeout < 1000) 02931 gruntdetect_timeout = 1000; 02932 02933 done: (void)0; 02934 } ast_mutex_unlock(&iflock); 02935 02936 ast_config_destroy(cfg); 02937 02938 if (use_ast_ind == 1){ 02939 if (!error && ast_channel_register(&vpb_tech_indicate) != 0) { 02940 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 02941 error = -1; 02942 } 02943 else { 02944 ast_log(LOG_NOTICE,"VPB driver Registered (w/AstIndication)\n"); 02945 } 02946 } 02947 else { 02948 if (!error && ast_channel_register(&vpb_tech) != 0) { 02949 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 02950 error = -1; 02951 } 02952 else { 02953 ast_log(LOG_NOTICE,"VPB driver Registered )\n"); 02954 } 02955 } 02956 02957 02958 if (error) 02959 unload_module(); 02960 else 02961 restart_monitor(); /* And start the monitor for the first time */ 02962 02963 return error; 02964 }
|
|
Definition at line 1494 of file chan_vpb.c. References ast_cond_init(), ast_log(), ast_mutex_init(), bridges, lock, LOG_ERROR, malloc, MAX_BRIDGES_V4PCI, and vpb_model_v4pci. Referenced by load_module(). 01495 { 01496 if(!bridges) { 01497 if(model==vpb_model_v4pci) 01498 max_bridges = MAX_BRIDGES_V4PCI; 01499 bridges = (vpb_bridge_t *)malloc(max_bridges * sizeof(vpb_bridge_t) ); 01500 if(!bridges) 01501 ast_log(LOG_ERROR, "Failed to initialize bridges\n"); 01502 else { 01503 memset(bridges,0,max_bridges * sizeof(vpb_bridge_t)); 01504 for(int i = 0; i < max_bridges; i++ ) { 01505 ast_mutex_init(&bridges[i].lock); 01506 ast_cond_init(&bridges[i].cond, NULL); 01507 } 01508 } 01509 } 01510 if(!echo_cancel) { 01511 if (model==vpb_model_v4pci) { 01512 vpb_echo_canc_disable(); 01513 ast_log(LOG_NOTICE, "Voicetronix echo cancellation OFF\n"); 01514 } 01515 else { 01516 /* need to it port by port for OpenSwitch*/ 01517 } 01518 } else { 01519 if (model==vpb_model_v4pci) { 01520 vpb_echo_canc_enable(); 01521 ast_log(LOG_NOTICE, "Voicetronix echo cancellation ON\n"); 01522 if (ec_supp_threshold > -1){ 01523 #ifdef VPB_PRI 01524 vpb_echo_canc_set_sup_thresh(0,(short *)&ec_supp_threshold); 01525 #else 01526 vpb_echo_canc_set_sup_thresh((short *)&ec_supp_threshold); 01527 #endif 01528 ast_log(LOG_NOTICE, "Voicetronix EC Sup Thres set\n"); 01529 } 01530 } 01531 else { 01532 /* need to it port by port for OpenSwitch*/ 01533 } 01534 } 01535 }
|
|
Definition at line 1537 of file chan_vpb.c. References ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_init(), vpb_pvt::buf, calloc, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, free, LOG_NOTICE, LOG_WARNING, MAX_VPB_GAIN, MIN_VPB_GAIN, MODE_FXO, TIMER_PERIOD_BUSY, TIMER_PERIOD_RINGBACK, VPB_EVENTS_ALL, VPB_EVENTS_NODTMF, VPB_EVENTS_STAT, VPB_GOT_RXHWG, VPB_GOT_RXSWG, VPB_GOT_TXHWG, VPB_GOT_TXSWG, vpb_model_unknown, vpb_model_v12pci, and vpb_model_v4pci. 01540 { 01541 struct vpb_pvt *tmp; 01542 char buf[64]; 01543 01544 tmp = (struct vpb_pvt *)calloc(1, sizeof *tmp); 01545 01546 if (!tmp) 01547 return NULL; 01548 01549 tmp->handle = vpb_open(board, channel); 01550 01551 if (tmp->handle < 0) { 01552 ast_log(LOG_WARNING, "Unable to create channel vpb/%d-%d: %s\n", 01553 board, channel, strerror(errno)); 01554 free(tmp); 01555 return NULL; 01556 } 01557 01558 snprintf(tmp->dev, sizeof(tmp->dev), "vpb/%d-%d", board, channel); 01559 01560 tmp->mode = mode; 01561 01562 tmp->group = group; 01563 tmp->callgroup = callgroup; 01564 tmp->pickupgroup = pickupgroup; 01565 01566 /* Initilize dtmf caller ID position variable */ 01567 tmp->dtmf_caller_pos=0; 01568 01569 strncpy(tmp->language, language, sizeof(tmp->language) - 1); 01570 strncpy(tmp->context, context, sizeof(tmp->context) - 1); 01571 01572 tmp->callerid_type=0; 01573 if(callerid) { 01574 if (strcasecmp(callerid,"on")==0){ 01575 tmp->callerid_type =1; 01576 strncpy(tmp->callerid, "unknown", sizeof(tmp->callerid) - 1); 01577 } 01578 else if (strcasecmp(callerid,"v23")==0){ 01579 tmp->callerid_type =2; 01580 strncpy(tmp->callerid, "unknown", sizeof(tmp->callerid) - 1); 01581 } 01582 else if (strcasecmp(callerid,"bell")==0){ 01583 tmp->callerid_type =3; 01584 strncpy(tmp->callerid, "unknown", sizeof(tmp->callerid) - 1); 01585 } 01586 else { 01587 strncpy(tmp->callerid, callerid, sizeof(tmp->callerid) - 1); 01588 } 01589 } else { 01590 strncpy(tmp->callerid, "unknown", sizeof(tmp->callerid) - 1); 01591 } 01592 01593 /* check if codec balances have been set in the config file */ 01594 if (bal3>=0) { 01595 if ((bal1>=0) && !(bal1 & 32)) bal1 |= 32; 01596 vpb_set_codec_reg(tmp->handle, 0x42, bal3); 01597 } 01598 if(bal1>=0) vpb_set_codec_reg(tmp->handle, 0x32, bal1); 01599 if(bal2>=0) vpb_set_codec_reg(tmp->handle, 0x3a, bal2); 01600 01601 if (gains & VPB_GOT_TXHWG){ 01602 if (txgain > MAX_VPB_GAIN){ 01603 tmp->txgain = MAX_VPB_GAIN; 01604 } 01605 else if (txgain < MIN_VPB_GAIN){ 01606 tmp->txgain = MIN_VPB_GAIN; 01607 } 01608 else { 01609 tmp->txgain = txgain; 01610 } 01611 01612 ast_log(LOG_NOTICE,"VPB setting Tx Hw gain to [%f]\n",tmp->txgain); 01613 vpb_play_set_hw_gain(tmp->handle, tmp->txgain); 01614 } 01615 01616 if (gains & VPB_GOT_RXHWG){ 01617 if (rxgain > MAX_VPB_GAIN){ 01618 tmp->rxgain = MAX_VPB_GAIN; 01619 } 01620 else if (rxgain < MIN_VPB_GAIN){ 01621 tmp->rxgain = MIN_VPB_GAIN; 01622 } 01623 else { 01624 tmp->rxgain = rxgain; 01625 } 01626 ast_log(LOG_NOTICE,"VPB setting Rx Hw gain to [%f]\n",tmp->rxgain); 01627 vpb_record_set_hw_gain(tmp->handle,tmp->rxgain); 01628 } 01629 01630 if (gains & VPB_GOT_TXSWG){ 01631 tmp->txswgain = txswgain; 01632 ast_log(LOG_NOTICE,"VPB setting Tx Sw gain to [%f]\n",tmp->txswgain); 01633 vpb_play_set_gain(tmp->handle, tmp->txswgain); 01634 } 01635 01636 if (gains & VPB_GOT_RXSWG){ 01637 tmp->rxswgain = rxswgain; 01638 ast_log(LOG_NOTICE,"VPB setting Rx Sw gain to [%f]\n",tmp->rxswgain); 01639 vpb_record_set_gain(tmp->handle, tmp->rxswgain); 01640 } 01641 01642 tmp->vpb_model = vpb_model_unknown; 01643 if( vpb_get_model(buf) == VPB_OK ) { 01644 if(strcmp(buf,"V12PCI")==0) 01645 tmp->vpb_model = vpb_model_v12pci; 01646 else if(strcmp(buf,"VPB4")==0) 01647 tmp->vpb_model = vpb_model_v4pci; 01648 } 01649 01650 ast_mutex_init(&tmp->owner_lock); 01651 ast_mutex_init(&tmp->lock); 01652 ast_mutex_init(&tmp->record_lock); 01653 ast_mutex_init(&tmp->play_lock); 01654 ast_mutex_init(&tmp->play_dtmf_lock); 01655 01656 /* set default read state */ 01657 tmp->read_state = 0; 01658 01659 tmp->golock=0; 01660 01661 tmp->busy_timer_id = vpb_timer_get_unique_timer_id(); 01662 vpb_timer_open(&tmp->busy_timer, tmp->handle, tmp->busy_timer_id, TIMER_PERIOD_BUSY); 01663 01664 tmp->ringback_timer_id = vpb_timer_get_unique_timer_id(); 01665 vpb_timer_open(&tmp->ringback_timer, tmp->handle, tmp->ringback_timer_id, TIMER_PERIOD_RINGBACK); 01666 01667 tmp->ring_timer_id = vpb_timer_get_unique_timer_id(); 01668 vpb_timer_open(&tmp->ring_timer, tmp->handle, tmp->ring_timer_id, timer_period_ring); 01669 01670 tmp->dtmfidd_timer_id = vpb_timer_get_unique_timer_id(); 01671 vpb_timer_open(&tmp->dtmfidd_timer, tmp->handle, tmp->dtmfidd_timer_id, dtmf_idd); 01672 01673 if (mode == MODE_FXO){ 01674 if (use_ast_dtmfdet) 01675 vpb_set_event_mask(tmp->handle, VPB_EVENTS_NODTMF ); 01676 else 01677 vpb_set_event_mask(tmp->handle, VPB_EVENTS_ALL ); 01678 } 01679 else { 01680 /* 01681 if (use_ast_dtmfdet) 01682 vpb_set_event_mask(tmp->handle, VPB_EVENTS_NODTMF ); 01683 else 01684 */ 01685 vpb_set_event_mask(tmp->handle, VPB_EVENTS_STAT ); 01686 } 01687 01688 if ((tmp->vpb_model == vpb_model_v12pci) && (echo_cancel)){ 01689 vpb_hostecho_on(tmp->handle); 01690 } 01691 if (use_ast_dtmfdet) { 01692 tmp->vad = ast_dsp_new(); 01693 ast_dsp_set_features(tmp->vad, DSP_FEATURE_DTMF_DETECT); 01694 ast_dsp_digitmode(tmp->vad, DSP_DIGITMODE_DTMF); 01695 if (relaxdtmf) 01696 ast_dsp_digitmode(tmp->vad, DSP_DIGITMODE_DTMF|DSP_DIGITMODE_RELAXDTMF); 01697 } 01698 else { 01699 tmp->vad = NULL; 01700 } 01701 01702 /* define grunt tone */ 01703 vpb_settonedet(tmp->handle,&toned_ungrunt); 01704 01705 ast_log(LOG_NOTICE,"Voicetronix %s channel %s initialized (rxsg=%f/txsg=%f/rxhg=%f/txhg=%f)(0x%x/0x%x/0x%x)\n", 01706 (tmp->vpb_model==vpb_model_v4pci)?"V4PCI": (tmp->vpb_model==vpb_model_v12pci)?"V12PCI":"[Unknown model]", 01707 tmp->dev, tmp->rxswgain, tmp->txswgain, tmp->rxgain, tmp->txgain, bal1, bal2, bal3 ); 01708 01709 return tmp; 01710 }
|
|
Definition at line 1103 of file chan_vpb.c. References ast_callerid_split(), ast_canmatch_extension(), ast_exists_extension(), ast_log(), AST_MAX_EXTENSION, ast_pickup_call(), ast_pickup_ext(), ast_set_callerid(), AST_STATE_RING, AST_STATE_UP, ast_verbose(), vpb_pvt::callerid_type, cid_name, cid_num, vpb_pvt::dev, DTMF_CID_START, DTMF_CID_STOP, get_callerid(), get_callerid_ast(), LOG_ERROR, vpb_pvt::mode, MODE_DIALTONE, MODE_FXO, MODE_IMMEDIATE, option_verbose, vpb_pvt::owner, playtone(), s, stoptone(), VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, vpb_new(), VPB_STATE_GETDTMF, VPB_STATE_ONHOOK, VPB_STATE_PLAYBUSY, and VPB_STATE_PLAYDIAL. Referenced by do_monitor(). 01104 { 01105 char s[2] = {0}; 01106 struct ast_channel *owner = p->owner; 01107 char cid_num[256]; 01108 char cid_name[256]; 01109 /* 01110 struct ast_channel *c; 01111 */ 01112 01113 if (option_verbose > 3) { 01114 char str[VPB_MAX_STR]; 01115 vpb_translate_event(e, str); 01116 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_notowned: mode=%d, event[%d][%s]=[%d]\n", 01117 p->dev, p->mode, e->type,str, e->data); 01118 } 01119 01120 switch(e->type) { 01121 case VPB_LOOP_ONHOOK: 01122 case VPB_LOOP_POLARITY: 01123 if (UsePolarityCID == 1){ 01124 if (option_verbose>3) 01125 ast_verbose(VERBOSE_PREFIX_4 "Polarity reversal\n"); 01126 if(p->callerid_type == 1) { 01127 if (option_verbose>3) 01128 ast_verbose(VERBOSE_PREFIX_4 "Using VPB Caller ID\n"); 01129 get_callerid(p); /* UK CID before 1st ring*/ 01130 } 01131 /* get_callerid_ast(p); /* Caller ID using the ast functions */ 01132 } 01133 break; 01134 case VPB_RING: 01135 if (p->mode == MODE_FXO) /* FXO port ring, start * */ { 01136 vpb_new(p, AST_STATE_RING, p->context); 01137 if (UsePolarityCID != 1){ 01138 if(p->callerid_type == 1) { 01139 if (option_verbose>3) 01140 ast_verbose(VERBOSE_PREFIX_4 "Using VPB Caller ID\n"); 01141 get_callerid(p); /* Australian CID only between 1st and 2nd ring */ 01142 } 01143 get_callerid_ast(p); /* Caller ID using the ast functions */ 01144 } 01145 else { 01146 ast_log(LOG_ERROR, "Setting caller ID: %s %s\n",p->cid_num, p->cid_name); 01147 ast_set_callerid(p->owner, p->cid_num, p->cid_name, p->cid_num); 01148 p->cid_num[0]=0; 01149 p->cid_name[0]=0; 01150 } 01151 01152 vpb_timer_stop(p->ring_timer); 01153 vpb_timer_start(p->ring_timer); 01154 } 01155 break; 01156 01157 case VPB_RING_OFF: 01158 break; 01159 01160 case VPB_STATION_OFFHOOK: 01161 if (p->mode == MODE_IMMEDIATE) 01162 vpb_new(p,AST_STATE_RING, p->context); 01163 else { 01164 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_notowned: playing dialtone\n",p->dev); 01165 playtone(p->handle, &Dialtone); 01166 p->state=VPB_STATE_PLAYDIAL; 01167 p->wantdtmf = 1; 01168 p->ext[0] = 0; /* Just to be sure & paranoid.*/ 01169 } 01170 break; 01171 01172 case VPB_DIALEND: 01173 if (p->mode == MODE_DIALTONE){ 01174 if (p->state == VPB_STATE_PLAYDIAL) { 01175 playtone(p->handle, &Dialtone); 01176 p->wantdtmf = 1; 01177 p->ext[0] = 0; /* Just to be sure & paranoid. */ 01178 } 01179 /* These are not needed as they have timers to restart them 01180 else if (p->state == VPB_STATE_PLAYBUSY) { 01181 playtone(p->handle, &Busytone); 01182 p->wantdtmf = 1; 01183 p->ext[0] = 0; 01184 } 01185 else if (p->state == VPB_STATE_PLAYRING) { 01186 playtone(p->handle, &Ringbacktone); 01187 p->wantdtmf = 1; 01188 p->ext[0] = 0; 01189 } 01190 */ 01191 } else { 01192 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_notowned: Got a DIALEND when not really expected\n",p->dev); 01193 } 01194 break; 01195 01196 case VPB_STATION_ONHOOK: /* clear ext */ 01197 stoptone(p->handle); 01198 p->wantdtmf = 1 ; 01199 p->ext[0] = 0; 01200 p->state=VPB_STATE_ONHOOK; 01201 break; 01202 case VPB_TIMEREXP: 01203 if (e->data == p->dtmfidd_timer_id) { 01204 if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)){ 01205 if (option_verbose > 3) 01206 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_notowned: DTMF IDD timer out, matching on [%s] in [%s]\n", p->dev,p->ext , p->context); 01207 01208 vpb_new(p,AST_STATE_RING, p->context); 01209 } 01210 } else if (e->data == p->ring_timer_id) { 01211 /* We didnt get another ring in time! */ 01212 if (p->owner){ 01213 if (p->owner->_state != AST_STATE_UP) { 01214 /* Assume caller has hung up */ 01215 vpb_timer_stop(p->ring_timer); 01216 } 01217 } else { 01218 /* No owner any more, Assume caller has hung up */ 01219 vpb_timer_stop(p->ring_timer); 01220 } 01221 } 01222 break; 01223 01224 case VPB_DTMF: 01225 if (p->state == VPB_STATE_ONHOOK){ 01226 /* DTMF's being passed while on-hook maybe Caller ID */ 01227 if ( p->mode == MODE_FXO ) { 01228 if ( e->data == DTMF_CID_START ) { /* CallerID Start signal */ 01229 p->dtmf_caller_pos = 0; /* Leaves the first digit out */ 01230 memset(p->callerid,0,AST_MAX_EXTENSION); 01231 } 01232 else if ( e->data == DTMF_CID_STOP ) { /* CallerID End signal */ 01233 p->callerid[p->dtmf_caller_pos] = '\0'; 01234 if (option_verbose > 2) 01235 ast_verbose(VERBOSE_PREFIX_3 " %s: DTMF CallerID %s\n",p->dev,p->callerid); 01236 if (owner){ 01237 /* 01238 if (owner->cid.cid_num) 01239 free(owner->cid.cid_num); 01240 owner->cid.cid_num=NULL; 01241 if (owner->cid.cid_name) 01242 free(owner->cid.cid_name); 01243 owner->cid.cid_name=NULL; 01244 owner->cid.cid_num = strdup(p->callerid); 01245 */ 01246 cid_name[0] = '\0'; 01247 cid_num[0] = '\0'; 01248 ast_callerid_split(p->callerid, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 01249 ast_set_callerid(owner, cid_num, cid_name, cid_num); 01250 01251 } 01252 else { 01253 if (option_verbose > 2) 01254 ast_verbose(VERBOSE_PREFIX_3 " %s: DTMF CallerID: no owner to assign CID \n",p->dev); 01255 } 01256 } else if ( p->dtmf_caller_pos < AST_MAX_EXTENSION ) { 01257 if ( p->dtmf_caller_pos >= 0 ) 01258 p->callerid[p->dtmf_caller_pos] = e->data; 01259 p->dtmf_caller_pos++; 01260 } 01261 } 01262 break; 01263 } 01264 if (p->wantdtmf == 1) { 01265 stoptone(p->handle); 01266 p->wantdtmf = 0; 01267 } 01268 p->state=VPB_STATE_GETDTMF; 01269 s[0] = e->data; 01270 strncat(p->ext, s, sizeof(p->ext) - strlen(p->ext) - 1); 01271 #if 0 01272 if (!strcmp(p->ext,ast_pickup_ext())) { 01273 /* Call pickup has been dialled! */ 01274 if (ast_pickup_call(c)) { 01275 /* Call pickup wasnt possible */ 01276 } 01277 } 01278 else 01279 #endif 01280 if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)){ 01281 if ( ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)){ 01282 if (option_verbose > 3) 01283 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_notowned: Multiple matches on [%s] in [%s]\n", p->dev,p->ext , p->context); 01284 /* Start DTMF IDD timer */ 01285 vpb_timer_stop(p->dtmfidd_timer); 01286 vpb_timer_start(p->dtmfidd_timer); 01287 } 01288 else { 01289 if (option_verbose > 3) 01290 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_notowned: Matched on [%s] in [%s]\n", p->dev,p->ext , p->context); 01291 vpb_new(p,AST_STATE_UP, p->context); 01292 } 01293 } else if (!ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)){ 01294 if (ast_exists_extension(NULL, "default", p->ext, 1, p->callerid)) { 01295 vpb_new(p,AST_STATE_UP, "default"); 01296 } else if (!ast_canmatch_extension(NULL, "default", p->ext, 1, p->callerid)) { 01297 if (option_verbose > 3) { 01298 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_notowned: can't match anything in %s or default\n", p->dev, p->context); 01299 } 01300 playtone(p->handle, &Busytone); 01301 vpb_timer_stop(p->busy_timer); 01302 vpb_timer_start(p->busy_timer); 01303 p->state = VPB_STATE_PLAYBUSY; 01304 } 01305 } 01306 break; 01307 01308 default: 01309 /* Ignore.*/ 01310 break; 01311 } 01312 01313 if (option_verbose > 3) 01314 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_notowned: mode=%d, [%d=>%d]\n", 01315 p->dev, p->mode, e->type, e->data); 01316 01317 return 0; 01318 }
|
|
Definition at line 841 of file chan_vpb.c. References ast_channel::_state, ast_async_goto(), AST_BRIDGE_IGNORE_SIGS, ast_cond_signal(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_RING, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, ast_frisolate(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), AST_STATE_UP, ast_strlen_zero(), ast_verbose(), vpb_pvt::bridge, vpb_pvt::busy_timer, vpb_pvt::busy_timer_id, vpb_bridge_t::c0, vpb_bridge_t::c1, ast_channel::cid, ast_callerid::cid_num, vpb_bridge_t::cond, ast_channel::context, vpb_pvt::dev, vpb_bridge_t::endbridge, ast_channel::exten, vpb_pvt::faxhandled, vpb_bridge_t::flags, vpb_bridge_t::fo, ast_frame::frametype, vpb_pvt::handle, vpb_pvt::lastgrunt, ast_channel::lock, vpb_pvt::lock, vpb_bridge_t::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, vpb_pvt::mode, MODE_FXO, ast_channel::name, option_verbose, vpb_pvt::owner, pbx_builtin_setvar_helper(), playtone(), vpb_bridge_t::rc, vpb_pvt::ring_timer, vpb_pvt::ring_timer_id, vpb_pvt::ringback_timer, vpb_pvt::ringback_timer_id, ast_frame::src, vpb_pvt::state, ast_frame::subclass, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, and VPB_STATE_PLAYBUSY. Referenced by do_monitor(). 00842 { 00843 struct ast_frame f = {AST_FRAME_CONTROL}; /* default is control, Clear rest. */ 00844 int endbridge = 0; 00845 int res=0; 00846 00847 if (option_verbose > 3) 00848 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_owned: got event: [%d=>%d]\n", p->dev, e->type, e->data); 00849 00850 f.src = (char *)type; 00851 switch (e->type) { 00852 case VPB_RING: 00853 if (p->mode == MODE_FXO) { 00854 f.subclass = AST_CONTROL_RING; 00855 vpb_timer_stop(p->ring_timer); 00856 vpb_timer_start(p->ring_timer); 00857 } else 00858 f.frametype = -1; /* ignore ring on station port. */ 00859 break; 00860 00861 case VPB_RING_OFF: 00862 f.frametype = -1; 00863 break; 00864 00865 case VPB_TIMEREXP: 00866 if (e->data == p->busy_timer_id) { 00867 playtone(p->handle,&Busytone); 00868 p->state = VPB_STATE_PLAYBUSY; 00869 vpb_timer_stop(p->busy_timer); 00870 vpb_timer_start(p->busy_timer); 00871 f.frametype = -1; 00872 } else if (e->data == p->ringback_timer_id) { 00873 playtone(p->handle, &Ringbacktone); 00874 vpb_timer_stop(p->ringback_timer); 00875 vpb_timer_start(p->ringback_timer); 00876 f.frametype = -1; 00877 } else if (e->data == p->ring_timer_id) { 00878 /* We didnt get another ring in time! */ 00879 if (p->owner->_state != AST_STATE_UP) { 00880 /* Assume caller has hung up */ 00881 vpb_timer_stop(p->ring_timer); 00882 f.subclass = AST_CONTROL_HANGUP; 00883 } else { 00884 vpb_timer_stop(p->ring_timer); 00885 f.frametype = -1; 00886 } 00887 00888 } else { 00889 f.frametype = -1; /* Ignore. */ 00890 } 00891 break; 00892 00893 case VPB_DTMF_DOWN: 00894 case VPB_DTMF: 00895 if (use_ast_dtmfdet){ 00896 f.frametype = -1; 00897 } else if (p->owner->_state == AST_STATE_UP) { 00898 f.frametype = AST_FRAME_DTMF; 00899 f.subclass = e->data; 00900 } else 00901 f.frametype = -1; 00902 break; 00903 00904 case VPB_TONEDETECT: 00905 if (e->data == VPB_BUSY || e->data == VPB_BUSY_308 || e->data == VPB_BUSY_AUST ) { 00906 if (option_verbose > 3) 00907 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_owned: got event: BUSY\n", p->dev); 00908 if (p->owner->_state == AST_STATE_UP) { 00909 f.subclass = AST_CONTROL_HANGUP; 00910 } 00911 else { 00912 f.subclass = AST_CONTROL_BUSY; 00913 } 00914 } 00915 else if (e->data == VPB_FAX){ 00916 if (!p->faxhandled){ 00917 if (strcmp(p->owner->exten, "fax")) { 00918 const char *target_context = ast_strlen_zero(p->owner->macrocontext) ? p->owner->context : p->owner->macrocontext; 00919 00920 if (ast_exists_extension(p->owner, target_context, "fax", 1, p->owner->cid.cid_num)) { 00921 if (option_verbose > 2) 00922 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", p->owner->name); 00923 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 00924 pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten); 00925 if (ast_async_goto(p->owner, target_context, "fax", 1)) 00926 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context); 00927 } else 00928 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n"); 00929 } else 00930 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 00931 } else 00932 ast_log(LOG_DEBUG, "Fax already handled\n"); 00933 00934 } 00935 else if (e->data == VPB_GRUNT) { 00936 if ( ast_tvdiff_ms(ast_tvnow(), p->lastgrunt) > gruntdetect_timeout ) { 00937 /* Nothing heard on line for a very long time 00938 * Timeout connection */ 00939 if (option_verbose > 2) 00940 ast_verbose(VERBOSE_PREFIX_3 "grunt timeout\n"); 00941 ast_log(LOG_NOTICE,"%s: Line hangup due of lack of conversation\n",p->dev); 00942 f.subclass = AST_CONTROL_HANGUP; 00943 } else { 00944 p->lastgrunt = ast_tvnow(); 00945 f.frametype = -1; 00946 } 00947 } 00948 else { 00949 f.frametype = -1; 00950 } 00951 break; 00952 00953 case VPB_CALLEND: 00954 #ifdef DIAL_WITH_CALL_PROGRESS 00955 if (e->data == VPB_CALL_CONNECTED) 00956 f.subclass = AST_CONTROL_ANSWER; 00957 else if (e->data == VPB_CALL_NO_DIAL_TONE || e->data == VPB_CALL_NO_RING_BACK) 00958 f.subclass = AST_CONTROL_CONGESTION; 00959 else if (e->data == VPB_CALL_NO_ANSWER || e->data == VPB_CALL_BUSY) 00960 f.subclass = AST_CONTROL_BUSY; 00961 else if (e->data == VPB_CALL_DISCONNECTED) 00962 f.subclass = AST_CONTROL_HANGUP; 00963 #else 00964 ast_log(LOG_NOTICE,"%s: Got call progress callback but blind dialing \n", p->dev); 00965 f.frametype = -1; 00966 #endif 00967 break; 00968 00969 case VPB_STATION_OFFHOOK: 00970 f.subclass = AST_CONTROL_ANSWER; 00971 break; 00972 00973 case VPB_DROP: 00974 if ((p->mode == MODE_FXO)&&(UseLoopDrop)){ /* ignore loop drop on stations */ 00975 if (p->owner->_state == AST_STATE_UP) 00976 f.subclass = AST_CONTROL_HANGUP; 00977 else 00978 f.frametype = -1; 00979 } 00980 break; 00981 case VPB_LOOP_ONHOOK: 00982 if (p->owner->_state == AST_STATE_UP) 00983 f.subclass = AST_CONTROL_HANGUP; 00984 else 00985 f.frametype = -1; 00986 break; 00987 case VPB_STATION_ONHOOK: 00988 f.subclass = AST_CONTROL_HANGUP; 00989 break; 00990 00991 case VPB_STATION_FLASH: 00992 f.subclass = AST_CONTROL_FLASH; 00993 break; 00994 00995 /* Called when dialing has finished and ringing starts 00996 * No indication that call has really been answered when using blind dialing 00997 */ 00998 case VPB_DIALEND: 00999 if (p->state < 5){ 01000 f.subclass = AST_CONTROL_ANSWER; 01001 if (option_verbose > 1) 01002 ast_verbose(VERBOSE_PREFIX_2 "%s: Dialend\n", p->dev); 01003 } else { 01004 f.frametype = -1; 01005 } 01006 break; 01007 01008 case VPB_PLAY_UNDERFLOW: 01009 f.frametype = -1; 01010 vpb_reset_play_fifo_alarm(p->handle); 01011 break; 01012 01013 case VPB_RECORD_OVERFLOW: 01014 f.frametype = -1; 01015 vpb_reset_record_fifo_alarm(p->handle); 01016 break; 01017 01018 default: 01019 f.frametype = -1; 01020 break; 01021 } 01022 01023 /* 01024 if (option_verbose > 3) ast_verbose("%s: LOCKING in handle_owned [%d]\n", p->dev,res); 01025 res = ast_mutex_lock(&p->lock); 01026 if (option_verbose > 3) ast_verbose("%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 01027 */ 01028 { 01029 if (p->bridge) { /* Check what happened, see if we need to report it. */ 01030 switch (f.frametype) { 01031 case AST_FRAME_DTMF: 01032 if ( !(p->bridge->c0 == p->owner && 01033 (p->bridge->flags & AST_BRIDGE_DTMF_CHANNEL_0) ) && 01034 !(p->bridge->c1 == p->owner && 01035 (p->bridge->flags & AST_BRIDGE_DTMF_CHANNEL_1) )) 01036 /* Kill bridge, this is interesting. */ 01037 endbridge = 1; 01038 break; 01039 01040 case AST_FRAME_CONTROL: 01041 if (!(p->bridge->flags & AST_BRIDGE_IGNORE_SIGS)) 01042 #if 0 01043 if (f.subclass == AST_CONTROL_BUSY || 01044 f.subclass == AST_CONTROL_CONGESTION || 01045 f.subclass == AST_CONTROL_HANGUP || 01046 f.subclass == AST_CONTROL_FLASH) 01047 #endif 01048 endbridge = 1; 01049 break; 01050 01051 default: 01052 break; 01053 } 01054 if (endbridge) { 01055 if (p->bridge->fo) 01056 *p->bridge->fo = ast_frisolate(&f); 01057 if (p->bridge->rc) 01058 *p->bridge->rc = p->owner; 01059 01060 ast_mutex_lock(&p->bridge->lock); { 01061 p->bridge->endbridge = 1; 01062 ast_cond_signal(&p->bridge->cond); 01063 } ast_mutex_unlock(&p->bridge->lock); 01064 } 01065 } 01066 } 01067 01068 if (endbridge){ 01069 res = ast_mutex_unlock(&p->lock); 01070 /* 01071 if (option_verbose > 3) ast_verbose("%s: unLOCKING in handle_owned [%d]\n", p->dev,res); 01072 */ 01073 return 0; 01074 } 01075 01076 if (option_verbose > 3) 01077 ast_verbose(VERBOSE_PREFIX_4 "%s: handle_owned: Prepared frame type[%d]subclass[%d], bridge=%p owner=[%s]\n", 01078 p->dev, f.frametype, f.subclass, (void *)p->bridge, p->owner->name); 01079 01080 /* Trylock used here to avoid deadlock that can occur if we 01081 * happen to be in here handling an event when hangup is called 01082 * Problem is that hangup holds p->owner->lock 01083 */ 01084 if ((f.frametype >= 0)&& (f.frametype != AST_FRAME_NULL)&&(p->owner)) { 01085 if (ast_mutex_trylock(&p->owner->lock)==0) { 01086 ast_queue_frame(p->owner, &f); 01087 ast_mutex_unlock(&p->owner->lock); 01088 if (option_verbose > 3) 01089 ast_verbose(VERBOSE_PREFIX_4 "%s: handled_owned: Queued Frame to [%s]\n", p->dev,p->owner->name); 01090 } else { 01091 ast_verbose("%s: handled_owned: Missed event %d/%d \n", 01092 p->dev,f.frametype, f.subclass); 01093 } 01094 } 01095 res = ast_mutex_unlock(&p->lock); 01096 /* 01097 if (option_verbose > 3) ast_verbose("%s: unLOCKING in handle_owned [%d]\n", p->dev,res); 01098 */ 01099 01100 return 0; 01101 }
|
|
Definition at line 2751 of file chan_vpb.c. References ast_log(), DEFAULT_GAIN, and LOG_ERROR. 02752 { 02753 float gain; 02754 02755 /* try to scan number */ 02756 if (sscanf(value, "%f", &gain) != 1) 02757 { 02758 ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n", value, gain_type, config); 02759 return DEFAULT_GAIN; 02760 } 02761 02762 02763 /* percentage? */ 02764 /*if (value[strlen(value) - 1] == '%') */ 02765 /* return gain / (float)100; */ 02766 02767 return gain; 02768 }
|
|
Definition at line 831 of file chan_vpb.c. References ast_verbose(), option_verbose, stoptone(), and VERBOSE_PREFIX_4. Referenced by monitor_handle_notowned(), monitor_handle_owned(), and vpb_indicate(). 00832 { 00833 int ret=VPB_OK; 00834 stoptone(handle); 00835 if (option_verbose > 3) 00836 ast_verbose(VERBOSE_PREFIX_4 "[%02d]: Playing tone\n", handle); 00837 ret = vpb_playtone_async(handle, tone); 00838 return ret; 00839 }
|
|
Definition at line 1443 of file chan_vpb.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_verbose(), do_monitor(), error(), LOG_ERROR, LOG_WARNING, option_verbose, VERBOSE_PREFIX_4, and VPB_NULL_EVENT. 01444 { 01445 int error = 0; 01446 01447 /* If we're supposed to be stopped -- stay stopped */ 01448 if (mthreadactive == -2) 01449 return 0; 01450 01451 if (option_verbose > 3) 01452 ast_verbose(VERBOSE_PREFIX_4 "Restarting monitor\n"); 01453 01454 ast_mutex_lock(&monlock); { 01455 if (monitor_thread == pthread_self()) { 01456 ast_log(LOG_WARNING, "Cannot kill myself\n"); 01457 error = -1; 01458 if (option_verbose > 3) 01459 ast_verbose(VERBOSE_PREFIX_4 "Monitor trying to kill monitor\n"); 01460 } 01461 else { 01462 if (mthreadactive != -1) { 01463 /* Why do other drivers kill the thread? No need says I, simply awake thread with event. */ 01464 VPB_EVENT e; 01465 e.handle = 0; 01466 e.type = VPB_NULL_EVENT; 01467 e.data = 0; 01468 01469 if (option_verbose > 3) 01470 ast_verbose(VERBOSE_PREFIX_4 "Trying to reawake monitor\n"); 01471 01472 vpb_put_event(&e); 01473 } else { 01474 /* Start a new monitor */ 01475 int pid = ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL); 01476 if (option_verbose > 3) 01477 ast_verbose(VERBOSE_PREFIX_4 "Created new monitor thread %d\n",pid); 01478 if (pid < 0) { 01479 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 01480 error = -1; 01481 } else 01482 mthreadactive = 0; /* Started the thread!*/ 01483 } 01484 } 01485 } ast_mutex_unlock(&monlock); 01486 01487 if (option_verbose > 3) 01488 ast_verbose(VERBOSE_PREFIX_4 "Monitor restarted\n"); 01489 01490 return error; 01491 }
|
|
Definition at line 813 of file chan_vpb.c. References ast_verbose(), option_verbose, and VERBOSE_PREFIX_4. Referenced by monitor_handle_notowned(), playtone(), vpb_hangup(), and vpb_indicate(). 00814 { 00815 int ret; 00816 VPB_EVENT je; 00817 while(vpb_playtone_state(handle)!=VPB_OK){ 00818 vpb_tone_terminate(handle); 00819 ret = vpb_get_event_ch_async(handle,&je); 00820 if ((ret == VPB_OK)&&(je.type != VPB_DIALEND)){ 00821 if (option_verbose > 3){ 00822 ast_verbose(VERBOSE_PREFIX_4 "Stop tone collected a wrong event!![%d]\n",je.type); 00823 } 00824 /* vpb_put_event(&je); */ 00825 } 00826 vpb_sleep(10); 00827 } 00828 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 2967 of file chan_vpb.c. References ast_channel_unregister(), ast_cond_destroy(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, bridges, free, vpb_pvt::handle, iflist, lock, vpb_pvt::lock, oh323_pvt::next, vpb_pvt::next, vpb_pvt::owner, vpb_pvt::owner_lock, vpb_pvt::play_dtmf_lock, vpb_pvt::play_lock, vpb_pvt::readthread, vpb_pvt::record_lock, vpb_tech, and vpb_tech_indicate. 02968 { 02969 struct vpb_pvt *p; 02970 /* First, take us out of the channel loop */ 02971 if (use_ast_ind == 1){ 02972 ast_channel_unregister(&vpb_tech_indicate); 02973 } 02974 else { 02975 ast_channel_unregister(&vpb_tech); 02976 } 02977 02978 ast_mutex_lock(&iflock); { 02979 /* Hangup all interfaces if they have an owner */ 02980 p = iflist; 02981 while(p) { 02982 if (p->owner) 02983 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 02984 p = p->next; 02985 } 02986 iflist = NULL; 02987 } ast_mutex_unlock(&iflock); 02988 02989 ast_mutex_lock(&monlock); { 02990 if (mthreadactive > -1) { 02991 pthread_cancel(monitor_thread); 02992 pthread_join(monitor_thread, NULL); 02993 } 02994 mthreadactive = -2; 02995 } ast_mutex_unlock(&monlock); 02996 02997 ast_mutex_lock(&iflock); { 02998 /* Destroy all the interfaces and free their memory */ 02999 03000 while(iflist) { 03001 p = iflist; 03002 ast_mutex_destroy(&p->lock); 03003 pthread_cancel(p->readthread); 03004 ast_mutex_destroy(&p->owner_lock); 03005 ast_mutex_destroy(&p->record_lock); 03006 ast_mutex_destroy(&p->play_lock); 03007 ast_mutex_destroy(&p->play_dtmf_lock); 03008 p->readthread = 0; 03009 03010 vpb_close(p->handle); 03011 03012 iflist = iflist->next; 03013 03014 free(p); 03015 } 03016 iflist = NULL; 03017 } ast_mutex_unlock(&iflock); 03018 03019 ast_mutex_lock(&bridge_lock); { 03020 memset(bridges, 0, sizeof bridges); 03021 } ast_mutex_unlock(&bridge_lock); 03022 ast_mutex_destroy(&bridge_lock); 03023 for(int i = 0; i < max_bridges; i++ ) { 03024 ast_mutex_destroy(&bridges[i].lock); 03025 ast_cond_destroy(&bridges[i].cond); 03026 } 03027 free(bridges); 03028 03029 return 0; 03030 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 3032 of file chan_vpb.c. 03033 { 03034 return usecnt; 03035 }
|
|
Definition at line 2102 of file chan_vpb.c. References ast_channel::_state, ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, ast_setstate(), AST_STATE_UP, ast_verbose(), vpb_pvt::dev, do_chanreads(), vpb_pvt::handle, vpb_pvt::lock, vpb_pvt::mode, MODE_FXO, ast_channel::name, option_verbose, vpb_pvt::readthread, ast_channel::rings, vpb_pvt::state, ast_channel::tech_pvt, VERBOSE_PREFIX_2, VERBOSE_PREFIX_4, and VPB_STATE_OFFHOOK. Referenced by vpb_new(). 02103 { 02104 struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 02105 int res = 0; 02106 /* 02107 VPB_EVENT je; 02108 int ret; 02109 if (option_verbose > 3) ast_verbose("%s: LOCKING in answer \n", p->dev); 02110 if (option_verbose > 3) ast_verbose("%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 02111 */ 02112 ast_mutex_lock(&p->lock); 02113 02114 if (option_verbose > 3) 02115 ast_verbose(VERBOSE_PREFIX_4 "%s: Answering channel\n",p->dev); 02116 02117 if (p->mode == MODE_FXO){ 02118 if (option_verbose > 3) 02119 ast_verbose("%s: Disabling Loop Drop detection\n",p->dev); 02120 vpb_disable_event(p->handle, VPB_MDROP); 02121 } 02122 02123 if (ast->_state != AST_STATE_UP) { 02124 if (p->mode == MODE_FXO){ 02125 vpb_sethook_sync(p->handle, VPB_OFFHOOK); 02126 p->state=VPB_STATE_OFFHOOK; 02127 /* vpb_sleep(500); 02128 ret = vpb_get_event_ch_async(p->handle,&je); 02129 if ((ret == VPB_OK)&&((je.type != VPB_DROP)&&(je.type != VPB_RING))){ 02130 if (option_verbose > 3){ 02131 ast_verbose(VERBOSE_PREFIX_4 "%s: Answer collected a wrong event!!\n",p->dev); 02132 } 02133 vpb_put_event(&je); 02134 } 02135 */ 02136 } 02137 ast_setstate(ast, AST_STATE_UP); 02138 02139 if(option_verbose>1) 02140 /* 02141 ast_verbose( VERBOSE_PREFIX_2 "%s: Answered call from %s on %s [%s]\n", p->dev, 02142 p->owner->callerid, ast->name,(p->mode == MODE_FXO)?"FXO":"FXS"); 02143 */ 02144 ast_verbose( VERBOSE_PREFIX_2 "%s: Answered call on %s [%s]\n", p->dev, 02145 ast->name,(p->mode == MODE_FXO)?"FXO":"FXS"); 02146 02147 ast->rings = 0; 02148 if( !p->readthread ){ 02149 /* res = ast_mutex_unlock(&p->lock); */ 02150 /* ast_verbose("%s: unLOCKING in answer [%d]\n", p->dev,res); */ 02151 ast_pthread_create(&p->readthread, NULL, do_chanreads, (void *)p); 02152 } else { 02153 if(option_verbose>3) 02154 ast_verbose(VERBOSE_PREFIX_4 "%s: Record thread already running!!\n",p->dev); 02155 } 02156 } else { 02157 if(option_verbose>3) { 02158 ast_verbose(VERBOSE_PREFIX_4 "%s: Answered state is up\n",p->dev); 02159 } 02160 /* res = ast_mutex_unlock(&p->lock); */ 02161 /* ast_verbose("%s: unLOCKING in answer [%d]\n", p->dev,res); */ 02162 } 02163 vpb_sleep(500); 02164 if (p->mode == MODE_FXO){ 02165 if (option_verbose > 3) 02166 ast_verbose("%s: Re-enabling Loop Drop detection\n",p->dev); 02167 vpb_enable_event(p->handle,VPB_MDROP); 02168 } 02169 res = ast_mutex_unlock(&p->lock); 02170 /* 02171 if(option_verbose>3) ast_verbose("%s: unLOCKING in answer [%d]\n", p->dev,res); 02172 */ 02173 return 0; 02174 }
|
|
Definition at line 417 of file chan_vpb.c. References AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock(), bridges, vpb_bridge_t::c0, vpb_bridge_t::c1, vpb_bridge_t::endbridge, vpb_bridge_t::flags, vpb_bridge_t::fo, inuse, vpb_bridge_t::rc, ast_channel::tech_pvt, vpb_pvt::vpb_model, and vpb_model_v4pci. 00418 { 00419 struct vpb_pvt *p0 = (struct vpb_pvt *)c0->tech_pvt; 00420 struct vpb_pvt *p1 = (struct vpb_pvt *)c1->tech_pvt; 00421 int i; 00422 int res; 00423 struct ast_channel *cs[3]; 00424 struct ast_channel *who; 00425 struct ast_frame *f; 00426 00427 cs[0] = c0; 00428 cs[1] = c1; 00429 00430 #ifdef BAD_V4PCI_BRIDGE 00431 if(p0->vpb_model==vpb_model_v4pci) 00432 return AST_BRIDGE_FAILED_NOWARN; 00433 #endif 00434 if ( UseNativeBridge != 1){ 00435 return AST_BRIDGE_FAILED_NOWARN; 00436 } 00437 00438 /* 00439 ast_mutex_lock(&p0->lock); 00440 ast_mutex_lock(&p1->lock); 00441 */ 00442 00443 /* Bridge channels, check if we can. I believe we always can, so find a slot.*/ 00444 00445 ast_mutex_lock(&bridge_lock); { 00446 for (i = 0; i < max_bridges; i++) 00447 if (!bridges[i].inuse) 00448 break; 00449 if (i < max_bridges) { 00450 bridges[i].inuse = 1; 00451 bridges[i].endbridge = 0; 00452 bridges[i].flags = flags; 00453 bridges[i].rc = rc; 00454 bridges[i].fo = fo; 00455 bridges[i].c0 = c0; 00456 bridges[i].c1 = c1; 00457 } 00458 } ast_mutex_unlock(&bridge_lock); 00459 00460 if (i == max_bridges) { 00461 ast_log(LOG_WARNING, "%s: vpb_bridge: Failed to bridge %s and %s!\n", p0->dev, c0->name, c1->name); 00462 ast_mutex_unlock(&p0->lock); 00463 ast_mutex_unlock(&p1->lock); 00464 return AST_BRIDGE_FAILED_NOWARN; 00465 } else { 00466 /* Set bridge pointers. You don't want to take these locks while holding bridge lock.*/ 00467 ast_mutex_lock(&p0->lock); { 00468 p0->bridge = &bridges[i]; 00469 } ast_mutex_unlock(&p0->lock); 00470 00471 ast_mutex_lock(&p1->lock); { 00472 p1->bridge = &bridges[i]; 00473 } ast_mutex_unlock(&p1->lock); 00474 00475 if (option_verbose>1) 00476 ast_verbose(VERBOSE_PREFIX_2 "%s: vpb_bridge: Bridging call entered with [%s, %s]\n",p0->dev, c0->name, c1->name); 00477 } 00478 00479 #ifdef HALF_DUPLEX_BRIDGE 00480 00481 if (option_verbose>1) 00482 ast_verbose(VERBOSE_PREFIX_2 "%s: vpb_bridge: Starting half-duplex bridge [%s, %s]\n",p0->dev, c0->name, c1->name); 00483 00484 int dir = 0; 00485 00486 memset(p0->buf, 0, sizeof p0->buf); 00487 memset(p1->buf, 0, sizeof p1->buf); 00488 00489 vpb_record_buf_start(p0->handle, VPB_ALAW); 00490 vpb_record_buf_start(p1->handle, VPB_ALAW); 00491 00492 vpb_play_buf_start(p0->handle, VPB_ALAW); 00493 vpb_play_buf_start(p1->handle, VPB_ALAW); 00494 00495 while( !bridges[i].endbridge ) { 00496 struct vpb_pvt *from, *to; 00497 if(++dir%2) { 00498 from = p0; 00499 to = p1; 00500 } else { 00501 from = p1; 00502 to = p0; 00503 } 00504 vpb_record_buf_sync(from->handle, from->buf, VPB_SAMPLES); 00505 vpb_play_buf_sync(to->handle, from->buf, VPB_SAMPLES); 00506 } 00507 00508 vpb_record_buf_finish(p0->handle); 00509 vpb_record_buf_finish(p1->handle); 00510 00511 vpb_play_buf_finish(p0->handle); 00512 vpb_play_buf_finish(p1->handle); 00513 00514 if (option_verbose>1) 00515 ast_verbose(VERBOSE_PREFIX_2 "%s: vpb_bridge: Finished half-duplex bridge [%s, %s]\n",p0->dev, c0->name, c1->name); 00516 00517 res = VPB_OK; 00518 00519 #else 00520 00521 res = vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_ON, i+1 /* resource 1 & 2 only for V4PCI*/ ); 00522 if (res == VPB_OK) { 00523 /* pthread_cond_wait(&bridges[i].cond, &bridges[i].lock);*/ /* Wait for condition signal. */ 00524 while( !bridges[i].endbridge ) { 00525 /* Are we really ment to be doing nothing ?!?! */ 00526 who = ast_waitfor_n(cs, 2, &timeoutms); 00527 if (!who) { 00528 if (!timeoutms) { 00529 res = AST_BRIDGE_RETRY; 00530 break; 00531 } 00532 ast_log(LOG_DEBUG, "%s: vpb_bridge: Empty frame read...\n",p0->dev); 00533 /* check for hangup / whentohangup */ 00534 if (ast_check_hangup(c0) || ast_check_hangup(c1)) 00535 break; 00536 continue; 00537 } 00538 f = ast_read(who); 00539 if (!f || ((f->frametype == AST_FRAME_DTMF) && 00540 (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || 00541 ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) { 00542 *fo = f; 00543 *rc = who; 00544 ast_log(LOG_DEBUG, "%s: vpb_bridge: Got a [%s]\n",p0->dev, f ? "digit" : "hangup"); 00545 /* 00546 if ((c0->tech_pvt == pvt0) && (!c0->_softhangup)) { 00547 if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 00548 ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name); 00549 } 00550 if ((c1->tech_pvt == pvt1) && (!c1->_softhangup)) { 00551 if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 00552 ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name); 00553 } 00554 */ 00555 /* That's all we needed */ 00556 /*return 0; */ 00557 /* Check if we need to break */ 00558 if (break_for_dtmf){ 00559 break; 00560 } 00561 else if ((f->frametype == AST_FRAME_DTMF) && ((f->subclass == '#')||(f->subclass == '*'))){ 00562 break; 00563 } 00564 } else { 00565 if ((f->frametype == AST_FRAME_DTMF) || 00566 (f->frametype == AST_FRAME_VOICE) || 00567 (f->frametype == AST_FRAME_VIDEO)) 00568 { 00569 /* Forward voice or DTMF frames if they happen upon us */ 00570 /* Actually I dont think we want to forward on any frames! 00571 if (who == c0) { 00572 ast_write(c1, f); 00573 } else if (who == c1) { 00574 ast_write(c0, f); 00575 } 00576 */ 00577 } 00578 ast_frfree(f); 00579 } 00580 /* Swap priority not that it's a big deal at this point */ 00581 cs[2] = cs[0]; 00582 cs[0] = cs[1]; 00583 cs[1] = cs[2]; 00584 }; 00585 vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_OFF, i+1 /* resource 1 & 2 only for V4PCI*/ ); 00586 } 00587 00588 #endif 00589 00590 ast_mutex_lock(&bridge_lock); { 00591 bridges[i].inuse = 0; 00592 } ast_mutex_unlock(&bridge_lock); 00593 00594 p0->bridge = NULL; 00595 p1->bridge = NULL; 00596 00597 00598 if (option_verbose>1) 00599 ast_verbose(VERBOSE_PREFIX_2 "Bridging call done with [%s, %s] => %d\n", c0->name, c1->name, res); 00600 00601 /* 00602 ast_mutex_unlock(&p0->lock); 00603 ast_mutex_unlock(&p1->lock); 00604 */ 00605 return (res==VPB_OK) ? AST_BRIDGE_COMPLETE : AST_BRIDGE_FAILED; 00606 }
|
|
Definition at line 1858 of file chan_vpb.c. References ast_mutex_lock(), ast_verbose(), vpb_pvt::dev, vpb_pvt::lock, option_verbose, s, ast_channel::tech_pvt, and VERBOSE_PREFIX_4. 01859 { 01860 struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 01861 int res = 0,i; 01862 char *s = strrchr(dest, '/'); 01863 char dialstring[254] = ""; 01864 int tmp = 0; 01865 01866 /* 01867 if (option_verbose > 3) ast_verbose("%s: LOCKING in call \n", p->dev); 01868 if (option_verbose > 3) ast_verbose("%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 01869 */ 01870 ast_mutex_lock(&p->lock); 01871 if (option_verbose > 3) 01872 ast_verbose(VERBOSE_PREFIX_4 "%s: starting call to [%s]\n", p->dev,dest); 01873 01874 if (s) 01875 s = s + 1; 01876 else 01877 s = dest; 01878 strncpy(dialstring, s, sizeof(dialstring) - 1); 01879 for (i=0; dialstring[i] != '\0' ; i++) { 01880 if ((dialstring[i] == 'w') || (dialstring[i] == 'W')) 01881 dialstring[i] = ','; 01882 else if ((dialstring[i] == 'f') || (dialstring[i] == 'F')) 01883 dialstring[i] = '&'; 01884 } 01885 01886 if (ast->_state != AST_STATE_DOWN && ast->_state != AST_STATE_RESERVED) { 01887 ast_log(LOG_WARNING, "vpb_call on %s neither down nor reserved!\n", ast->name); 01888 tmp = ast_mutex_unlock(&p->lock); 01889 /* 01890 if (option_verbose > 3) ast_verbose("%s: unLOCKING in call [%d]\n", p->dev,tmp); 01891 */ 01892 return -1; 01893 } 01894 if (p->mode != MODE_FXO) /* Station port, ring it. */ 01895 res = vpb_ring_station_async(p->handle, VPB_RING_STATION_ON,0); 01896 else { 01897 VPB_CALL call; 01898 01899 /* Dial must timeout or it can leave channels unuseable */ 01900 if( timeout == 0 ) 01901 timeout = TIMER_PERIOD_NOANSWER; 01902 else 01903 timeout = timeout * 1000; /* convert from secs to ms. */ 01904 01905 /* These timeouts are only used with call progress dialing */ 01906 call.dialtones = 1; /* Number of dialtones to get outside line */ 01907 call.dialtone_timeout = VPB_DIALTONE_WAIT; /* Wait this long for dialtone (ms) */ 01908 call.ringback_timeout = VPB_RINGWAIT; /* Wait this long for ringing after dialing (ms) */ 01909 call.inter_ringback_timeout = VPB_CONNECTED_WAIT; /* If ringing stops for this long consider it connected (ms) */ 01910 call.answer_timeout = timeout; /* Time to wait for answer after ringing starts (ms) */ 01911 memcpy( &call.tone_map, DialToneMap, sizeof(DialToneMap) ); 01912 vpb_set_call(p->handle, &call); 01913 01914 if (option_verbose > 1) 01915 ast_verbose(VERBOSE_PREFIX_2 "%s: Calling %s on %s \n",p->dev, dialstring, ast->name); 01916 01917 if (option_verbose > 2) { 01918 int j; 01919 ast_verbose(VERBOSE_PREFIX_2 "%s: Dial parms for %s %d/%dms/%dms/%dms/%dms\n", p->dev 01920 , ast->name, call.dialtones, call.dialtone_timeout 01921 , call.ringback_timeout, call.inter_ringback_timeout 01922 , call.answer_timeout ); 01923 for( j=0; !call.tone_map[j].terminate; j++ ) 01924 ast_verbose(VERBOSE_PREFIX_2 "%s: Dial parms for %s tone %d->%d\n", p->dev, 01925 ast->name, call.tone_map[j].tone_id, call.tone_map[j].call_id); 01926 } 01927 01928 if (option_verbose > 3) 01929 ast_verbose("%s: Disabling Loop Drop detection\n",p->dev); 01930 vpb_disable_event(p->handle, VPB_MDROP); 01931 vpb_sethook_sync(p->handle,VPB_OFFHOOK); 01932 p->state=VPB_STATE_OFFHOOK; 01933 01934 #ifndef DIAL_WITH_CALL_PROGRESS 01935 vpb_sleep(300); 01936 if (option_verbose > 3) 01937 ast_verbose("%s: Enabling Loop Drop detection\n",p->dev); 01938 vpb_enable_event(p->handle, VPB_MDROP); 01939 res = vpb_dial_async(p->handle, dialstring); 01940 #else 01941 if (option_verbose > 3) 01942 ast_verbose("%s: Enabling Loop Drop detection\n",p->dev); 01943 vpb_enable_event(p->handle, VPB_MDROP); 01944 res = vpb_call_async(p->handle, dialstring); 01945 #endif 01946 01947 if (res != VPB_OK) { 01948 ast_log(LOG_DEBUG, "Call on %s to %s failed: %s\n", ast->name, s, vpb_strerror(res)); 01949 res = -1; 01950 } else 01951 res = 0; 01952 } 01953 01954 if (option_verbose > 2) 01955 ast_verbose(VERBOSE_PREFIX_3 "%s: VPB Calling %s [t=%d] on %s returned %d\n",p->dev , s, timeout, ast->name, res); 01956 if (res == 0) { 01957 ast_setstate(ast, AST_STATE_RINGING); 01958 ast_queue_control(ast,AST_CONTROL_RINGING); 01959 } 01960 01961 if (!p->readthread){ 01962 ast_pthread_create(&p->readthread, NULL, do_chanreads, (void *)p); 01963 } 01964 01965 tmp = ast_mutex_unlock(&p->lock); 01966 /* 01967 if (option_verbose > 3) ast_verbose("%s: unLOCKING in call [%d]\n", p->dev,tmp); 01968 */ 01969 return res; 01970 }
|
|
Definition at line 1821 of file chan_vpb.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), vpb_pvt::dev, vpb_pvt::lock, option_verbose, vpb_pvt::play_dtmf, vpb_pvt::play_dtmf_lock, s, ast_channel::tech_pvt, and VERBOSE_PREFIX_4. 01822 { 01823 struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 01824 char s[2]; 01825 int res = 0; 01826 01827 if (use_ast_dtmf){ 01828 if (option_verbose > 3) 01829 ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_digit: asked to play digit[%c] but we are using asterisk dtmf play back?!\n", p->dev, digit); 01830 return 0; 01831 } 01832 01833 /* 01834 if (option_verbose > 3) ast_verbose("%s: LOCKING in digit \n", p->dev); 01835 if (option_verbose > 3) ast_verbose("%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 01836 */ 01837 ast_mutex_lock(&p->lock); 01838 01839 01840 s[0] = digit; 01841 s[1] = '\0'; 01842 01843 if (option_verbose > 3) 01844 ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_digit: asked to play digit[%s]\n", p->dev, s); 01845 01846 ast_mutex_lock(&p->play_dtmf_lock); 01847 strncat(p->play_dtmf,s,sizeof(*p->play_dtmf)); 01848 ast_mutex_unlock(&p->play_dtmf_lock); 01849 01850 res = ast_mutex_unlock(&p->lock); 01851 /* 01852 if (option_verbose > 3) ast_verbose("%s: unLOCKING in digit [%d]\n", p->dev,res); 01853 */ 01854 return 0; 01855 }
|
|
Definition at line 1785 of file chan_vpb.c. References ast_channel::_state, AST_CONTROL_RINGING, ast_indicate(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_RINGING, ast_verbose(), vpb_pvt::dev, vpb_pvt::lock, LOG_DEBUG, ast_channel::name, option_verbose, vpb_pvt::owner, ast_channel::tech_pvt, VERBOSE_PREFIX_4, and vpb_indicate(). 01786 { 01787 struct vpb_pvt *p = (struct vpb_pvt *)newchan->tech_pvt; 01788 int res = 0; 01789 01790 /* 01791 if (option_verbose > 3) ast_verbose("%s: LOCKING in fixup \n", p->dev); 01792 if (option_verbose > 3) ast_verbose("%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 01793 */ 01794 ast_mutex_lock(&p->lock); 01795 ast_log(LOG_DEBUG, "New owner for channel %s is %s\n", p->dev, newchan->name); 01796 01797 if (p->owner == oldchan) { 01798 p->owner = newchan; 01799 } 01800 01801 if (newchan->_state == AST_STATE_RINGING){ 01802 if (use_ast_ind == 1) { 01803 if (option_verbose > 3) 01804 ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_fixup Calling ast_indicate\n", p->dev); 01805 ast_indicate(newchan, AST_CONTROL_RINGING); 01806 } 01807 else { 01808 if (option_verbose > 3) 01809 ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_fixup Calling vpb_indicate\n", p->dev); 01810 vpb_indicate(newchan, AST_CONTROL_RINGING); 01811 } 01812 } 01813 01814 res= ast_mutex_unlock(&p->lock); 01815 /* 01816 if (option_verbose > 3) ast_verbose("%s: unLOCKING in fixup [%d]\n", p->dev,res); 01817 */ 01818 return 0; 01819 }
|
|
Definition at line 1972 of file chan_vpb.c. References ast_dsp_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_DOWN, ast_update_use_count(), ast_verbose(), vpb_pvt::dialtone, vpb_pvt::ext, vpb_pvt::handle, vpb_pvt::last_ignore_dtmf, vpb_pvt::lastinput, vpb_pvt::lastoutput, vpb_pvt::lock, vpb_pvt::mode, MODE_FXO, ast_channel::name, option_verbose, vpb_pvt::owner, vpb_pvt::play_lock, vpb_pvt::readthread, restart_monitor(), vpb_pvt::state, vpb_pvt::stopreads, stoptone(), ast_channel::tech, ast_channel::tech_pvt, usecnt_lock, vpb_pvt::vad, VERBOSE_PREFIX_2, VERBOSE_PREFIX_4, and VPB_STATE_ONHOOK. 01973 { 01974 struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 01975 VPB_EVENT je; 01976 char str[VPB_MAX_STR]; 01977 int res =0 ; 01978 01979 /* 01980 if (option_verbose > 3) ast_verbose("%s: LOCKING in hangup \n", p->dev); 01981 if (option_verbose > 3) ast_verbose("%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 01982 if (option_verbose > 3) ast_verbose("%s: LOCKING pthread_self(%d)\n", p->dev,pthread_self()); 01983 ast_mutex_lock(&p->lock); 01984 */ 01985 if (option_verbose > 1) 01986 ast_verbose(VERBOSE_PREFIX_2 "%s: Hangup requested\n", ast->name); 01987 01988 if (!ast->tech || !ast->tech_pvt) { 01989 ast_log(LOG_WARNING, "%s: channel not connected?\n", ast->name); 01990 res = ast_mutex_unlock(&p->lock); 01991 /* 01992 if (option_verbose > 3) ast_verbose("%s: unLOCKING in hangup [%d]\n", p->dev,res); 01993 */ 01994 /* Free up ast dsp if we have one */ 01995 if ((use_ast_dtmfdet)&&(p->vad)) { 01996 ast_dsp_free(p->vad); 01997 p->vad = NULL; 01998 } 01999 return 0; 02000 } 02001 02002 02003 02004 /* Stop record */ 02005 p->stopreads = 1; 02006 if( p->readthread ){ 02007 pthread_join(p->readthread, NULL); 02008 if(option_verbose>3) 02009 ast_verbose( VERBOSE_PREFIX_4 "%s: stopped record thread \n",ast->name); 02010 } 02011 02012 /* Stop play */ 02013 if (p->lastoutput != -1) { 02014 if(option_verbose>1) 02015 ast_verbose( VERBOSE_PREFIX_2 "%s: Ending play mode \n",ast->name); 02016 vpb_play_terminate(p->handle); 02017 ast_mutex_lock(&p->play_lock); { 02018 vpb_play_buf_finish(p->handle); 02019 } ast_mutex_unlock(&p->play_lock); 02020 } 02021 02022 if(option_verbose>3) 02023 ast_verbose( VERBOSE_PREFIX_4 "%s: Setting state down\n",ast->name); 02024 ast_setstate(ast,AST_STATE_DOWN); 02025 02026 02027 /* 02028 if (option_verbose > 3) ast_verbose("%s: LOCKING in hangup \n", p->dev); 02029 if (option_verbose > 3) ast_verbose("%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 02030 if (option_verbose > 3) ast_verbose("%s: LOCKING pthread_self(%d)\n", p->dev,pthread_self()); 02031 */ 02032 ast_mutex_lock(&p->lock); 02033 02034 if (p->mode != MODE_FXO) { 02035 /* station port. */ 02036 vpb_ring_station_async(p->handle, VPB_RING_STATION_OFF,0); 02037 if(p->state!=VPB_STATE_ONHOOK){ 02038 /* This is causing a "dial end" "play tone" loop 02039 playtone(p->handle, &Busytone); 02040 p->state = VPB_STATE_PLAYBUSY; 02041 if(option_verbose>4) 02042 ast_verbose( VERBOSE_PREFIX_4 "%s: Station offhook[%d], playing busy tone\n", 02043 ast->name,p->state); 02044 */ 02045 } 02046 else { 02047 stoptone(p->handle); 02048 } 02049 #ifdef VPB_PRI 02050 vpb_setloop_async(p->handle, VPB_OFFHOOK); 02051 vpb_sleep(100); 02052 vpb_setloop_async(p->handle, VPB_ONHOOK); 02053 #endif 02054 } else { 02055 stoptone(p->handle); /* Terminates any dialing */ 02056 vpb_sethook_sync(p->handle, VPB_ONHOOK); 02057 p->state=VPB_STATE_ONHOOK; 02058 } 02059 while (VPB_OK==vpb_get_event_ch_async(p->handle,&je)){ 02060 if(option_verbose>3) { 02061 vpb_translate_event(&je, str); 02062 ast_verbose( VERBOSE_PREFIX_4 "%s: Flushing event [%d]=>%s\n",ast->name,je.type,str); 02063 } 02064 } 02065 02066 p->readthread = 0; 02067 p->lastoutput = -1; 02068 p->lastinput = -1; 02069 p->last_ignore_dtmf = 1; 02070 p->ext[0] = 0; 02071 p->dialtone = 0; 02072 02073 p->owner = NULL; 02074 ast->tech_pvt=NULL; 02075 02076 /* Free up ast dsp if we have one */ 02077 if ((use_ast_dtmfdet)&&(p->vad)) { 02078 ast_dsp_free(p->vad); 02079 p->vad = NULL; 02080 } 02081 02082 ast_mutex_lock(&usecnt_lock); { 02083 usecnt--; 02084 } ast_mutex_unlock(&usecnt_lock); 02085 ast_update_use_count(); 02086 02087 if (option_verbose > 1) 02088 ast_verbose(VERBOSE_PREFIX_2 "%s: Hangup complete\n", ast->name); 02089 02090 restart_monitor(); 02091 /* 02092 if (option_verbose > 3) ast_verbose("%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 02093 */ 02094 res = ast_mutex_unlock(&p->lock); 02095 /* 02096 if (option_verbose > 3) ast_verbose("%s: unLOCKING in hangup [%d]\n", p->dev,res); 02097 if (option_verbose > 3) ast_verbose("%s: LOCKING in hangup count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 02098 */ 02099 return 0; 02100 }
|
|
Definition at line 1712 of file chan_vpb.c. References ast_channel::_state, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_UP, ast_verbose(), vpb_pvt::busy_timer, vpb_pvt::dev, vpb_pvt::handle, vpb_pvt::lock, option_verbose, playtone(), vpb_pvt::ringback_timer, vpb_pvt::ringback_timer_id, vpb_pvt::state, stoptone(), ast_channel::tech_pvt, VERBOSE_PREFIX_4, VPB_STATE_PLAYBUSY, and VPB_STATE_PLAYRING. Referenced by vpb_fixup(). 01713 { 01714 struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 01715 int res = 0; 01716 int tmp = 0; 01717 01718 if (use_ast_ind == 1) { 01719 if (option_verbose > 3) 01720 ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_indicate called when using Ast Indications !?!\n", p->dev); 01721 return 0; 01722 } 01723 01724 if (option_verbose > 3) 01725 ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_indicate [%d] state[%d]\n", p->dev, condition,ast->_state); 01726 /* 01727 if (ast->_state != AST_STATE_UP) { 01728 ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_indicate Not in AST_STATE_UP\n", p->dev, condition,ast->_state); 01729 return res; 01730 } 01731 */ 01732 01733 /* 01734 if (option_verbose > 3) ast_verbose("%s: LOCKING in indicate \n", p->dev); 01735 if (option_verbose > 3) ast_verbose("%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner); 01736 */ 01737 ast_mutex_lock(&p->lock); 01738 switch(condition) { 01739 case AST_CONTROL_BUSY: 01740 case AST_CONTROL_CONGESTION: 01741 if (ast->_state == AST_STATE_UP) { 01742 playtone(p->handle, &Busytone); 01743 p->state = VPB_STATE_PLAYBUSY; 01744 vpb_timer_stop(p->busy_timer); 01745 vpb_timer_start(p->busy_timer); 01746 } 01747 break; 01748 case AST_CONTROL_RINGING: 01749 if (ast->_state == AST_STATE_UP) { 01750 playtone(p->handle, &Ringbacktone); 01751 p->state = VPB_STATE_PLAYRING; 01752 if (option_verbose > 3) 01753 ast_verbose(VERBOSE_PREFIX_4 "%s: vpb indicate: setting ringback timer [%d]\n", p->dev,p->ringback_timer_id); 01754 01755 vpb_timer_stop(p->ringback_timer); 01756 vpb_timer_start(p->ringback_timer); 01757 } 01758 break; 01759 case AST_CONTROL_ANSWER: 01760 case -1: /* -1 means stop playing? */ 01761 vpb_timer_stop(p->ringback_timer); 01762 vpb_timer_stop(p->busy_timer); 01763 stoptone(p->handle); 01764 break; 01765 case AST_CONTROL_HANGUP: 01766 if (ast->_state == AST_STATE_UP) { 01767 playtone(p->handle, &Busytone); 01768 p->state = VPB_STATE_PLAYBUSY; 01769 vpb_timer_stop(p->busy_timer); 01770 vpb_timer_start(p->busy_timer); 01771 } 01772 break; 01773 01774 default: 01775 res = 0; 01776 break; 01777 } 01778 tmp = ast_mutex_unlock(&p->lock); 01779 /* 01780 if (option_verbose > 3) ast_verbose("%s: unLOCKING in indicate [%d]\n", p->dev,tmp); 01781 */ 01782 return res; 01783 }
|
|
Definition at line 2609 of file chan_vpb.c. References ast_callerid_split(), ast_channel_alloc(), AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_set_callerid(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_UP, ast_update_use_count(), ast_verbose(), vpb_pvt::bridge, vpb_pvt::callerid, vpb_pvt::callgroup, ast_channel::callgroup, cid_name, cid_num, ast_channel::context, vpb_pvt::dev, vpb_pvt::ext, ast_channel::exten, vpb_pvt::faxhandled, ast_channel::language, vpb_pvt::language, vpb_pvt::last_ignore_dtmf, vpb_pvt::lastgrunt, vpb_pvt::lastinput, vpb_pvt::lastoutput, vpb_pvt::lastplay, vpb_pvt::mode, MODE_FXO, ast_channel::name, ast_channel::nativeformats, option_verbose, vpb_pvt::owner, vpb_pvt::pickupgroup, ast_channel::pickupgroup, vpb_pvt::play_dtmf, ast_channel::rawreadformat, ast_channel::rawwriteformat, vpb_pvt::readthread, ast_channel::rings, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt_lock, vpb_answer(), vpb_tech, and vpb_tech_indicate. Referenced by monitor_handle_notowned(), and vpb_request(). 02610 { 02611 struct ast_channel *tmp; 02612 char cid_num[256]; 02613 char cid_name[256]; 02614 02615 if (me->owner) { 02616 ast_log(LOG_WARNING, "Called vpb_new on owned channel (%s) ?!\n", me->dev); 02617 return NULL; 02618 } 02619 if (option_verbose > 3) 02620 ast_verbose("%s: New call for context [%s]\n",me->dev,context); 02621 02622 tmp = ast_channel_alloc(1); 02623 if (tmp) { 02624 if (use_ast_ind == 1){ 02625 tmp->tech = &vpb_tech_indicate; 02626 } 02627 else { 02628 tmp->tech = &vpb_tech; 02629 } 02630 02631 strncpy(tmp->name, me->dev, sizeof(tmp->name) - 1); 02632 tmp->type = type; 02633 02634 tmp->callgroup = me->callgroup; 02635 tmp->pickupgroup = me->pickupgroup; 02636 02637 /* Linear is the preferred format. Although Voicetronix supports other formats 02638 * they are all converted to/from linear in the vpb code. Best for us to use 02639 * linear since we can then adjust volume in this modules. 02640 */ 02641 tmp->nativeformats = prefformat; 02642 tmp->rawreadformat = AST_FORMAT_SLINEAR; 02643 tmp->rawwriteformat = AST_FORMAT_SLINEAR; 02644 ast_setstate(tmp, state); 02645 if (state == AST_STATE_RING) { 02646 tmp->rings = 1; 02647 cid_name[0] = '\0'; 02648 cid_num[0] = '\0'; 02649 ast_callerid_split(me->callerid, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 02650 ast_set_callerid(tmp, cid_num, cid_name, cid_num); 02651 } 02652 tmp->tech_pvt = me; 02653 02654 strncpy(tmp->context, context, sizeof(tmp->context)-1); 02655 if (strlen(me->ext)) 02656 strncpy(tmp->exten, me->ext, sizeof(tmp->exten)-1); 02657 else 02658 strncpy(tmp->exten, "s", sizeof(tmp->exten) - 1); 02659 if (strlen(me->language)) 02660 strncpy(tmp->language, me->language, sizeof(tmp->language)-1); 02661 02662 me->owner = tmp; 02663 02664 me->bridge = NULL; 02665 me->lastoutput = -1; 02666 me->lastinput = -1; 02667 me->last_ignore_dtmf = 1; 02668 me->readthread = 0; 02669 me->play_dtmf[0] = '\0'; 02670 me->faxhandled =0; 02671 02672 me->lastgrunt = ast_tvnow(); /* Assume at least one grunt tone seen now. */ 02673 me->lastplay = ast_tvnow(); /* Assume at least one grunt tone seen now. */ 02674 02675 ast_mutex_lock(&usecnt_lock); 02676 usecnt++; 02677 ast_mutex_unlock(&usecnt_lock); 02678 ast_update_use_count(); 02679 if (state != AST_STATE_DOWN) { 02680 if ((me->mode != MODE_FXO)&&(state != AST_STATE_UP)){ 02681 vpb_answer(tmp); 02682 } 02683 if (ast_pbx_start(tmp)) { 02684 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 02685 ast_hangup(tmp); 02686 } 02687 } 02688 } else { 02689 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 02690 } 02691 return tmp; 02692 }
|
|
Definition at line 2176 of file chan_vpb.c. References AST_FRAME_NULL, and ast_channel::tech_pvt. 02177 { 02178 struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 02179 static struct ast_frame f = {AST_FRAME_NULL}; 02180 02181 f.src = (char *)type; 02182 ast_log(LOG_NOTICE, "%s: vpb_read: should never be called!\n", p->dev); 02183 ast_verbose("%s: vpb_read: should never be called!\n", p->dev); 02184 02185 return &f; 02186 }
|
|
Definition at line 2694 of file chan_vpb.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, ast_verbose(), vpb_pvt::context, vpb_pvt::dev, free, vpb_pvt::group, group, iflist, LOG_NOTICE, ast_channel::name, name, vpb_pvt::next, option_verbose, vpb_pvt::owner, restart_monitor(), s, strdup, strsep(), VERBOSE_PREFIX_2, and vpb_new(). 02695 { 02696 int oldformat; 02697 struct vpb_pvt *p; 02698 struct ast_channel *tmp = NULL; 02699 char *name = strdup(data ? (char *)data : ""); 02700 char *s, *sepstr; 02701 int group=-1; 02702 02703 oldformat = format; 02704 format &= prefformat; 02705 if (!format) { 02706 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat); 02707 return NULL; 02708 } 02709 02710 sepstr = name; 02711 s = strsep(&sepstr, "/"); /* Handle / issues */ 02712 if (!s) 02713 s = ""; 02714 /* Check if we are looking for a group */ 02715 if (toupper(name[0]) == 'G' || toupper(name[0])=='R') { 02716 group=atoi(name+1); 02717 } 02718 /* Search for an unowned channel */ 02719 ast_mutex_lock(&iflock); { 02720 p = iflist; 02721 while(p) { 02722 if (group == -1){ 02723 if (strncmp(s, p->dev + 4, sizeof p->dev) == 0) { 02724 if (!p->owner) { 02725 tmp = vpb_new(p, AST_STATE_DOWN, p->context); 02726 break; 02727 } 02728 } 02729 } 02730 else { 02731 if ((p->group == group) && (!p->owner)) { 02732 tmp = vpb_new(p, AST_STATE_DOWN, p->context); 02733 break; 02734 } 02735 } 02736 p = p->next; 02737 } 02738 } ast_mutex_unlock(&iflock); 02739 02740 02741 if (option_verbose > 1) 02742 ast_verbose(VERBOSE_PREFIX_2 " %s requested, got: [%s]\n", 02743 name, tmp ? tmp->name : "None"); 02744 02745 free(name); 02746 02747 restart_monitor(); 02748 return tmp; 02749 }
|
|
Definition at line 2251 of file chan_vpb.c. References ast_channel::_state, a_gain_vector(), ast2vpbformat(), ast2vpbformatname(), AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_UP, ast_verbose(), vpb_pvt::chuck_count, ast_frame::data, ast_frame::datalen, vpb_pvt::dev, fmt, ast_frame::frametype, vpb_pvt::handle, vpb_pvt::lastoutput, vpb_pvt::lastplay, LOG_DEBUG, MAX_VPB_GAIN, ast_channel::name, option_verbose, vpb_pvt::play_buf_time, vpb_pvt::play_lock, vpb_pvt::read_state, ast_frame::subclass, ast_channel::tech_pvt, vpb_pvt::txswgain, and VPB_SAMPLES. 02252 { 02253 struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 02254 int res = 0, fmt = 0; 02255 struct timeval play_buf_time_start; 02256 struct ast_frame *nextf; 02257 int tdiff; 02258 02259 /* ast_mutex_lock(&p->lock); */ 02260 if(option_verbose>5) 02261 ast_verbose("%s: vpb_write: Writing to channel\n", p->dev); 02262 02263 if (frame->frametype != AST_FRAME_VOICE) { 02264 if(option_verbose>3) 02265 ast_verbose("%s: vpb_write: Don't know how to handle from type %d\n", ast->name, frame->frametype); 02266 /* ast_mutex_unlock(&p->lock); */ 02267 return 0; 02268 } else if (ast->_state != AST_STATE_UP) { 02269 if(option_verbose>3) 02270 ast_verbose("%s: vpb_write: Attempt to Write frame type[%d]subclass[%d] on not up chan(state[%d])\n",ast->name, frame->frametype, frame->subclass,ast->_state); 02271 p->lastoutput = -1; 02272 /* ast_mutex_unlock(&p->lock); */ 02273 return 0; 02274 } 02275 /* ast_log(LOG_DEBUG, "%s: vpb_write: Checked frame type..\n", p->dev); */ 02276 02277 02278 fmt = ast2vpbformat(frame->subclass); 02279 if (fmt < 0) { 02280 ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %d format!\n",ast->name, frame->subclass); 02281 return -1; 02282 } 02283 02284 tdiff = ast_tvdiff_ms(ast_tvnow(), p->lastplay); 02285 ast_log(LOG_DEBUG, "%s: vpb_write: time since last play(%d) \n", p->dev, tdiff); 02286 if (tdiff < (VPB_SAMPLES/8 - 1)){ 02287 ast_log(LOG_DEBUG, "%s: vpb_write: Asked to play too often (%d) (%d)\n", p->dev, tdiff,frame->datalen); 02288 // return 0; 02289 } 02290 p->lastplay = ast_tvnow(); 02291 /* 02292 ast_log(LOG_DEBUG, "%s: vpb_write: Checked frame format..\n", p->dev); 02293 */ 02294 02295 ast_mutex_lock(&p->play_lock); 02296 02297 /* 02298 ast_log(LOG_DEBUG, "%s: vpb_write: Got play lock..\n", p->dev); 02299 */ 02300 02301 /* Check if we have set up the play_buf */ 02302 if (p->lastoutput == -1) { 02303 vpb_play_buf_start(p->handle, fmt); 02304 if(option_verbose>1) { 02305 ast_verbose("%s: vpb_write: Starting play mode (codec=%d)[%s]\n",p->dev,fmt,ast2vpbformatname(frame->subclass)); 02306 } 02307 p->lastoutput = fmt; 02308 ast_mutex_unlock(&p->play_lock); 02309 return 0; 02310 } else if (p->lastoutput != fmt) { 02311 vpb_play_buf_finish(p->handle); 02312 vpb_play_buf_start(p->handle, fmt); 02313 if(option_verbose>1) 02314 ast_verbose("%s: vpb_write: Changed play format (%d=>%d)\n",p->dev,p->lastoutput,fmt); 02315 ast_mutex_unlock(&p->play_lock); 02316 return 0; 02317 } 02318 p->lastoutput = fmt; 02319 02320 02321 02322 /* Apply extra gain ! */ 02323 if( p->txswgain > MAX_VPB_GAIN ) 02324 a_gain_vector(p->txswgain - MAX_VPB_GAIN , (short*)frame->data, frame->datalen/sizeof(short)); 02325 02326 /* ast_log(LOG_DEBUG, "%s: vpb_write: Applied gain..\n", p->dev); */ 02327 /* ast_log(LOG_DEBUG, "%s: vpb_write: play_buf_time %d\n", p->dev, p->play_buf_time); */ 02328 02329 if ((p->read_state == 1)&&(p->play_buf_time<5)){ 02330 play_buf_time_start = ast_tvnow(); 02331 /* res = vpb_play_buf_sync(p->handle, (char*)frame->data, tdiff*8*2); */ 02332 res = vpb_play_buf_sync(p->handle, (char*)frame->data, frame->datalen); 02333 if( res == VPB_OK && option_verbose > 5 ) { 02334 short * data = (short*)frame->data; 02335 ast_verbose("%s: vpb_write: Wrote chan (codec=%d) %d %d\n", p->dev, fmt, data[0],data[1]); 02336 } 02337 p->play_buf_time = ast_tvdiff_ms(ast_tvnow(), play_buf_time_start); 02338 } 02339 else { 02340 p->chuck_count++; 02341 ast_log(LOG_DEBUG, "%s: vpb_write: Tossed data away, tooooo much data!![%d]\n", p->dev,p->chuck_count); 02342 p->play_buf_time=0; 02343 } 02344 02345 ast_mutex_unlock(&p->play_lock); 02346 /* ast_mutex_unlock(&p->lock); */ 02347 if(option_verbose>5) 02348 ast_verbose("%s: vpb_write: Done Writing to channel\n", p->dev); 02349 return 0; 02350 }
|
|
Definition at line 177 of file chan_vpb.c. |
|
Definition at line 245 of file chan_vpb.c. Referenced by mkbrd(), unload_module(), and vpb_bridge(). |
|
Definition at line 143 of file chan_vpb.c. |
|
Definition at line 98 of file chan_vpb.c. |
|
Definition at line 101 of file chan_vpb.c. |
|
Definition at line 95 of file chan_vpb.c. |
|
Definition at line 142 of file chan_vpb.c. |
|
Definition at line 206 of file chan_vpb.c. |
|
Definition at line 183 of file chan_vpb.c. |
|
Definition at line 180 of file chan_vpb.c. |
|
Definition at line 107 of file chan_vpb.c. |
|
|
|
Definition at line 104 of file chan_vpb.c. |
|
Definition at line 246 of file chan_vpb.c. |
|
Definition at line 122 of file chan_vpb.c. |
|
Definition at line 124 of file chan_vpb.c. |
|
Definition at line 109 of file chan_vpb.c. |
|
Definition at line 171 of file chan_vpb.c. |
|
Definition at line 144 of file chan_vpb.c. |
|
Definition at line 97 of file chan_vpb.c. |
|
Definition at line 188 of file chan_vpb.c. |
|
Definition at line 153 of file chan_vpb.c. |
|
Definition at line 154 of file chan_vpb.c. |
|
Definition at line 96 of file chan_vpb.c. |
|
Definition at line 174 of file chan_vpb.c. |
|
Definition at line 169 of file chan_vpb.c. |
|
Definition at line 166 of file chan_vpb.c. |
|
Definition at line 105 of file chan_vpb.c. |
|
Definition at line 160 of file chan_vpb.c. |
|
Definition at line 163 of file chan_vpb.c. |
|
Definition at line 157 of file chan_vpb.c. |
|
Definition at line 351 of file chan_vpb.c. Referenced by load_module(), unload_module(), and vpb_new(). |
|
Definition at line 378 of file chan_vpb.c. Referenced by load_module(), unload_module(), and vpb_new(). |