/ implemented basic group'ing, as per chan_zap

/ reformated whole file to consistent format


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2624 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Ben Kramer 22 years ago
parent 940a5deb2e
commit 09e0fc2074

@ -9,12 +9,6 @@
* *
* This program is free software, distributed under the terms of * This program is free software, distributed under the terms of
* the GNU General Public License * the GNU General Public License
*
*/
/* This module is now being supported by Voicetronix. If you wish to submit
* any patches to it please email them to support@voicetronix.com.au
*
*/ */
#include <stdio.h> #include <stdio.h>
@ -36,6 +30,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <ctype.h>
#include <vpbapi.h> #include <vpbapi.h>
@ -185,6 +180,8 @@ static struct vpb_pvt {
int state; /* used to keep port state (internal to driver) */ int state; /* used to keep port state (internal to driver) */
int group; /* Which group this port belongs to */
char dev[256]; char dev[256];
vpb_model_t vpb_model; vpb_model_t vpb_model;
@ -277,7 +274,6 @@ static int vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
ast_log(LOG_WARNING, "Failed to bridge %s and %s!\n", c0->name, c1->name); ast_log(LOG_WARNING, "Failed to bridge %s and %s!\n", c0->name, c1->name);
return -2; return -2;
} else { } else {
/* Set bridge pointers. You don't want to take these locks while holding bridge lock.*/ /* Set bridge pointers. You don't want to take these locks while holding bridge lock.*/
ast_mutex_lock(&p0->lock); { ast_mutex_lock(&p0->lock); {
p0->bridge = &bridges[i]; p0->bridge = &bridges[i];
@ -406,7 +402,8 @@ static void get_callerid(struct vpb_pvt *p)
vpb_sleep(RING_SKIP); vpb_sleep(RING_SKIP);
if (option_verbose>3) if (option_verbose>3)
ast_verbose(VERBOSE_PREFIX_4 "CID record - skipped %fms trailing ring\n", get_time_in_ms() - cid_record_time); ast_verbose(VERBOSE_PREFIX_4 "CID record - skipped %fms trailing ring\n",
get_time_in_ms() - cid_record_time);
cid_record_time = get_time_in_ms(); cid_record_time = get_time_in_ms();
// Record bit between the rings which contains the callerid // Record bit between the rings which contains the callerid
@ -416,7 +413,8 @@ static void get_callerid(struct vpb_pvt *p)
#endif #endif
if (option_verbose>3) if (option_verbose>3)
ast_verbose(VERBOSE_PREFIX_4 "CID record - recorded %fms between rings\n", get_time_in_ms() - cid_record_time); ast_verbose(VERBOSE_PREFIX_4 "CID record - recorded %fms between rings\n",
get_time_in_ms() - cid_record_time);
ast_mutex_unlock(&p->record_lock); ast_mutex_unlock(&p->record_lock);
@ -427,7 +425,8 @@ static void get_callerid(struct vpb_pvt *p)
// This decodes FSK 1200baud type callerid // This decodes FSK 1200baud type callerid
if ((rc=vpb_cid_decode(callerid, buf, CID_MSECS*8)) == VPB_OK ) { if ((rc=vpb_cid_decode(callerid, buf, CID_MSECS*8)) == VPB_OK ) {
if(!*callerid) strcpy(callerid,"undisclosed"); // blocked CID (eg caller used 1831) if(!*callerid)
strcpy(callerid,"undisclosed"); // blocked CID (eg caller used 1831)
} else { } else {
ast_log(LOG_ERROR, "Failed to decode caller id on %s - %s\n", p->dev, vpb_strerror(rc) ); ast_log(LOG_ERROR, "Failed to decode caller id on %s - %s\n", p->dev, vpb_strerror(rc) );
strcpy(callerid,"unknown"); strcpy(callerid,"unknown");
@ -471,9 +470,11 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
} else } else
f.frametype = -1; /* ignore ring on station port. */ f.frametype = -1; /* ignore ring on station port. */
break; break;
case VPB_RING_OFF: case VPB_RING_OFF:
f.frametype = -1; f.frametype = -1;
break; break;
case VPB_TIMEREXP: case VPB_TIMEREXP:
if (e->data == p->busy_timer_id) { if (e->data == p->busy_timer_id) {
playtone(p->handle,&Busytone); playtone(p->handle,&Busytone);
@ -488,6 +489,7 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
f.frametype = -1; /* Ignore. */ f.frametype = -1; /* Ignore. */
} }
break; break;
case VPB_DTMF: case VPB_DTMF:
if (p->owner->_state == AST_STATE_UP) { if (p->owner->_state == AST_STATE_UP) {
f.frametype = AST_FRAME_DTMF; f.frametype = AST_FRAME_DTMF;
@ -509,7 +511,8 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
if( ( get_time_in_ms() - p->lastgrunt ) > gruntdetect_timeout ) { if( ( get_time_in_ms() - p->lastgrunt ) > gruntdetect_timeout ) {
// Nothing heard on line for a very long time // Nothing heard on line for a very long time
// Timeout connection // Timeout connection
if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "grunt timeout\n"); if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "grunt timeout\n");
ast_log(LOG_NOTICE,"Line hangup due of lack of conversation\n"); ast_log(LOG_NOTICE,"Line hangup due of lack of conversation\n");
f.subclass = AST_CONTROL_HANGUP; f.subclass = AST_CONTROL_HANGUP;
} else { } else {
@ -524,11 +527,9 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
#ifdef DIAL_WITH_CALL_PROGRESS #ifdef DIAL_WITH_CALL_PROGRESS
if (e->data == VPB_CALL_CONNECTED) if (e->data == VPB_CALL_CONNECTED)
f.subclass = AST_CONTROL_ANSWER; f.subclass = AST_CONTROL_ANSWER;
else if (e->data == VPB_CALL_NO_DIAL_TONE || else if (e->data == VPB_CALL_NO_DIAL_TONE || e->data == VPB_CALL_NO_RING_BACK)
e->data == VPB_CALL_NO_RING_BACK)
f.subclass = AST_CONTROL_CONGESTION; f.subclass = AST_CONTROL_CONGESTION;
else if (e->data == VPB_CALL_NO_ANSWER || else if (e->data == VPB_CALL_NO_ANSWER || e->data == VPB_CALL_BUSY)
e->data == VPB_CALL_BUSY)
f.subclass = AST_CONTROL_BUSY; f.subclass = AST_CONTROL_BUSY;
else if (e->data == VPB_CALL_DISCONNECTED) else if (e->data == VPB_CALL_DISCONNECTED)
f.subclass = AST_CONTROL_HANGUP; f.subclass = AST_CONTROL_HANGUP;
@ -541,6 +542,7 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
case VPB_STATION_OFFHOOK: case VPB_STATION_OFFHOOK:
f.subclass = AST_CONTROL_ANSWER; f.subclass = AST_CONTROL_ANSWER;
break; break;
/* not sure why this was commented out */ /* not sure why this was commented out */
case VPB_DROP: case VPB_DROP:
if (p->mode == MODE_FXO){ /* ignore loop drop on stations */ if (p->mode == MODE_FXO){ /* ignore loop drop on stations */
@ -608,8 +610,8 @@ static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
#endif #endif
endbridge = 1; endbridge = 1;
break; break;
default:
default:
break; break;
} }
if (endbridge) { if (endbridge) {
@ -659,8 +661,10 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
get_callerid(p); /* Australian Caller ID only between 1st and 2nd ring */ get_callerid(p); /* Australian Caller ID only between 1st and 2nd ring */
} }
break; break;
case VPB_RING_OFF: case VPB_RING_OFF:
break; break;
case VPB_STATION_OFFHOOK: case VPB_STATION_OFFHOOK:
if (p->mode == MODE_IMMEDIATE) if (p->mode == MODE_IMMEDIATE)
vpb_new(p,AST_STATE_RING, p->context); vpb_new(p,AST_STATE_RING, p->context);
@ -672,6 +676,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
p->state=VPB_STATE_PLAYDIAL; p->state=VPB_STATE_PLAYDIAL;
} }
break; break;
case VPB_DIALEND: case VPB_DIALEND:
if (p->mode == MODE_DIALTONE){ if (p->mode == MODE_DIALTONE){
if (p->state == VPB_STATE_PLAYDIAL) { if (p->state == VPB_STATE_PLAYDIAL) {
@ -709,7 +714,6 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
p->state=VPB_STATE_GETDTMF; p->state=VPB_STATE_GETDTMF;
s[0] = e->data; s[0] = e->data;
strcat(p->ext, s); strcat(p->ext, s);
if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)) if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid))
vpb_new(p,AST_STATE_RING, p->context); vpb_new(p,AST_STATE_RING, p->context);
else if (!ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)) else if (!ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid))
@ -717,14 +721,12 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
vpb_new(p,AST_STATE_RING, "default"); vpb_new(p,AST_STATE_RING, "default");
else if (!ast_canmatch_extension(NULL, "default", p->ext, 1, p->callerid)) { else if (!ast_canmatch_extension(NULL, "default", p->ext, 1, p->callerid)) {
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, ast_log(LOG_DEBUG, "%s can't match anything in %s or default\n",
"%s can't match anything in %s or default\n",
p->ext, p->context); p->ext, p->context);
playtone(p->handle, &Busytone); playtone(p->handle, &Busytone);
vpb_timer_start(p->busy_timer); vpb_timer_start(p->busy_timer);
p->state = VPB_STATE_PLAYBUSY; p->state = VPB_STATE_PLAYBUSY;
} }
break; break;
default: default:
@ -751,7 +753,6 @@ static void *do_monitor(void *unused)
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
for(;;) { for(;;) {
VPB_EVENT e; VPB_EVENT e;
VPB_EVENT je; VPB_EVENT je;
char str[VPB_MAX_STR]; char str[VPB_MAX_STR];
@ -775,7 +776,6 @@ static void *do_monitor(void *unused)
p = NULL; p = NULL;
ast_mutex_lock(&monlock); { ast_mutex_lock(&monlock); {
vpb_translate_event(&e, str); vpb_translate_event(&e, str);
if (e.type == VPB_NULL_EVENT) { if (e.type == VPB_NULL_EVENT) {
@ -796,7 +796,6 @@ static void *do_monitor(void *unused)
if (p && (option_verbose > 3)) if (p && (option_verbose > 3))
ast_verbose(VERBOSE_PREFIX_4 "Event [%d=>%s] on %s\n", ast_verbose(VERBOSE_PREFIX_4 "Event [%d=>%s] on %s\n",
e.type, str, p ? p->dev : "null"); e.type, str, p ? p->dev : "null");
done: (void)0; done: (void)0;
} ast_mutex_unlock(&monlock); } ast_mutex_unlock(&monlock);
@ -856,7 +855,6 @@ static int restart_monitor(void)
ast_verbose(VERBOSE_PREFIX_4 "Trying to reawake monitor\n"); ast_verbose(VERBOSE_PREFIX_4 "Trying to reawake monitor\n");
vpb_put_event(&e); vpb_put_event(&e);
} else { } else {
/* Start a new monitor */ /* Start a new monitor */
int pid = pthread_create(&monitor_thread, NULL, do_monitor, NULL); int pid = pthread_create(&monitor_thread, NULL, do_monitor, NULL);
@ -885,8 +883,10 @@ static void mkbrd(vpb_model_t model, int echo_cancel)
if(model==vpb_model_v4pci) if(model==vpb_model_v4pci)
max_bridges = MAX_BRIDGES_V4PCI; max_bridges = MAX_BRIDGES_V4PCI;
bridges = (vpb_bridge_t *)malloc(max_bridges * sizeof(vpb_bridge_t) ); bridges = (vpb_bridge_t *)malloc(max_bridges * sizeof(vpb_bridge_t) );
if(!bridges) ast_log(LOG_ERROR, "Failed to initialize bridges\n"); if(!bridges)
else memset(bridges,0,max_bridges * sizeof(vpb_bridge_t)); ast_log(LOG_ERROR, "Failed to initialize bridges\n");
else
memset(bridges,0,max_bridges * sizeof(vpb_bridge_t));
} }
if(!echo_cancel) { if(!echo_cancel) {
if (model==vpb_model_v4pci) { if (model==vpb_model_v4pci) {
@ -909,7 +909,7 @@ static void mkbrd(vpb_model_t model, int echo_cancel)
struct vpb_pvt *mkif(int board, int channel, int mode, float txgain, float rxgain, struct vpb_pvt *mkif(int board, int channel, int mode, float txgain, float rxgain,
float txswgain, float rxswgain, int bal1, int bal2, int bal3, float txswgain, float rxswgain, int bal1, int bal2, int bal3,
char * callerid, int echo_cancel ) char * callerid, int echo_cancel, int group )
{ {
struct vpb_pvt *tmp; struct vpb_pvt *tmp;
char buf[64]; char buf[64];
@ -932,6 +932,8 @@ struct vpb_pvt *mkif(int board, int channel, int mode, float txgain, float rxgai
tmp->mode = mode; tmp->mode = mode;
tmp->group = group;
strcpy(tmp->language, language); strcpy(tmp->language, language);
strcpy(tmp->context, context); strcpy(tmp->context, context);
@ -1010,8 +1012,7 @@ static int vpb_indicate(struct ast_channel *ast, int condition)
int res = 0; int res = 0;
if (option_verbose > 3) if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 " vpb indicate on %s with %d\n", ast_verbose(VERBOSE_PREFIX_4 " vpb indicate on %s with %d\n", p->dev, condition);
p->dev, condition);
switch(condition) { switch(condition) {
case AST_CONTROL_BUSY: case AST_CONTROL_BUSY:
@ -1102,8 +1103,10 @@ static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
VPB_CALL call; VPB_CALL call;
// Dial must timeout or it can leave channels unuseable // Dial must timeout or it can leave channels unuseable
if( timeout == 0 ) timeout = TIMER_PERIOD_NOANSWER; if( timeout == 0 )
else timeout = timeout * 1000; //convert from secs to ms. timeout = TIMER_PERIOD_NOANSWER;
else
timeout = timeout * 1000; //convert from secs to ms.
// These timeouts are only used with call progress dialing // These timeouts are only used with call progress dialing
call.dialtones = 1; // Number of dialtones to get outside line call.dialtones = 1; // Number of dialtones to get outside line
@ -1115,8 +1118,7 @@ static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
vpb_set_call(p->handle, &call); vpb_set_call(p->handle, &call);
if (option_verbose > 1) if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Calling %s on %s \n", ast_verbose(VERBOSE_PREFIX_2 "Calling %s on %s \n", s, ast->name);
s, ast->name);
if (option_verbose > 2) { if (option_verbose > 2) {
int j; int j;
@ -1139,18 +1141,14 @@ static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
#endif #endif
if (res != VPB_OK) { if (res != VPB_OK) {
ast_log(LOG_DEBUG, "Call on %s to %s failed: %s\n", ast_log(LOG_DEBUG, "Call on %s to %s failed: %s\n", ast->name, s, vpb_strerror(res));
ast->name, s, vpb_strerror(res));
res = -1; res = -1;
} else } else
res = 0; res = 0;
} }
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 ast_verbose(VERBOSE_PREFIX_3 " VPB Calling %s [t=%d] on %s returned %d\n", s, timeout, ast->name, res);
" VPB Calling %s [t=%d] on %s returned %d\n",
s, timeout, ast->name, res);
if (res == 0) { if (res == 0) {
ast_setstate(ast, AST_STATE_RINGING); ast_setstate(ast, AST_STATE_RINGING);
ast_queue_control(ast,AST_CONTROL_RINGING, 0); ast_queue_control(ast,AST_CONTROL_RINGING, 0);
@ -1196,7 +1194,6 @@ static int vpb_hangup(struct ast_channel *ast)
vpb_ring_station_async(p->handle, VPB_RING_STATION_OFF,0); vpb_ring_station_async(p->handle, VPB_RING_STATION_OFF,0);
playtone(p->handle, &Busytone); playtone(p->handle, &Busytone);
p->state = VPB_STATE_PLAYBUSY; p->state = VPB_STATE_PLAYBUSY;
} else { } else {
stoptone(p->handle); // Terminates any dialing stoptone(p->handle); // Terminates any dialing
vpb_sethook_sync(p->handle, VPB_ONHOOK); vpb_sethook_sync(p->handle, VPB_ONHOOK);
@ -1223,7 +1220,6 @@ static int vpb_hangup(struct ast_channel *ast)
ast_verbose(VERBOSE_PREFIX_2 "Hangup on %s complete\n", ast->name); ast_verbose(VERBOSE_PREFIX_2 "Hangup on %s complete\n", ast->name);
restart_monitor(); restart_monitor();
return 0; return 0;
} }
@ -1238,9 +1234,7 @@ static int vpb_answer(struct ast_channel *ast)
ast_verbose( VERBOSE_PREFIX_2 "Answered call from %s on %s\n", p->owner->callerid, ast->name); ast_verbose( VERBOSE_PREFIX_2 "Answered call from %s on %s\n", p->owner->callerid, ast->name);
ast->rings = 0; ast->rings = 0;
pthread_create(&p->readthread, NULL, do_chanreads, (void *)p); pthread_create(&p->readthread, NULL, do_chanreads, (void *)p);
return 0; return 0;
} }
@ -1257,7 +1251,6 @@ static struct ast_frame *vpb_read(struct ast_channel *ast)
static inline int ast2vpbformat(int ast_format) static inline int ast2vpbformat(int ast_format)
{ {
switch(ast_format) { switch(ast_format) {
case AST_FORMAT_ALAW: case AST_FORMAT_ALAW:
return VPB_ALAW; return VPB_ALAW;
@ -1266,7 +1259,6 @@ static inline int ast2vpbformat(int ast_format)
case AST_FORMAT_ULAW: case AST_FORMAT_ULAW:
return VPB_MULAW; return VPB_MULAW;
case AST_FORMAT_ADPCM: case AST_FORMAT_ADPCM:
return VPB_OKIADPCM; return VPB_OKIADPCM;
default: default:
return -1; return -1;
@ -1275,7 +1267,6 @@ static inline int ast2vpbformat(int ast_format)
static inline int astformatbits(int ast_format) static inline int astformatbits(int ast_format)
{ {
switch(ast_format) { switch(ast_format) {
case AST_FORMAT_ALAW: case AST_FORMAT_ALAW:
case AST_FORMAT_ULAW: case AST_FORMAT_ULAW:
@ -1309,18 +1300,18 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
int res = 0, fmt = 0; int res = 0, fmt = 0;
if (frame->frametype != AST_FRAME_VOICE) { if (frame->frametype != AST_FRAME_VOICE) {
if(option_verbose>3) ast_verbose( VERBOSE_PREFIX_4 "Don't know how to handle from type %d\n", frame->frametype); if(option_verbose>3)
ast_verbose( VERBOSE_PREFIX_4 "Don't know how to handle from type %d\n", frame->frametype);
return 0; return 0;
} else if (ast->_state != AST_STATE_UP) { } else if (ast->_state != AST_STATE_UP) {
if(option_verbose>3) ast_verbose( VERBOSE_PREFIX_4 "Writing frame type [%d,%d] on chan %s not up\n", if(option_verbose>3)
frame->frametype, frame->subclass, ast->name); ast_verbose( VERBOSE_PREFIX_4 "Writing frame type [%d,%d] on chan %s not up\n", frame->frametype, frame->subclass, ast->name);
return 0; return 0;
} }
fmt = ast2vpbformat(frame->subclass); fmt = ast2vpbformat(frame->subclass);
if (fmt < 0) { if (fmt < 0) {
ast_log(LOG_WARNING, "vpb_write Cannot handle frames of %d format!\n", ast_log(LOG_WARNING, "vpb_write Cannot handle frames of %d format!\n", frame->subclass);
frame->subclass);
return -1; return -1;
} }
@ -1350,7 +1341,6 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
} }
ast_mutex_unlock(&p->play_lock); ast_mutex_unlock(&p->play_lock);
return 0; return 0;
} }
@ -1378,17 +1368,16 @@ static void *do_chanreads(void *pvt)
while (!p->stopreads && p->owner) { while (!p->stopreads && p->owner) {
ast_mutex_lock(&p->lock); { ast_mutex_lock(&p->lock); {
if (p->bridge) if (p->bridge) {
if (p->bridge->c0 == p->owner && if (p->bridge->c0 == p->owner && (p->bridge->flags & AST_BRIDGE_REC_CHANNEL_0))
(p->bridge->flags & AST_BRIDGE_REC_CHANNEL_0))
bridgerec = 1; bridgerec = 1;
else if (p->bridge->c1 == p->owner && else if (p->bridge->c1 == p->owner && (p->bridge->flags & AST_BRIDGE_REC_CHANNEL_1))
(p->bridge->flags & AST_BRIDGE_REC_CHANNEL_1))
bridgerec = 1; bridgerec = 1;
else else
bridgerec = 0; bridgerec = 0;
else } else {
bridgerec = 1; bridgerec = 1;
}
} ast_mutex_unlock(&p->lock); } ast_mutex_unlock(&p->lock);
if ( (p->owner->_state != AST_STATE_UP) || !bridgerec) { if ( (p->owner->_state != AST_STATE_UP) || !bridgerec) {
@ -1419,14 +1408,16 @@ static void *do_chanreads(void *pvt)
if( p->play_dtmf[0] ) { if( p->play_dtmf[0] ) {
// Try to ignore DTMF event we get after playing digit // Try to ignore DTMF event we get after playing digit
// This DTMF is played by asterisk and leads to an annoying trailing beep on CISCO phones // This DTMF is played by asterisk and leads to an annoying trailing beep on CISCO phones
if( !ignore_dtmf) vpb_set_event_mask(p->handle, VPB_EVENTS_NODTMF ); if( !ignore_dtmf)
vpb_set_event_mask(p->handle, VPB_EVENTS_NODTMF );
vpb_dial_sync(p->handle,p->play_dtmf); vpb_dial_sync(p->handle,p->play_dtmf);
if(option_verbose>1) if(option_verbose>1)
ast_verbose( VERBOSE_PREFIX_2 "Played on %s DTMF %s\n",p->dev,p->play_dtmf); ast_verbose( VERBOSE_PREFIX_2 "Played on %s DTMF %s\n",p->dev,p->play_dtmf);
p->play_dtmf[0] = '\0'; p->play_dtmf[0] = '\0';
ast_mutex_unlock(&p->play_dtmf_lock); ast_mutex_unlock(&p->play_dtmf_lock);
vpb_sleep(700); // Long enough to miss echo and DTMF event vpb_sleep(700); // Long enough to miss echo and DTMF event
if( !ignore_dtmf) vpb_set_event_mask(p->handle, VPB_EVENTS_ALL ); if( !ignore_dtmf)
vpb_set_event_mask(p->handle, VPB_EVENTS_ALL );
continue; continue;
} }
ast_mutex_unlock(&p->play_dtmf_lock); ast_mutex_unlock(&p->play_dtmf_lock);
@ -1454,7 +1445,6 @@ static void *do_chanreads(void *pvt)
/* Read only if up and not bridged, or a bridge for which we can read. */ /* Read only if up and not bridged, or a bridge for which we can read. */
if( (res = vpb_record_buf_sync(p->handle, readbuf, readlen) ) == VPB_OK ) { if( (res = vpb_record_buf_sync(p->handle, readbuf, readlen) ) == VPB_OK ) {
// Apply extra gain ! // Apply extra gain !
if( p->rxswgain > MAX_VPB_GAIN ) if( p->rxswgain > MAX_VPB_GAIN )
gain_vector(p->rxswgain - MAX_VPB_GAIN , (short*)readbuf, readlen/sizeof(short)); gain_vector(p->rxswgain - MAX_VPB_GAIN , (short*)readbuf, readlen/sizeof(short));
@ -1478,18 +1468,15 @@ static void *do_chanreads(void *pvt)
vpb_record_buf_finish(p->handle); vpb_record_buf_finish(p->handle);
vpb_record_buf_start(p->handle, fmt); vpb_record_buf_start(p->handle, fmt);
} }
} }
/* When stopreads seen, go away! */ /* When stopreads seen, go away! */
vpb_record_buf_finish(p->handle); vpb_record_buf_finish(p->handle);
ast_mutex_unlock(&p->record_lock); ast_mutex_unlock(&p->record_lock);
if (option_verbose > 1) if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Ending record mode on %s (%d/%s)\n", ast_verbose(VERBOSE_PREFIX_2 "Ending record mode on %s (%d/%s)\n",
p->dev, p->stopreads, p->owner? "yes" : "no"); p->dev, p->stopreads, p->owner? "yes" : "no");
return NULL; return NULL;
} }
@ -1550,13 +1537,15 @@ static struct ast_channel *vpb_new(struct vpb_pvt *i, int state, char *context)
usecnt++; usecnt++;
ast_mutex_unlock(&usecnt_lock); ast_mutex_unlock(&usecnt_lock);
ast_update_use_count(); ast_update_use_count();
if (state != AST_STATE_DOWN) if (state != AST_STATE_DOWN) {
if (ast_pbx_start(tmp)) { if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
ast_hangup(tmp); ast_hangup(tmp);
} }
} else }
} else {
ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
}
return tmp; return tmp;
} }
@ -1567,6 +1556,7 @@ static struct ast_channel *vpb_request(char *type, int format, void *data)
struct ast_channel *tmp = NULL; struct ast_channel *tmp = NULL;
char *name = strdup(data ? (char *)data : ""); char *name = strdup(data ? (char *)data : "");
char *s, *sepstr; char *s, *sepstr;
int group=-1;
oldformat = format; oldformat = format;
format &= prefformat; format &= prefformat;
@ -1579,15 +1569,28 @@ static struct ast_channel *vpb_request(char *type, int format, void *data)
s = strsep(&sepstr, "/"); /* Handle / issues */ s = strsep(&sepstr, "/"); /* Handle / issues */
if (!s) if (!s)
s = ""; s = "";
/* Check if we are looking for a group */
if (toupper(name[0]) == 'G' || toupper(name[0])=='R') {
group=atoi(name+1);
}
/* Search for an unowned channel */ /* Search for an unowned channel */
ast_mutex_lock(&iflock); { ast_mutex_lock(&iflock); {
p = iflist; p = iflist;
while(p) { while(p) {
if (strncmp(s, p->dev + 4, sizeof p->dev) == 0) if (group == -1){
if (strncmp(s, p->dev + 4, sizeof p->dev) == 0) {
if (!p->owner) { if (!p->owner) {
tmp = vpb_new(p, AST_STATE_DOWN, p->context); tmp = vpb_new(p, AST_STATE_DOWN, p->context);
break; break;
} }
}
}
else {
if ((p->group == group) && (!p->owner)) {
tmp = vpb_new(p, AST_STATE_DOWN, p->context);
break;
}
}
p = p->next; p = p->next;
} }
} ast_mutex_unlock(&iflock); } ast_mutex_unlock(&iflock);
@ -1610,8 +1613,7 @@ static float parse_gain_value(char *gain_type, char *value)
/* try to scan number */ /* try to scan number */
if (sscanf(value, "%f", &gain) != 1) if (sscanf(value, "%f", &gain) != 1)
{ {
ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n", ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n", value, gain_type, config);
value, gain_type, config);
return DEFAULT_GAIN; return DEFAULT_GAIN;
} }
@ -1660,7 +1662,7 @@ int load_module()
group = atoi(v->value); group = atoi(v->value);
else if (strcasecmp(v->name, "channel") == 0) { else if (strcasecmp(v->name, "channel") == 0) {
int channel = atoi(v->value); int channel = atoi(v->value);
tmp = mkif(board, channel, mode, txgain, rxgain, txswgain, rxswgain, bal1, bal2, bal3, callerid, echo_cancel); tmp = mkif(board, channel, mode, txgain, rxgain, txswgain, rxswgain, bal1, bal2, bal3, callerid, echo_cancel,group);
if (tmp) { if (tmp) {
if(first_channel) { if(first_channel) {
mkbrd( tmp->vpb_model, echo_cancel ); mkbrd( tmp->vpb_model, echo_cancel );
@ -1673,12 +1675,11 @@ int load_module()
"Unable to register channel '%s'\n", v->value); "Unable to register channel '%s'\n", v->value);
error = -1; error = -1;
goto done; goto done;
} }
callerid = NULL; callerid = NULL;
} else if (strcasecmp(v->name, "language") == 0) } else if (strcasecmp(v->name, "language") == 0) {
strncpy(language, v->value, sizeof(language)-1); strncpy(language, v->value, sizeof(language)-1);
else if (strcasecmp(v->name, "callerid") == 0) { } else if (strcasecmp(v->name, "callerid") == 0) {
callerid = strdup(v->value); callerid = strdup(v->value);
} else if (strcasecmp(v->name, "mode") == 0) { } else if (strcasecmp(v->name, "mode") == 0) {
if (strncasecmp(v->value, "di", 2) == 0) if (strncasecmp(v->value, "di", 2) == 0)
@ -1689,9 +1690,9 @@ int load_module()
mode = MODE_FXO; mode = MODE_FXO;
else else
ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value); ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
} else if (!strcasecmp(v->name, "context")) } else if (!strcasecmp(v->name, "context")) {
strncpy(context, v->value, sizeof(context)-1); strncpy(context, v->value, sizeof(context)-1);
else if (!strcasecmp(v->name, "echocancel")) { } else if (!strcasecmp(v->name, "echocancel")) {
if (!strcasecmp(v->value, "off")) if (!strcasecmp(v->value, "off"))
echo_cancel = 0; echo_cancel = 0;
} else if (strcasecmp(v->name, "txgain") == 0) { } else if (strcasecmp(v->name, "txgain") == 0) {
@ -1720,8 +1721,9 @@ int load_module()
ast_log(LOG_WARNING, "Bad bal3 value: %d\n", bal3); ast_log(LOG_WARNING, "Bad bal3 value: %d\n", bal3);
bal3 = -1; bal3 = -1;
} }
} else if (strcasecmp(v->name, "grunttimeout") == 0) } else if (strcasecmp(v->name, "grunttimeout") == 0) {
gruntdetect_timeout = 1000*atoi(v->value); gruntdetect_timeout = 1000*atoi(v->value);
}
v = v->next; v = v->next;
} }
@ -1733,11 +1735,8 @@ int load_module()
ast_destroy(cfg); ast_destroy(cfg);
if (!error && if (!error && ast_channel_register(type, tdesc, prefformat, vpb_request) != 0) {
ast_channel_register(type, tdesc,
prefformat, vpb_request) != 0) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
error = -1; error = -1;
} }

Loading…
Cancel
Save