Sat Nov 1 06:30:33 2008

Asterisk developer's documentation


chan_vpb.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2003, Paul Bagyenda
00005  * Paul Bagyenda <bagyenda@dsmagic.com>
00006  * Copyright (C) 2004 - 2005, Ben Kramer
00007  * Ben Kramer <ben@voicetronix.com.au>
00008  *
00009  * Daniel Bichara <daniel@bichara.com.br> - Brazilian CallerID detection (c)2004 
00010  *
00011  * Welber Silveira - welberms@magiclink.com.br - (c)2004
00012  * Copying CLID string to propper structure after detection
00013  *
00014  * See http://www.asterisk.org for more information about
00015  * the Asterisk project. Please do not directly contact
00016  * any of the maintainers of this project for assistance;
00017  * the project provides a web site, mailing lists and IRC
00018  * channels for your use.
00019  *
00020  * This program is free software, distributed under the terms of
00021  * the GNU General Public License Version 2. See the LICENSE file
00022  * at the top of the source tree.
00023  */
00024 
00025 /*! \file
00026  *
00027  * \brief VoiceTronix Interface driver
00028  * 
00029  * \ingroup channel_drivers
00030  */
00031 
00032 
00033 extern "C" {
00034 
00035 #include <stdio.h>
00036 #include <string.h>
00037 
00038 #include "asterisk.h"
00039 
00040 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 38904 $")
00041 
00042 #include "asterisk/lock.h"
00043 #include "asterisk/utils.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/config.h"
00046 #include "asterisk/logger.h"
00047 #include "asterisk/module.h"
00048 #include "asterisk/pbx.h"
00049 #include "asterisk/options.h"
00050 #include "asterisk/callerid.h"
00051 #include "asterisk/dsp.h"
00052 #include "asterisk/features.h"
00053 }
00054 
00055 #include <sys/socket.h>
00056 #include <sys/time.h>
00057 #include <errno.h>
00058 #include <unistd.h>
00059 #include <stdlib.h>
00060 #include <arpa/inet.h>
00061 #include <fcntl.h>
00062 #include <sys/ioctl.h>
00063 #include <ctype.h>
00064 
00065 #include <vpbapi.h>
00066 #include <assert.h>
00067 
00068 #ifdef pthread_create
00069 #undef pthread_create
00070 #endif
00071 
00072 #define DEFAULT_GAIN 0
00073 #define DEFAULT_ECHO_CANCEL 1
00074   
00075 #define VPB_SAMPLES 160 
00076 #define VPB_MAX_BUF VPB_SAMPLES*4 + AST_FRIENDLY_OFFSET
00077 
00078 #define VPB_NULL_EVENT 200
00079 
00080 #define VPB_WAIT_TIMEOUT 4000
00081 
00082 #define MAX_VPB_GAIN 12.0
00083 #define MIN_VPB_GAIN -12.0
00084 
00085 #define DTMF_CALLERID  
00086 #define DTMF_CID_START 'D'
00087 #define DTMF_CID_STOP 'C'
00088 
00089 /**/
00090 #if defined(__cplusplus) || defined(c_plusplus)
00091  extern "C" {
00092 #endif
00093 /**/
00094 
00095 static const char desc[] = "VoiceTronix V6PCI/V12PCI/V4PCI  API Support";
00096 static const char type[] = "vpb";
00097 static const char tdesc[] = "Standard VoiceTronix API Driver";
00098 static const char config[] = "vpb.conf";
00099 
00100 /* Default context for dialtone mode */
00101 static char context[AST_MAX_EXTENSION] = "default";
00102 
00103 /* Default language */
00104 static char language[MAX_LANGUAGE] = "";
00105 static int usecnt =0;
00106 
00107 static int gruntdetect_timeout = 3600000; /* Grunt detect timeout is 1hr. */
00108 
00109 static const int prefformat = AST_FORMAT_SLINEAR;
00110 
00111 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
00112 
00113 /* Protect the interface list (of vpb_pvt's) */
00114 AST_MUTEX_DEFINE_STATIC(iflock);
00115 
00116 /* Protect the monitoring thread, so only one process can kill or start it, and not
00117    when it's doing something critical. */
00118 AST_MUTEX_DEFINE_STATIC(monlock);
00119 
00120 /* This is the thread for the monitor which checks for input on the channels
00121    which are not currently in use.  */
00122 static pthread_t monitor_thread;
00123 
00124 static int mthreadactive = -1; /* Flag for monitoring monitorthread.*/
00125 
00126 
00127 static int restart_monitor(void);
00128 
00129 /* The private structures of the VPB channels are 
00130    linked for selecting outgoing channels */
00131    
00132 #define MODE_DIALTONE   1
00133 #define MODE_IMMEDIATE  2
00134 #define MODE_FXO  3
00135 
00136 /* Pick a country or add your own! */
00137 /* These are the tones that are played to the user */
00138 #define TONES_AU
00139 /* #define TONES_USA */
00140 
00141 #ifdef TONES_AU
00142 static VPB_TONE Dialtone     = {440,      440,  440,  -10,     -10,  -10,  5000, 0   };
00143 static VPB_TONE Busytone     = {470,      0,    0,    -10,     -100,    -100,   5000,  0 };
00144 static VPB_TONE Ringbacktone = {400,      50,      440,  -10,     -10,  -10,     1400,    800 };
00145 #endif
00146 #ifdef TONES_USA
00147 static VPB_TONE Dialtone     = {350, 440,   0, -16,   -16, -100, 10000,    0};
00148 static VPB_TONE Busytone     = {480, 620,   0, -10,   -10, -100,   500,  500};
00149 static VPB_TONE Ringbacktone = {440, 480,   0, -20,   -20, -100,  2000, 4000};
00150 #endif
00151 
00152 /* grunt tone defn's */
00153 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 } } };
00154 static VPB_DETECT toned_ungrunt = { 2, VPB_GRUNT, 1, 2000, 1, 0, 0, -40, 0, 0, 30, 40, { { 0, 0, 0, 0 } } };
00155 
00156 /* Use loop polarity detection for CID */
00157 static int UsePolarityCID=0;
00158 
00159 /* Use loop drop detection */
00160 static int UseLoopDrop=1;
00161 
00162 /* To use or not to use Native bridging */
00163 static int UseNativeBridge=1;
00164 
00165 /* Use Asterisk Indication or VPB */
00166 static int use_ast_ind=0;
00167 
00168 /* Use Asterisk DTMF detection or VPB */
00169 static int use_ast_dtmfdet=0;
00170 
00171 static int relaxdtmf=0;
00172 
00173 /* Use Asterisk DTMF play back or VPB */
00174 static int use_ast_dtmf=0;
00175 
00176 /* Break for DTMF on native bridge ? */
00177 static int break_for_dtmf=1;
00178 
00179 /* Set EC suppression threshold */
00180 static int ec_supp_threshold=-1;
00181 
00182 /* Inter Digit Delay for collecting DTMF's */
00183 static int dtmf_idd = 3000;
00184 
00185 #define TIMER_PERIOD_RINGBACK 2000
00186 #define TIMER_PERIOD_BUSY 700
00187 #define TIMER_PERIOD_RING 4000
00188 static int timer_period_ring = TIMER_PERIOD_RING;
00189      
00190 #define VPB_EVENTS_ALL (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \
00191          |VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
00192          |VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH)
00193 #define VPB_EVENTS_NODROP (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \
00194          |VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
00195          |VPB_MRING_OFF|VPB_MSTATION_FLASH)
00196 #define VPB_EVENTS_NODTMF (VPB_MRING|VPB_MDIGIT|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \
00197          |VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
00198          |VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH)
00199 #define VPB_EVENTS_STAT (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \
00200          |VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
00201          |VPB_MRING_OFF|VPB_MSTATION_FLASH)
00202 
00203 
00204 /* Dialing parameters for Australia */
00205 /* #define DIAL_WITH_CALL_PROGRESS */
00206 VPB_TONE_MAP DialToneMap[] = {   { VPB_BUSY_AUST, VPB_CALL_DISCONNECT, 0 },
00207             { VPB_DIAL, VPB_CALL_DIALTONE, 0 },
00208             { VPB_RINGBACK_308, VPB_CALL_RINGBACK, 0 },
00209             { VPB_BUSY_AUST, VPB_CALL_BUSY, 0 },
00210             { VPB_GRUNT, VPB_CALL_GRUNT, 0 },
00211             { 0, 0, 1 } };
00212 #define VPB_DIALTONE_WAIT 2000 /* Wait up to 2s for a dialtone */
00213 #define VPB_RINGWAIT 4000 /* Wait up to 4s for ring tone after dialing */
00214 #define VPB_CONNECTED_WAIT 4000 /* If no ring tone detected for 4s then consider call connected */
00215 #define TIMER_PERIOD_NOANSWER 120000 /* Let it ring for 120s before deciding theres noone there */
00216 
00217 #define MAX_BRIDGES_V4PCI 2
00218 #define MAX_BRIDGES_V12PCI 128
00219 
00220 /* port states */
00221 #define VPB_STATE_ONHOOK   0
00222 #define VPB_STATE_OFFHOOK  1
00223 #define VPB_STATE_DIALLING 2
00224 #define VPB_STATE_JOINED   3
00225 #define VPB_STATE_GETDTMF  4
00226 #define VPB_STATE_PLAYDIAL 5
00227 #define VPB_STATE_PLAYBUSY 6
00228 #define VPB_STATE_PLAYRING 7
00229 
00230 #define VPB_GOT_RXHWG      1
00231 #define VPB_GOT_TXHWG      2
00232 #define VPB_GOT_RXSWG      4
00233 #define VPB_GOT_TXSWG      8
00234 
00235 typedef struct  {
00236    int inuse;
00237    struct ast_channel *c0, *c1, **rc;
00238    struct ast_frame **fo;
00239    int flags;
00240    ast_mutex_t lock;
00241    ast_cond_t cond;
00242    int endbridge;
00243 } vpb_bridge_t;
00244 
00245 static vpb_bridge_t * bridges;
00246 static int max_bridges = MAX_BRIDGES_V4PCI;
00247 
00248 AST_MUTEX_DEFINE_STATIC(bridge_lock);
00249 
00250 typedef enum {
00251    vpb_model_unknown = 0, 
00252    vpb_model_v4pci,
00253    vpb_model_v12pci
00254 } vpb_model_t;
00255 
00256 static struct vpb_pvt {
00257 
00258    ast_mutex_t owner_lock;       /* Protect blocks that expect ownership to remain the same */
00259    struct ast_channel *owner;    /* Channel who owns us, possibly NULL */
00260 
00261    int golock;          /* Got owner lock ? */
00262 
00263    int mode;            /* fxo/imediate/dialtone*/
00264    int handle;          /* Handle for vpb interface */
00265 
00266    int state;           /* used to keep port state (internal to driver) */
00267 
00268    int group;           /* Which group this port belongs to */
00269    ast_group_t callgroup;                  /* Call group */
00270    ast_group_t pickupgroup;                /* Pickup group */
00271 
00272 
00273    char dev[256];          /* Device name, eg vpb/1-1 */
00274    vpb_model_t vpb_model;        /* card model */
00275 
00276    struct ast_frame f, fr;       /* Asterisk frame interface */
00277    char buf[VPB_MAX_BUF];        /* Static buffer for reading frames */
00278 
00279    int dialtone;           /* NOT USED */
00280    float txgain, rxgain;         /* Hardware gain control */
00281    float txswgain, rxswgain;     /* Software gain control */
00282 
00283    int wantdtmf;           /* Waiting for DTMF. */
00284    char context[AST_MAX_EXTENSION]; /* The context for this channel */
00285 
00286    char ext[AST_MAX_EXTENSION];     /* DTMF buffer for the ext[ens] */
00287    char language[MAX_LANGUAGE];     /* language being used */
00288    char callerid[AST_MAX_EXTENSION];   /* CallerId used for directly connected phone */
00289    int  callerid_type;        /* Caller ID type: 0=>none 1=>vpb 2=>AstV23 3=>AstBell */
00290    char cid_num[AST_MAX_EXTENSION];
00291    char cid_name[AST_MAX_EXTENSION];
00292 
00293    int dtmf_caller_pos;       /* DTMF CallerID detection (Brazil)*/
00294 
00295    int lastoutput;            /* Holds the last Audio format output'ed */
00296    int lastinput;          /* Holds the last Audio format input'ed */
00297    int last_ignore_dtmf;
00298 
00299    void *busy_timer;       /* Void pointer for busy vpb_timer */
00300    int busy_timer_id;         /* unique timer ID for busy timer */
00301 
00302    void *ringback_timer;         /* Void pointer for ringback vpb_timer */
00303    int ringback_timer_id;        /* unique timer ID for ringback timer */
00304 
00305    void *ring_timer;       /* Void pointer for ring vpb_timer */
00306    int ring_timer_id;         /* unique timer ID for ring timer */
00307 
00308    void *dtmfidd_timer;       /* Void pointer for DTMF IDD vpb_timer */
00309    int dtmfidd_timer_id;         /* unique timer ID for DTMF IDD timer */
00310 
00311    struct ast_dsp *vad;       /* AST  Voice Activation Detection dsp */
00312 
00313    struct timeval lastgrunt;        /* time stamp of last grunt event */
00314 
00315    ast_mutex_t lock;       /* This one just protects bridge ptr below */
00316    vpb_bridge_t *bridge;
00317 
00318    int stopreads;             /* Stop reading...*/
00319    int read_state;            /* Read state */
00320    int chuck_count;        /* a count of packets weve chucked away!*/
00321    pthread_t readthread;         /* For monitoring read channel. One per owned channel. */
00322 
00323    ast_mutex_t record_lock;      /* This one prevents reentering a record_buf block */
00324    ast_mutex_t play_lock;        /* This one prevents reentering a play_buf block */
00325    int  play_buf_time;        /* How long the last play_buf took */
00326    struct timeval lastplay;      /* Last play time */
00327 
00328    ast_mutex_t play_dtmf_lock;
00329    char play_dtmf[16];
00330 
00331    int faxhandled;            /* has a fax tone been handled ? */
00332 
00333    struct vpb_pvt *next;         /* Next channel in list */
00334 
00335 } *iflist = NULL;
00336 
00337 static struct ast_channel *vpb_new(struct vpb_pvt *i, int state, char *context);
00338 static void *do_chanreads(void *pvt);
00339 
00340 static struct ast_channel *vpb_request(const char *type, int format, void *data, int *cause);
00341 static int vpb_digit(struct ast_channel *ast, char digit);
00342 static int vpb_call(struct ast_channel *ast, char *dest, int timeout);
00343 static int vpb_hangup(struct ast_channel *ast);
00344 static int vpb_answer(struct ast_channel *ast);
00345 static struct ast_frame *vpb_read(struct ast_channel *ast);
00346 static int vpb_write(struct ast_channel *ast, struct ast_frame *frame);
00347 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);
00348 static int vpb_indicate(struct ast_channel *ast, int condition);
00349 static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00350 
00351 static struct ast_channel_tech vpb_tech = {
00352    type: type,
00353    description: tdesc,
00354    capabilities: AST_FORMAT_SLINEAR,
00355    properties: NULL,
00356    requester: vpb_request,
00357    devicestate: NULL,
00358    send_digit: vpb_digit,
00359    call: vpb_call,
00360    hangup: vpb_hangup,
00361    answer: vpb_answer,
00362    read: vpb_read,
00363    write: vpb_write,
00364    send_text: NULL,
00365    send_image: NULL,
00366    send_html: NULL,
00367    exception: NULL,
00368    bridge: vpb_bridge,
00369    indicate: vpb_indicate,
00370    fixup: vpb_fixup,
00371    setoption: NULL,
00372    queryoption: NULL,
00373    transfer: NULL,
00374    write_video: NULL,
00375    bridged_channel: NULL
00376 };
00377 
00378 static struct ast_channel_tech vpb_tech_indicate = {
00379    type: type,
00380    description: tdesc,
00381    capabilities: AST_FORMAT_SLINEAR,
00382    properties: NULL,
00383    requester: vpb_request,
00384    devicestate: NULL,
00385    send_digit: vpb_digit,
00386    call: vpb_call,
00387    hangup: vpb_hangup,
00388    answer: vpb_answer,
00389    read: vpb_read,
00390    write: vpb_write,
00391    send_text: NULL,
00392    send_image: NULL,
00393    send_html: NULL,
00394    exception: NULL,
00395    bridge: vpb_bridge,
00396    indicate: NULL,
00397    fixup: vpb_fixup,
00398    setoption: NULL,
00399    queryoption: NULL,
00400    transfer: NULL,
00401    write_video: NULL,
00402    bridged_channel: NULL
00403 };
00404 
00405 /* Can't get vpb_bridge() working on v4pci without either a horrible 
00406 *  high pitched feedback noise or bad hiss noise depending on gain settings
00407 *  Get asterisk to do the bridging
00408 */
00409 #define BAD_V4PCI_BRIDGE
00410 
00411 /* This one enables a half duplex bridge which may be required to prevent high pitched
00412  * feedback when getting asterisk to do the bridging and when using certain gain settings.
00413  */
00414 /* #define HALF_DUPLEX_BRIDGE */
00415 
00416 /* This is the Native bridge code, which Asterisk will try before using its own bridging code */
00417 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)
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 }
00607 
00608 /* Caller ID can be located in different positions between the rings depending on your Telco
00609  * Australian (Telstra) callerid starts 700ms after 1st ring and finishes 1.5s after first ring
00610  * Use ANALYSE_CID to record rings and determine location of callerid
00611  */
00612 /* #define ANALYSE_CID */
00613 #define RING_SKIP 300
00614 #define CID_MSECS 2000
00615 
00616 static void get_callerid(struct vpb_pvt *p)
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 }
00711 
00712 static void get_callerid_ast(struct vpb_pvt *p)
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 }
00811 
00812 /* Terminate any tones we are presently playing */
00813 static void stoptone( int handle)
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 }
00829 
00830 /* Safe vpb_playtone_async */
00831 static int playtone( int handle, VPB_TONE *tone)
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 }
00840 
00841 static inline int monitor_handle_owned(struct vpb_pvt *p, VPB_EVENT *e)
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) {
0087