Index: channels/chan_zap.c =================================================================== --- channels/chan_zap.c (revision 83879) +++ channels/chan_zap.c (working copy) @@ -1605,13 +1605,20 @@ return 0; } -static inline int zt_set_hook(int fd, int hs) +static inline int zt_set_hook(int fd, int hs, int fx) { - int x, res; + int x, res, count = 0; x = hs; res = ioctl(fd, ZT_HOOK, &x); + while (fx && res < 0 && count < 20) { + usleep(100000); /* 1/10 sec. */ + x = hs; + res = ioctl(fd, ZT_HOOK, &x); + count++; + } + if (res < 0) { if (errno == EINPROGRESS) return 0; @@ -2631,7 +2638,7 @@ } #endif if (p->sig && (p->sig != SIG_PRI)) - res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); + res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK, 0); if (res < 0) { ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name); } @@ -2774,7 +2781,7 @@ if (p->hanguponpolarityswitch) { gettimeofday(&p->polaritydelaytv, NULL); } - res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); + res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK, p->sig == SIG_FXOLS || p->sig == SIG_FXOKS ? 1 : 0); tone_zone_play_tone(p->subs[index].zfd, -1); p->dialing = 0; if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) { @@ -3834,8 +3841,8 @@ if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) { /* Make sure it starts ringing */ - zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); - zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING); + zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF, 0); + zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING, 0); save_conference(p->oprpeer); tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); } @@ -3955,7 +3962,7 @@ if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS)) { /* Make sure it stops ringing */ - zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF); + zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF, 0); tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1); restore_conference(p->oprpeer); } @@ -4005,7 +4012,7 @@ p->subs[index].f.frametype = AST_FRAME_CONTROL; p->subs[index].f.subclass = AST_CONTROL_ANSWER; /* Make sure it stops ringing */ - zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); + zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK, 1); ast_log(LOG_DEBUG, "channel %d answered\n", p->channel); if (p->cidspill) { /* Cancel any running CallerID spill */ @@ -4045,7 +4052,7 @@ return &p->subs[index].f; case AST_STATE_UP: /* Make sure it stops ringing */ - zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); + zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK, 1); /* Okay -- probably call waiting*/ if (ast_bridged_channel(p->owner)) ast_queue_control(p->owner, AST_CONTROL_UNHOLD); @@ -4170,8 +4177,8 @@ if (!par.rxisoffhook) { /* Make sure it stops ringing */ - zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF); - zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING); + zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF, 0); + zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING, 0); save_conference(p); tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); } @@ -4539,7 +4546,7 @@ update_conf(p); break; case ZT_EVENT_RINGOFFHOOK: - zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); + zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK, p->sig == SIG_FXOLS || p->sig == SIG_FXOKS ? 1 : 0); if (p->owner && (p->owner->_state == AST_STATE_RINGING)) { p->subs[SUB_REAL].needanswer = 1; p->dialing = 0; @@ -5133,12 +5140,12 @@ break; case AST_CONTROL_RADIO_KEY: if (p->radio) - res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK); + res = zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK, 0); res = 0; break; case AST_CONTROL_RADIO_UNKEY: if (p->radio) - res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF); + res = zt_set_hook(p->subs[index].zfd, ZT_RINGOFF, 0); res = 0; break; case AST_CONTROL_FLASH: @@ -5373,7 +5380,7 @@ static int zt_wink(struct zt_pvt *p, int index) { int j; - zt_set_hook(p->subs[index].zfd, ZT_WINK); + zt_set_hook(p->subs[index].zfd, ZT_WINK, 0); for (;;) { /* set bits of interest */ @@ -5565,7 +5572,7 @@ if (res > 0) { /* if E911, take off hook */ if (p->sig == SIG_E911) - zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); + zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK, 0); res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000); } if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp); @@ -5629,7 +5636,7 @@ ast_hangup(chan); return NULL; } - zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); + zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK, 0); ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); res = my_getsigstr(chan, anibuf, "#", 10000); if ((res > 0) && (strlen(anibuf) > 2)) { @@ -6157,7 +6164,7 @@ if (p->cid_signalling == CID_SIG_V23_JP) { #ifdef ZT_EVENT_RINGBEGIN if (res == ZT_EVENT_RINGBEGIN) { - res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK); + res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK, 0); usleep(1); } #endif @@ -6202,7 +6209,7 @@ } if (p->cid_signalling == CID_SIG_V23_JP) { - res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK); + res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK, 0); usleep(1); res = 4000; } else { @@ -6571,7 +6578,7 @@ case SIG_FXOLS: case SIG_FXOGS: case SIG_FXOKS: - res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); + res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK, 1); if (res && (errno == EBUSY)) break; if (i->cidspill) { @@ -6694,18 +6701,18 @@ case SIG_GR303FXSKS: zt_disable_ec(i); res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); - zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); + zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK, 0); break; case SIG_GR303FXOKS: case SIG_FXOKS: zt_disable_ec(i); /* Diddle the battery for the zhone */ #ifdef ZHONE_HACK - zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK); + zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK, 1); usleep(1); #endif res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1); - zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK); + zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK, 0); break; case SIG_PRI: zt_disable_ec(i); @@ -7469,7 +7476,7 @@ if (!here) { if (conf.chan.sig != SIG_PRI) /* Hang it up to be sure it's good */ - zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK); + zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK, 0); } ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone); #ifdef HAVE_PRI