From 14650e5c4fab314f7f6cdaf73062f6a5b2c96c19 Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Tue, 10 Sep 2002 04:45:51 +0000 Subject: Version 0.2.0 from FTP git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@521 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_zap.c | 212 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 138 insertions(+), 74 deletions(-) (limited to 'channels') diff --git a/channels/chan_zap.c b/channels/chan_zap.c index f78c882ce..2a3dfcc55 100755 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -134,6 +134,8 @@ static float txgain = 0.0; static int echocancel; +static int echocanbridged = 0; + static char accountcode[20] = ""; static char mailbox[AST_MAX_EXTENSION]; @@ -313,10 +315,12 @@ static struct zt_pvt { int callwaitcas; int callwaitrings; int echocancel; + int echocanbridged; int permcallwaiting; int callwaitingcallerid; int threewaycalling; int transfer; + int dnd; int cref; /* Call reference number */ ZT_DIAL_OPERATION dop; struct zt_confinfo conf; /* Saved state of conference */ @@ -387,6 +391,8 @@ struct ast_channel *them; them = p->owners[p->thirdcallindex]; else them = p->owners[p->normalindex]; + if (!them) + return 0; if (!them->bridge) return 1; /* get their private structure, too */ themp = them->pvt->pvt; @@ -902,7 +908,7 @@ static int zt_call(struct ast_channel *ast, char *dest, int timeout) int x, res, index; char *c, *n, *l; char callerid[256]; - if ((ast->state != AST_STATE_DOWN) && (ast->state != AST_STATE_RESERVED)) { + if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name); return -1; } @@ -913,6 +919,9 @@ static int zt_call(struct ast_channel *ast, char *dest, int timeout) case SIG_FXOKS: if (p->owner == ast) { /* Normal ring, on hook */ + + /* Don't send audio while on hook, until the call is answered */ + p->dialing = 1; if (p->use_callerid) { /* Generate the Caller-ID spill if desired */ if (p->cidspill) { @@ -956,7 +965,7 @@ static int zt_call(struct ast_channel *ast, char *dest, int timeout) return -1; } - ast->state = AST_STATE_RINGING; + ast_setstate(ast, AST_STATE_RINGING); index = zt_get_index(ast, p, 0); if (index > -1) { p->needringing[index] = 1; @@ -1037,7 +1046,7 @@ static int zt_call(struct ast_channel *ast, char *dest, int timeout) ast_log(LOG_DEBUG, "Deferring dialing...\n"); p->dialing = 1; if (strlen(c + p->stripmsd) < 1) p->dialednone = 1; - ast->state = AST_STATE_DIALING; + ast_setstate(ast, AST_STATE_DIALING); break; #ifdef ZAPATA_PRI case SIG_PRI: @@ -1072,7 +1081,7 @@ static int zt_call(struct ast_channel *ast, char *dest, int timeout) #endif case 0: /* Special pseudo -- automatically up*/ - ast->state = AST_STATE_UP; + ast_setstate(ast, AST_STATE_UP); break; default: ast_log(LOG_DEBUG, "not yet implemented\n"); @@ -1150,7 +1159,7 @@ static int zt_hangup(struct ast_channel *ast) restore_gains(p); zap_digitmode(p->z,0); - ast->state = AST_STATE_DOWN; + ast_setstate(ast, AST_STATE_DOWN); ast_log(LOG_DEBUG, "Hangup: index = %d, normal = %d, callwait = %d, thirdcall = %d\n", index, p->normalindex, p->callwaitindex, p->thirdcallindex); p->ignoredtmf = 0; @@ -1274,7 +1283,7 @@ static int zt_hangup(struct ast_channel *ast) p->callwaitingrepeat = 0; ast->pvt->pvt = NULL; - ast->state = AST_STATE_DOWN; + ast_setstate(ast, AST_STATE_DOWN); ast_pthread_mutex_lock(&usecnt_lock); usecnt--; if (usecnt < 0) @@ -1306,7 +1315,7 @@ static int zt_answer(struct ast_channel *ast) { struct zt_pvt *p = ast->pvt->pvt; int res=0; - ast->state = AST_STATE_UP; + ast_setstate(ast, AST_STATE_UP); switch(p->sig) { case SIG_FXSLS: case SIG_FXSGS: @@ -1351,10 +1360,16 @@ static int zt_answer(struct ast_channel *ast) static inline int bridge_cleanup(struct zt_pvt *p0, struct zt_pvt *p1) { int res = 0; - if (p0) + if (p0) { res = conf_clear(p0); - if (p1) + if (!p0->echocanbridged) + zt_enable_ec(p0); + } + if (p1) { res |= conf_clear(p1); + if (!p1->echocanbridged) + zt_enable_ec(p1); + } return res; } @@ -1474,6 +1489,7 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_channel *who = NULL, *cs[3]; struct ast_frame *f; int to = -1; + int firstpass = 1; int confno = -1; @@ -1516,17 +1532,36 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, return 0; } if (!p0 || !p1 || (c0->type != type) || (c1->type != type)) { + if (!firstpass) { + if ((c0->type == type) && !p0->echocanbridged) + zt_enable_ec(p0); + if ((c1->type == type) && !p1->echocanbridged) + zt_enable_ec(p1); + } pthread_mutex_unlock(&c0->lock); pthread_mutex_unlock(&c1->lock); return -2; } + if (firstpass) { + /* Only do this once, turning off echo cancellation if this is a native bridge + with bridged echo cancellation turned off */ + if (!p0->echocanbridged) + zt_disable_ec(p0); + if (!p1->echocanbridged) + zt_disable_ec(p1); + firstpass = 0; + } if (INTHREEWAY(p0) && (c0 == p0->owners[p0->thirdcallindex])) tone_zone_play_tone(zap_fd(p0->pseudo), -1); if (INTHREEWAY(p1) && (c1 == p1->owners[p1->thirdcallindex])) tone_zone_play_tone(zap_fd(p1->pseudo), -1); if (INTHREEWAY(p0) && (INTHREEWAY(p1))) { ast_log(LOG_WARNING, "Too weird, can't bridge multiple three way calls\n"); + if (!p0->echocanbridged) + zt_enable_ec(p0); + if (!p1->echocanbridged) + zt_enable_ec(p1); pthread_mutex_unlock(&c0->lock); pthread_mutex_unlock(&c1->lock); return -1; @@ -1546,6 +1581,10 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, } else { ast_log(LOG_WARNING, "Can't bridge since %s is on conf %d and %s is on conf %d\n", c0->name, p0->confno, c1->name, p1->confno); + if (!p0->echocanbridged) + zt_enable_ec(p0); + if (!p1->echocanbridged) + zt_enable_ec(p1); pthread_mutex_unlock(&c0->lock); pthread_mutex_unlock(&c1->lock); return -1; @@ -1662,7 +1701,7 @@ static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan) for (x=0;x<3;x++) if (p->owners[x] == oldchan) p->owners[x] = newchan; - if (newchan->state == AST_STATE_RINGING) + if (newchan->_state == AST_STATE_RINGING) zt_indicate(newchan, AST_CONTROL_RINGING); return 0; } @@ -1731,7 +1770,7 @@ static int attempt_transfer(struct zt_pvt *p) } else { ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", p->owners[p->normalindex]->name, p->owners[p->thirdcallindex]->name); - p->owners[p->thirdcallindex]->softhangup=1; + p->owners[p->thirdcallindex]->_softhangup |= AST_SOFTHANGUP_DEV; } return 0; } @@ -1768,11 +1807,11 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) if (!x) { /* if not still dialing in driver */ zt_enable_ec(p); p->dialing = 0; - if (ast->state == AST_STATE_DIALING) { + if (ast->_state == AST_STATE_DIALING) { if (p->confirmanswer || (!p->dialednone && ((p->sig == SIG_EM) || (p->sig == SIG_EMWINK) || (p->sig == SIG_FEATD) || (p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATB)))) { - ast->state = AST_STATE_RINGING; + ast_setstate(ast, AST_STATE_RINGING); } else { - ast->state = AST_STATE_UP; + ast_setstate(ast, AST_STATE_UP); p->f[index].frametype = AST_FRAME_CONTROL; p->f[index].subclass = AST_CONTROL_ANSWER; } @@ -1804,9 +1843,9 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) } else if (p->thirdcallindex > -1) { if (p->transfer) { if (attempt_transfer(p)) - p->owners[p->thirdcallindex]->softhangup = 1; + p->owners[p->thirdcallindex]->_softhangup |= AST_SOFTHANGUP_DEV; } else - p->owners[p->thirdcallindex]->softhangup=1; + p->owners[p->thirdcallindex]->_softhangup |= AST_SOFTHANGUP_DEV; } } else if (index == p->callwaitindex) { /* Check to see if there is a normal call */ @@ -1823,28 +1862,28 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) zt_ring_phone(p); } } else if (index == p->thirdcallindex) { - if ((ast->state != AST_STATE_UP) && (ast->state != AST_STATE_RINGING) && - (ast->state != AST_STATE_RING)) { + if ((ast->_state != AST_STATE_UP) && (ast->_state != AST_STATE_RINGING) && + (ast->_state != AST_STATE_RING)) { /* According to the LSSGR, we should kill everything now, and we do, instead of ringing the phone */ if (p->normalindex > -1) - p->owners[p->normalindex]->softhangup=1; + p->owners[p->normalindex]->_softhangup |= AST_SOFTHANGUP_DEV; if (p->callwaitindex > -1) { ast_log(LOG_WARNING, "Somehow there was a call wait\n"); - p->owners[p->callwaitindex]->softhangup = 1; + p->owners[p->callwaitindex]->_softhangup |= AST_SOFTHANGUP_DEV; } } else { if (p->transfer) { if (attempt_transfer(p)) - p->owners[p->normalindex]->softhangup = 1; + p->owners[p->normalindex]->_softhangup |= AST_SOFTHANGUP_DEV; else { /* Don't actually hangup. We're going to get transferred */ zt_disable_ec(p); break; } } else - p->owners[p->normalindex]->softhangup = 1; + p->owners[p->normalindex]->_softhangup |= AST_SOFTHANGUP_DEV; } } /* Fall through */ @@ -1859,7 +1898,7 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: - switch(ast->state) { + switch(ast->_state) { case AST_STATE_RINGING: zt_enable_ec(p); p->f[index].frametype = AST_FRAME_CONTROL; @@ -1878,10 +1917,10 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) p->f[index].frametype = AST_FRAME_NULL; p->f[index].subclass = 0; } else - ast->state = AST_STATE_UP; + ast_setstate(ast, AST_STATE_UP); return &p->f[index]; case AST_STATE_DOWN: - ast->state = AST_STATE_RING; + ast_setstate(ast, AST_STATE_RING); ast->rings = 1; p->f[index].frametype = AST_FRAME_CONTROL; p->f[index].subclass = AST_CONTROL_OFFHOOK; @@ -1895,13 +1934,13 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) ast_moh_stop(p->owner->bridge); break; default: - ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->state); + ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state); } break; case SIG_FXSLS: case SIG_FXSGS: case SIG_FXSKS: - if (ast->state == AST_STATE_RING) { + if (ast->_state == AST_STATE_RING) { p->ringt = RINGT; } /* Fall through */ @@ -1910,12 +1949,12 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) case SIG_FEATD: case SIG_FEATDMF: case SIG_FEATB: - if (ast->state == AST_STATE_DOWN) { + if (ast->_state == AST_STATE_DOWN) { if (option_debug) ast_log(LOG_DEBUG, "Ring detected\n"); p->f[index].frametype = AST_FRAME_CONTROL; p->f[index].subclass = AST_CONTROL_RING; - } else if (ast->state == AST_STATE_RINGING) { + } else if (ast->_state == AST_STATE_RINGING) { if (option_debug) ast_log(LOG_DEBUG, "Line answered\n"); if (p->confirmanswer) { @@ -1924,10 +1963,10 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) } else { p->f[index].frametype = AST_FRAME_CONTROL; p->f[index].subclass = AST_CONTROL_ANSWER; - ast->state = AST_STATE_UP; + ast_setstate(ast, AST_STATE_UP); } - } else if (ast->state != AST_STATE_RING) - ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->state, p->channel); + } else if (ast->_state != AST_STATE_RING) + ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel); break; default: ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig); @@ -1962,8 +2001,8 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) if (p->callwaitindex > -1) { tone_zone_play_tone(zap_fd(p->z), -1); p->owner = p->owners[p->callwaitindex]; - if (p->owner->state == AST_STATE_RINGING) { - p->owner->state = AST_STATE_UP; + if (p->owner->_state == AST_STATE_RINGING) { + ast_setstate(p->owner, AST_STATE_UP); p->needanswer[p->callwaitindex] = 1; } p->callwaitingrepeat = 0; @@ -1975,9 +2014,9 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) ast_moh_stop(p->owners[p->callwaitindex]->bridge); } else if (p->thirdcallindex == -1) { if (p->threewaycalling) { - if ((ast->state == AST_STATE_RINGING) || - (ast->state == AST_STATE_UP) || - (ast->state == AST_STATE_RING)) { + if ((ast->_state == AST_STATE_RINGING) || + (ast->_state == AST_STATE_UP) || + (ast->_state == AST_STATE_RING)) { if (!alloc_pseudo(p)) { /* Start three way call */ /* Disable echo canceller for better dialing */ @@ -2012,7 +2051,7 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) /* Drop the last call and stop the conference */ if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->owners[p->thirdcallindex]->name); - p->owners[p->thirdcallindex]->softhangup=1; + p->owners[p->thirdcallindex]->_softhangup |= AST_SOFTHANGUP_DEV; conf_clear(p); } } else if (index == p->callwaitindex) { @@ -2032,17 +2071,17 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) /* One way or another, cancel music on hold */ if (p->owners[p->normalindex]->bridge) ast_moh_stop(p->owners[p->normalindex]->bridge); - if ((ast->state != AST_STATE_RINGING) && (ast->state != AST_STATE_UP) && (ast->state != AST_STATE_RING)) { + if ((ast->_state != AST_STATE_RINGING) && (ast->_state != AST_STATE_UP) && (ast->_state != AST_STATE_RING)) { tone_zone_play_tone(zap_fd(p->z), -1); p->owner = p->owners[p->normalindex]; - ast_log(LOG_DEBUG, "Dumping incomplete three way call in state %d\n", ast->state); + ast_log(LOG_DEBUG, "Dumping incomplete three way call in state %d\n", ast->_state); zt_enable_ec(p); return NULL; } p->owner = p->owners[p->normalindex]; p->owners[p->thirdcallindex]->fds[0] = zap_fd(p->pseudo); p->callwaitingrepeat = 0; - if (p->owners[p->thirdcallindex]->state == AST_STATE_RINGING) { + if (p->owners[p->thirdcallindex]->_state == AST_STATE_RINGING) { /* If we were ringing, stop the ringing on the main line and start it on the pseudo */ tone_zone_play_tone(zap_fd(p->z), -1); @@ -2068,7 +2107,7 @@ struct ast_frame *zt_handle_event(struct ast_channel *ast) if (p->dialing) ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel); else - ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->state, p->channel); + ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel); break; case SIG_FEATDMF: case SIG_FEATB: @@ -2174,10 +2213,10 @@ struct ast_frame *zt_exception(struct ast_channel *ast) if (p->owner) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name); - if ((usedindex == p->callwaitindex) && (p->owner->state == AST_STATE_RINGING)) { + if ((usedindex == p->callwaitindex) && (p->owner->_state == AST_STATE_RINGING)) { /* Answer the call wait if necessary */ p->needanswer[usedindex] = 1; - p->owner->state = AST_STATE_UP; + ast_setstate(p->owner, AST_STATE_UP); } p->callwaitingrepeat = 0; if (p->owner->bridge) @@ -2238,7 +2277,7 @@ struct ast_frame *zt_read(struct ast_channel *ast) p->needringing[index] = 0; p->f[index].frametype = AST_FRAME_CONTROL; p->f[index].subclass = AST_CONTROL_RINGING; - ast->state = AST_STATE_RINGING; + ast_setstate(ast, AST_STATE_RINGING); pthread_mutex_unlock(&p->lock); return &p->f[index]; } @@ -2248,7 +2287,7 @@ struct ast_frame *zt_read(struct ast_channel *ast) p->needanswer[index] = 0; p->f[index].frametype = AST_FRAME_CONTROL; p->f[index].subclass = AST_CONTROL_ANSWER; - ast->state = AST_STATE_UP; + ast_setstate(ast, AST_STATE_UP); pthread_mutex_unlock(&p->lock); return &p->f[index]; } @@ -2290,7 +2329,7 @@ struct ast_frame *zt_read(struct ast_channel *ast) of a DTMF digit */ p->f[index].frametype = AST_FRAME_CONTROL; p->f[index].subclass = AST_CONTROL_ANSWER; - ast->state = AST_STATE_UP; + ast_setstate(ast, AST_STATE_UP); } pthread_mutex_unlock(&p->lock); return &p->f[index]; @@ -2345,7 +2384,7 @@ struct ast_frame *zt_read(struct ast_channel *ast) of a DTMF digit */ p->f[index].frametype = AST_FRAME_CONTROL; p->f[index].subclass = AST_CONTROL_ANSWER; - ast->state = AST_STATE_UP; + ast_setstate(ast, AST_STATE_UP); } else { ast_log(LOG_DEBUG, "Got some dtmf ('%s')... on channel %s\n", zap_dtmfbuf(z), ast->name); /* DTMF tone detected. Queue and erturn */ @@ -2409,7 +2448,7 @@ struct ast_frame *zt_read(struct ast_channel *ast) p->f[index].datalen = READ_SIZE; /* Handle CallerID Transmission */ - if (p->cidspill &&((ast->state == AST_STATE_UP) || (ast->rings == p->cidrings))) { + if (p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) { send_callerid(p); } @@ -2561,12 +2600,12 @@ static int zt_indicate(struct ast_channel *chan, int condition) break; case AST_CONTROL_RINGING: res = tone_zone_play_tone(zap_fd(p->z), ZT_TONE_RINGTONE); - if (chan->state != AST_STATE_UP) { - if ((chan->state != AST_STATE_RING) || + if (chan->_state != AST_STATE_UP) { + if ((chan->_state != AST_STATE_RING) || ((p->sig != SIG_FXSKS) && (p->sig != SIG_FXSLS) && (p->sig != SIG_FXSGS))) - chan->state = AST_STATE_RINGING; + ast_setstate(chan, AST_STATE_RINGING); } break; case AST_CONTROL_CONGESTION: @@ -2619,7 +2658,6 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int tmp->pvt->rawwriteformat = deflaw; tmp->writeformat = deflaw; - tmp->state = state; if (state == AST_STATE_RING) tmp->rings = 1; tmp->pvt->pvt = i; @@ -2660,6 +2698,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int ast_log(LOG_WARNING, "channel %d already has a normal call\n", i->channel); i->normalindex = x; } + ast_setstate(tmp, state); ast_pthread_mutex_lock(&usecnt_lock); usecnt++; ast_pthread_mutex_unlock(&usecnt_lock); @@ -2913,7 +2952,7 @@ static void *ss_thread(void *data) chan->callerid = strdup(p->callerid); chan->ani = strdup(p->callerid); } - chan->state = AST_STATE_RING; + ast_setstate(chan, AST_STATE_RING); zt_enable_ec(p); res = ast_pbx_run(chan); if (res) { @@ -2944,9 +2983,10 @@ static void *ss_thread(void *data) */ struct zt_pvt *chan_pvt=iflist; while(chan_pvt!=NULL){ - if((p!=chan_pvt)&& - ((p->pickupgroup & chan_pvt->callgroup)==chan_pvt->callgroup)&& - (chan_pvt->owner && (chan_pvt->owner->state==AST_STATE_RING || chan_pvt->owner->state == AST_STATE_RINGING)) + if((p!=chan_pvt) && + (p->pickupgroup & chan_pvt->callgroup) && + (chan_pvt->owner && (chan_pvt->owner->_state==AST_STATE_RING || chan_pvt->owner->_state == AST_STATE_RINGING)) && + chan_pvt->dialing ){ /* Switch us from Third call to Call Wait */ p->callwaitindex = p->thirdcallindex; @@ -2982,6 +3022,24 @@ static void *ss_thread(void *data) len = 0; memset(exten, 0, sizeof(exten)); timeout = firstdigittimeout; + } else if (!strcmp(exten, "*78")) { + /* Do not disturb */ + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel); + res = tone_zone_play_tone(zap_fd(p->z), ZT_TONE_DIALRECALL); + p->dnd = 1; + getforward = 0; + memset(exten, 0, sizeof(exten)); + len = 0; + } else if (!strcmp(exten, "*79")) { + /* Do not disturb */ + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel); + res = tone_zone_play_tone(zap_fd(p->z), ZT_TONE_DIALRECALL); + p->dnd = 0; + getforward = 0; + memset(exten, 0, sizeof(exten)); + len = 0; } else if (p->cancallforward && !strcmp(exten, "*72")) { res = tone_zone_play_tone(zap_fd(p->z), ZT_TONE_DIALRECALL); getforward = 1; @@ -3035,7 +3093,7 @@ static void *ss_thread(void *data) ISTRUNK(pbridge)) { int func = ZT_FLASH; /* flash hookswitch */ - if (ioctl(zap_fd(pbridge->z),ZT_HOOK,&func) == -1) { + if ((ioctl(zap_fd(pbridge->z),ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) { ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", nbridge->name, strerror(errno)); } @@ -3136,7 +3194,7 @@ static void *ss_thread(void *data) chan->callerid = strdup(cid); chan->ani = strdup(cid); } - chan->state = AST_STATE_RING; + ast_setstate(chan, AST_STATE_RING); chan->rings = 1; p->ringt = RINGT; zt_enable_ec(p); @@ -3418,12 +3476,12 @@ static int reset_channel(struct zt_pvt *p) ast_log(LOG_DEBUG, "reset_channel()\n"); if (p->owner) { ioctlflag = 0; - p->owner->softhangup = 1; + p->owner->_softhangup |= AST_SOFTHANGUP_DEV; } for (i = 0; i < 3; i++) { if (p->owners[i]) { ioctlflag = 0; - p->owners[i]->softhangup = 1; + p->owners[i]->_softhangup |= AST_SOFTHANGUP_DEV; } } if (ioctlflag) { @@ -3495,6 +3553,7 @@ static struct zt_pvt *mkintf(int channel, int signalling) free(tmp); return NULL; } + memset(&p, 0, sizeof(p)); res = ioctl(zap_fd(tmp->z), ZT_GET_PARAMS, &p); if (res < 0) { ast_log(LOG_ERROR, "Unable to get parameters\n"); @@ -3651,6 +3710,7 @@ static struct zt_pvt *mkintf(int channel, int signalling) tmp->adsi = adsi; tmp->permhidecallerid = hidecallerid; tmp->echocancel = echocancel; + tmp->echocanbridged = echocanbridged; tmp->cancallforward = cancallforward; tmp->callwaiting = tmp->permcallwaiting; tmp->hidecallerid = tmp->permhidecallerid; @@ -3712,6 +3772,9 @@ static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch) /* Check to see if we have a channel match */ if ((channelmatch > 0) && (p->channel != channelmatch)) return 0; + /* If do not distrub, definitely not */ + if (p->dnd) + return 0; /* If no owner definitely available */ if (!p->owner) { @@ -3753,8 +3816,8 @@ static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch) return 0; } - if ((p->owner->state != AST_STATE_UP) && - (p->owner->state != AST_STATE_RINGING)) { + if ((p->owner->_state != AST_STATE_UP) && + (p->owner->_state != AST_STATE_RINGING)) { /* If the current call is not up, then don't allow the call */ return 0; } @@ -4156,7 +4219,7 @@ static void *pri_dchannel(void *vpri) for (x=pri->channels;x>=0;x--) { /* find a candidate channel */ if (pri->pvt[x] && pri->pvt[x]->owner && pri->pvt[x]->isidlecall) { - pri->pvt[x]->owner->softhangup = 1; + pri->pvt[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; haveidles++; /* Stop if we have enough idle channels or can't spare any more active idle ones */ @@ -4242,14 +4305,14 @@ static void *pri_dchannel(void *vpri) chan, pri->span); /* Force soft hangup if appropriate */ if (pri->pvt[chan]->owner) - pri->pvt[chan]->owner->softhangup = 1; + pri->pvt[chan]->owner->_softhangup |= AST_SOFTHANGUP_DEV; } } else { if (option_verbose > 2) ast_verbose("Restart on requested on entire span %d\n", pri->span); for (x=1;x <= pri->channels;x++) if ((x != pri->dchannel) && (pri->pvt[x]->owner)) - pri->pvt[x]->owner->softhangup = 1; + pri->pvt[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV; } break; case PRI_EVENT_RING: @@ -4266,7 +4329,7 @@ static void *pri_dchannel(void *vpri) break; } else { ast_log(LOG_WARNING, "Ring requested on channel %d already in use on span %d. Hanging up owner.\n", chan, pri->span); - pri->pvt[chan]->owner->softhangup = 1; + pri->pvt[chan]->owner->_softhangup |= AST_SOFTHANGUP_DEV; chan = 0; } } @@ -4367,9 +4430,9 @@ static void *pri_dchannel(void *vpri) chan = pri_fixup(pri, chan, e->hangup.call); if (chan) { if (pri->pvt[chan]->owner) { + pri->pvt[chan]->owner->_softhangup |= AST_SOFTHANGUP_DEV; if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Channel %d, span %d got hangup\n", chan, pri->span); - pri->pvt[chan]->owner->softhangup = 1; } if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { if (option_verbose > 2) @@ -4413,7 +4476,7 @@ static void *pri_dchannel(void *vpri) if (pri->pvt[chan]) { if (pri->pvt[chan]->owner) { ast_log(LOG_WARNING, "Got restart ack on channel with owner\n"); - pri->pvt[chan]->owner->softhangup = 1; + pri->pvt[chan]->owner->_softhangup |= AST_SOFTHANGUP_DEV; } pri->pvt[chan]->resetting = 0; } @@ -4785,6 +4848,8 @@ int load_module() adsi = ast_true(v->value); } else if (!strcasecmp(v->name, "transfer")) { transfer = ast_true(v->value); + } else if (!strcasecmp(v->name, "echocancelwhenbridged")) { + echocanbridged = ast_true(v->value); } else if (!strcasecmp(v->name, "echocancel")) { if (v->value && strlen(v->value)) y = atoi(v->value); @@ -4961,7 +5026,7 @@ int unload_module() p = iflist; while(p) { if (p->owner) - ast_softhangup(p->owner); + ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); p = p->next; } iflist = NULL; @@ -5137,8 +5202,6 @@ static int reload_zt(void) threewaycalling = ast_true(v->value); } else if (!strcasecmp(v->name, "transfer")) { transfer = ast_true(v->value); - } else if (!strcasecmp(v->name, "echocancel")) { - echocancel = ast_true(v->value); } else if (!strcasecmp(v->name, "hidecallerid")) { hidecallerid = ast_true(v->value); } else if (!strcasecmp(v->name, "callwaiting")) { @@ -5302,11 +5365,12 @@ static int zt_sendtext(struct ast_channel *c, char *text) float scont = 0.0; + if (!text[0]) return(0); /* if nothing to send, dont */ if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */ if (p->mate) - buf = malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); - else buf = malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN); + else + buf = malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN); if (!buf) { ast_log(LOG_ERROR, "MALLOC FAILED\n"); return -1; -- cgit v1.2.3