00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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: 7221 $")
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
00101 static char context[AST_MAX_EXTENSION] = "default";
00102
00103
00104 static char language[MAX_LANGUAGE] = "";
00105 static int usecnt =0;
00106
00107 static int gruntdetect_timeout = 3600000;
00108
00109 static const int prefformat = AST_FORMAT_SLINEAR;
00110
00111 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
00112
00113
00114 AST_MUTEX_DEFINE_STATIC(iflock);
00115
00116
00117
00118 AST_MUTEX_DEFINE_STATIC(monlock);
00119
00120
00121
00122 static pthread_t monitor_thread;
00123
00124 static int mthreadactive = -1;
00125
00126
00127 static int restart_monitor(void);
00128
00129
00130
00131
00132 #define MODE_DIALTONE 1
00133 #define MODE_IMMEDIATE 2
00134 #define MODE_FXO 3
00135
00136
00137
00138 #define TONES_AU
00139
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
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
00157 static int UsePolarityCID=0;
00158
00159
00160 static int UseLoopDrop=1;
00161
00162
00163 static int UseNativeBridge=1;
00164
00165
00166 static int use_ast_ind=0;
00167
00168
00169 static int use_ast_dtmfdet=0;
00170
00171 static int relaxdtmf=0;
00172
00173
00174 static int use_ast_dtmf=0;
00175
00176
00177 static int break_for_dtmf=1;
00178
00179
00180 static int ec_supp_threshold=-1;
00181
00182
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
00205
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
00213 #define VPB_RINGWAIT 4000
00214 #define VPB_CONNECTED_WAIT 4000
00215 #define TIMER_PERIOD_NOANSWER 120000
00216
00217 #define MAX_BRIDGES_V4PCI 2
00218 #define MAX_BRIDGES_V12PCI 128
00219
00220
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;
00259 struct ast_channel *owner;
00260
00261 int golock;
00262
00263 int mode;
00264 int handle;
00265
00266 int state;
00267
00268 int group;
00269 ast_group_t callgroup;
00270 ast_group_t pickupgroup;
00271
00272
00273 char dev[256];
00274 vpb_model_t vpb_model;
00275
00276 struct ast_frame f, fr;
00277 char buf[VPB_MAX_BUF];
00278
00279 int dialtone;
00280 float txgain, rxgain;
00281 float txswgain, rxswgain;
00282
00283 int wantdtmf;
00284 char context[AST_MAX_EXTENSION];
00285
00286 char ext[AST_MAX_EXTENSION];
00287 char language[MAX_LANGUAGE];
00288 char callerid[AST_MAX_EXTENSION];
00289 int callerid_type;
00290 char cid_num[AST_MAX_EXTENSION];
00291 char cid_name[AST_MAX_EXTENSION];
00292
00293 int dtmf_caller_pos;
00294
00295 int lastoutput;
00296 int lastinput;
00297 int last_ignore_dtmf;
00298
00299 void *busy_timer;
00300 int busy_timer_id;
00301
00302 void *ringback_timer;
00303 int ringback_timer_id;
00304
00305 void *ring_timer;
00306 int ring_timer_id;
00307
00308 void *dtmfidd_timer;
00309 int dtmfidd_timer_id;
00310
00311 struct ast_dsp *vad;
00312
00313 struct timeval lastgrunt;
00314
00315 ast_mutex_t lock;
00316 vpb_bridge_t *bridge;
00317
00318 int stopreads;
00319 int read_state;
00320 int chuck_count;
00321 pthread_t readthread;
00322
00323 ast_mutex_t record_lock;
00324 ast_mutex_t play_lock;
00325 int play_buf_time;
00326 struct timeval lastplay;
00327
00328 ast_mutex_t play_dtmf_lock;
00329 char play_dtmf[16];
00330
00331 int faxhandled;
00332
00333 struct vpb_pvt *next;
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
00406
00407
00408
00409 #define BAD_V4PCI_BRIDGE
00410
00411
00412
00413
00414
00415
00416
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
00440
00441
00442
00443
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
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 );
00522 if (res == VPB_OK) {
00523
00524 while( !bridges[i].endbridge ) {
00525
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
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
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
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
00570
00571
00572
00573
00574
00575
00576
00577 }
00578 ast_frfree(f);
00579 }
00580
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 );
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
00603
00604
00605 return (res==VPB_OK) ? AST_BRIDGE_COMPLETE : AST_BRIDGE_FAILED;
00606 }
00607
00608
00609
00610
00611
00612
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];
00619 struct timeval cid_record_time;
00620 int rc;
00621 struct ast_channel *owner = p->owner;
00622
00623
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
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
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
00672 if ((rc=vpb_cid_decode2(cli_struct, buf, CID_MSECS*8)) == VPB_OK ) {
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 if (cli_struct->ra_cldn[0]=='\0'){
00683
00684
00685
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
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
00748
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
00781
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
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
00825 }
00826 vpb_sleep(10);
00827 }
00828 }
00829
00830
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};
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;
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
00879 if (p->owner->_state != AST_STATE_UP) {
00880
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;
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
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
00938
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)){
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
00996
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
01025
01026
01027
01028 {
01029 if (p->bridge) {
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
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
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
01081
01082
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
01098
01099
01100 return 0;
01101 }
01102
01103 static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
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
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);
01130 }
01131
01132 }
01133 break;
01134 case VPB_RING:
01135 if (p->mode == MODE_FXO) {
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);
01142 }
01143 get_callerid_ast(p);
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;
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;
01178 }
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
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:
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
01212 if (p->owner){
01213 if (p->owner->_state != AST_STATE_UP) {
01214
01215 vpb_timer_stop(p->ring_timer);
01216 }
01217 } else {
01218
01219 vpb_timer_stop(p->ring_timer);
01220 }
01221 }
01222 break;
01223
01224 case VPB_DTMF:
01225 if (p->state == VPB_STATE_ONHOOK){
01226
01227 if ( p->mode == MODE_FXO ) {
01228 if ( e->data == DTMF_CID_START ) {
01229 p->dtmf_caller_pos = 0;
01230 memset(p->callerid,0,AST_MAX_EXTENSION);
01231 }
01232 else if ( e->data == DTMF_CID_STOP ) {
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
01239
01240
01241
01242
01243
01244
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
01274 if (ast_pickup_call(c)) {
01275
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
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
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 }
01319
01320 static void *do_monitor(void *unused)
01321 {
01322
01323
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
01339
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
01346
01347
01348
01349
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
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
01409 if ((p->owner)&&(!p->golock)){
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425 }
01426
01427 if (p->owner) {
01428 monitor_handle_owned(p, &e);
01429 } else {
01430 monitor_handle_notowned(p, &e);
01431 }
01432
01433
01434
01435
01436
01437
01438 }
01439
01440 return NULL;
01441 }
01442
01443 static int restart_monitor(void)
01444 {
01445 int error = 0;
01446
01447
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
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
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;
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 }
01492
01493
01494 static void mkbrd(vpb_model_t model, int echo_cancel)
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
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
01533 }
01534 }
01535 }
01536
01537 static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float txgain, float rxgain,
01538 float txswgain, float rxswgain, int bal1, int bal2, int bal3,
01539 char * callerid, int echo_cancel, int group, ast_group_t callgroup, ast_group_t pickupgroup )
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
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
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
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
01682
01683
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
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 }
01711
01712 static int vpb_indicate(struct ast_channel *ast, int condition)
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
01728
01729
01730
01731
01732
01733
01734
01735
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:
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
01781
01782 return res;
01783 }
01784
01785 static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
01786 {
01787 struct vpb_pvt *p = (struct vpb_pvt *)newchan->tech_pvt;
01788 int res = 0;
01789
01790
01791
01792
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
01817
01818 return 0;
01819 }
01820
01821 static int vpb_digit(struct ast_channel *ast, char digit)
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
01835
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
01853
01854 return 0;
01855 }
01856
01857
01858 static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
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
01868
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
01891
01892 return -1;
01893 }
01894 if (p->mode != MODE_FXO)
01895 res = vpb_ring_station_async(p->handle, VPB_RING_STATION_ON,0);
01896 else {
01897 VPB_CALL call;
01898
01899
01900 if( timeout == 0 )
01901 timeout = TIMER_PERIOD_NOANSWER;
01902 else
01903 timeout = timeout * 1000;
01904
01905
01906 call.dialtones = 1;
01907 call.dialtone_timeout = VPB_DIALTONE_WAIT;
01908 call.ringback_timeout = VPB_RINGWAIT;
01909 call.inter_ringback_timeout = VPB_CONNECTED_WAIT;
01910 call.answer_timeout = timeout;
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
01968
01969 return res;
01970 }
01971
01972 static int vpb_hangup(struct ast_channel *ast)
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
01981
01982
01983
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
01993
01994
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
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
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
02029
02030
02031
02032 ast_mutex_lock(&p->lock);
02033
02034 if (p->mode != MODE_FXO) {
02035
02036 vpb_ring_station_async(p->handle, VPB_RING_STATION_OFF,0);
02037 if(p->state!=VPB_STATE_ONHOOK){
02038
02039
02040
02041
02042
02043
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);
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
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
02093
02094 res = ast_mutex_unlock(&p->lock);
02095
02096
02097
02098
02099 return 0;
02100 }
02101
02102 static int vpb_answer(struct ast_channel *ast)
02103 {
02104 struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
02105 int res = 0;
02106
02107
02108
02109
02110
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
02128
02129
02130
02131
02132
02133
02134
02135
02136 }
02137 ast_setstate(ast, AST_STATE_UP);
02138
02139 if(option_verbose>1)
02140
02141
02142
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
02150
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
02161
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
02172
02173 return 0;
02174 }
02175
02176 static struct ast_frame *vpb_read(struct ast_channel *ast)
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 }
02187
02188 static inline int ast2vpbformat(int ast_format)
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 }
02203
02204 static inline char * ast2vpbformatname(int ast_format)
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 }
02219
02220 static inline int astformatbits(int ast_format)
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 }
02234
02235 int a_gain_vector(float g, short *v, int n)
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 }
02249
02250
02251 static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
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
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
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
02273 return 0;
02274 }
02275
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
02289 }
02290 p->lastplay = ast_tvnow();
02291
02292
02293
02294
02295 ast_mutex_lock(&p->play_lock);
02296
02297
02298
02299
02300
02301
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
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
02327
02328
02329 if ((p->read_state == 1)&&(p->play_buf_time<5)){
02330 play_buf_time_start = ast_tvnow();
02331
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
02347 if(option_verbose>5)
02348 ast_verbose("%s: vpb_write: Done Writing to channel\n", p->dev);
02349 return 0;
02350 }
02351
02352
02353 static void *do_chanreads(void *pvt)
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
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
02420
02421
02422
02423
02424 ignore_dtmf = 0;
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
02438
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
02446
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);
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
02468 if (p->owner){
02469 afmt = p->owner->rawreadformat;
02470
02471 }
02472 else {
02473 afmt = AST_FORMAT_SLINEAR;
02474
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
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
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
02525 fr->frametype = AST_FRAME_NULL;
02526 fr->subclass = 0;
02527 }
02528 else if (fr->subclass == 'u'){
02529
02530 fr->frametype = AST_FRAME_NULL;
02531 fr->subclass = 0;
02532 }
02533 else if (fr->subclass == 'f'){
02534 }
02535 }
02536
02537
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
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
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
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 }
02608
02609 static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
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
02638
02639
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();
02673 me->lastplay = ast_tvnow();
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 }
02693
02694 static struct ast_channel *vpb_request(const char *type, int format, void *data, int *cause)
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, "/");
02712 if (!s)
02713 s = "";
02714
02715 if (toupper(name[0]) == 'G' || toupper(name[0])=='R') {
02716 group=atoi(name+1);
02717 }
02718
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 }
02750
02751 static float parse_gain_value(char *gain_type, char *value)
02752 {
02753 float gain;
02754
02755
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
02764
02765
02766
02767 return gain;
02768 }
02769
02770 int load_module()
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;
02785 int bal1 = -1;
02786 int bal2 = -1;
02787 int bal3 = -1;
02788 char * callerid = NULL;
02789
02790 cfg = ast_config_load(config);
02791
02792
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
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();
02962
02963 return error;
02964 }
02965
02966
02967 int unload_module()
02968 {
02969 struct vpb_pvt *p;
02970
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
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
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 }
03031
03032 int usecount()
03033 {
03034 return usecnt;
03035 }
03036
03037 char *description()
03038 {
03039 return (char *) desc;
03040 }
03041
03042 char *key()
03043 {
03044 return ASTERISK_GPL_KEY;
03045 }
03046
03047
03048 #if defined(__cplusplus) || defined(c_plusplus)
03049 }
03050 #endif
03051