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: 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
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) {
0087