diff --git a/src/channels/chan_voicemngr.c b/src/channels/chan_voicemngr.c index a528d6d1f0cb430a25dd7b8f2c6b67d720c3630b..87431cd0fdbecedae85a7d448c90f5f9ceb99c80 100644 --- a/src/channels/chan_voicemngr.c +++ b/src/channels/chan_voicemngr.c @@ -120,11 +120,11 @@ static int chan_voicemngr_create_connection(struct chan_voicemngr_subchannel *p) static int chan_voicemngr_stop_dialtone(struct chan_voicemngr_pvt *p); static void chan_voicemngr_signal_howler(struct chan_voicemngr_pvt *p); static int chan_voicemngr_signal_ringing(struct chan_voicemngr_pvt *p); -static int chan_voicemngr_stop_ringing(struct chan_voicemngr_pvt *p); +static int chan_voicemngr_stop_ringing(struct chan_voicemngr_pvt *p, int hangupcause); static int chan_voicemngr_signal_ringing_callerid_pending(struct chan_voicemngr_pvt *p); -static int chan_voicemngr_stop_ringing_callerid_pending(struct chan_voicemngr_pvt *p); +static int chan_voicemngr_stop_ringing_callerid_pending(struct chan_voicemngr_pvt *p, int hangupcause); static int chan_voicemngr_signal_callwaiting(const struct chan_voicemngr_pvt *p); -static int chan_voicemngr_stop_callwaiting(const struct chan_voicemngr_pvt *p); +static int chan_voicemngr_stop_callwaiting(const struct chan_voicemngr_pvt *p, int hangupcause); static int chan_voicemngr_signal_callerid(struct ast_channel *chan, struct chan_voicemngr_subchannel *sub, int callwt); static struct chan_voicemngr_subchannel *chan_voicemngr_get_idle_subchannel(const struct chan_voicemngr_pvt *p); static struct chan_voicemngr_subchannel* chan_voicemngr_get_active_subchannel(const struct chan_voicemngr_pvt *p); @@ -1558,7 +1558,7 @@ static int chan_voicemngr_hangup(struct ast_channel *ast) } if (sub->channel_state == CALLWAITING) { - chan_voicemngr_stop_callwaiting(p); + chan_voicemngr_stop_callwaiting(p, ast_channel_hangupcause(ast)); } else if (sub_peer->channel_state == ONHOLD && sub_peer->onhold_hangup_timer_id != -1 && sub->channel_state == RINGING) { ast_debug(2, "There is a forgotten onhold call, not releasing channel\n"); @@ -1567,9 +1567,9 @@ static int chan_voicemngr_hangup(struct ast_channel *ast) //Stop ringing if other end hungup before we answered channel_settings *s = &channel_config[p->line_id]; if (!s->calleridenable) { - p->tech->stop_ringing(p); + p->tech->stop_ringing(p, ast_channel_hangupcause(ast)); } else { - p->tech->stop_ringing_callerid_pending(p); + p->tech->stop_ringing_callerid_pending(p, ast_channel_hangupcause(ast)); } } else if (chan_voicemngr_subchannel_is_idle(sub_peer) && p->tech->release) { // No active subchannel left, release @@ -2347,9 +2347,9 @@ static int cwtimeout_cb(const void *data) } //ast_mutex_unlock(&sub->parent->lock); if (sub->channel_state == CALLWAITING) - chan_voicemngr_stop_callwaiting(sub->parent); + chan_voicemngr_stop_callwaiting(sub->parent, AST_CAUSE_USER_BUSY); else if (sub->channel_state == RINGING) - chan_voicemngr_stop_ringing(sub->parent); + chan_voicemngr_stop_ringing(sub->parent, AST_CAUSE_USER_BUSY); pvt_unlock(sub->parent); if (owner) { @@ -2941,7 +2941,7 @@ static void handle_Rnumber_etsi(struct chan_voicemngr_subchannel *sub, struct ch if (sub_peer->channel_state == CALLWAITING) { ast_log(LOG_WARNING, "R1 call waiting\n"); /* Stop call waiting tone on current call */ - chan_voicemngr_stop_callwaiting(p); + chan_voicemngr_stop_callwaiting(p, ast_channel_hangupcause(owner)); if (ast_sched_del(sched, sub_peer->cw_timer_id)) { ast_log(LOG_WARNING, "Failed to remove scheduled call waiting timer\n"); @@ -3029,7 +3029,7 @@ static void handle_Rnumber_etsi(struct chan_voicemngr_subchannel *sub, struct ch ast_log(LOG_WARNING, "R2 Call waiting\n"); /* Stop call waiting tone on current call */ - chan_voicemngr_stop_callwaiting(p); + chan_voicemngr_stop_callwaiting(p, ast_channel_hangupcause(owner)); /* Cancel timer */ if (ast_sched_del(sched, sub_peer->cw_timer_id)) { @@ -3121,7 +3121,7 @@ static void handle_Rkey_uk(struct chan_voicemngr_subchannel *sub, struct chan_vo } ast_log(LOG_NOTICE, " R in Call waiting\n"); /* Stop call waiting tone on current call */ - chan_voicemngr_stop_callwaiting(p); + chan_voicemngr_stop_callwaiting(p, ast_channel_hangupcause(owner)); /* Cancel timers */ if (ast_sched_del(sched, sub_peer->cw_timer_id)) { ast_log(LOG_WARNING, "Failed to remove scheduled call waiting timer\n"); @@ -6044,9 +6044,14 @@ static int chan_voicemngr_signal_callwaiting(const struct chan_voicemngr_pvt *p) return 0; } -static int chan_voicemngr_stop_callwaiting(const struct chan_voicemngr_pvt *p) +static int chan_voicemngr_stop_callwaiting(const struct chan_voicemngr_pvt *p, int hangupcause) { - endpt_signal(p->line_id, "callwt", "off", NULL); + ast_debug(3, "chan_voicemngr_stop_callwaiting(), hangupcause: %d\n", hangupcause); + if (hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) + endpt_signal(p->line_id, "callwt", "off", "answered"); + else + endpt_signal(p->line_id, "callwt", "off", NULL); + chan_voicemngr_send_ubus_event("CALLWAITING_STOPPED", p->line_id); return 0; } @@ -6065,11 +6070,14 @@ static int chan_voicemngr_signal_ringing(struct chan_voicemngr_pvt *p) } -static int chan_voicemngr_stop_ringing(struct chan_voicemngr_pvt *p) +static int chan_voicemngr_stop_ringing(struct chan_voicemngr_pvt *p, int hangupcause) { - ast_log(LOG_ERROR, "chan_voicemngr_stop_ringing()\n"); + ast_debug(3, "chan_voicemngr_stop_ringing(), hangupcause: %d\n", hangupcause); if (channel_config[p->line_id].ringsignal) { - endpt_signal(p->line_id, "ringing", "off", NULL); + if (hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) + endpt_signal(p->line_id, "ringing", "off", "answered"); + else + endpt_signal(p->line_id, "ringing", "off", NULL); } return 0; @@ -6090,10 +6098,14 @@ static int chan_voicemngr_signal_ringing_callerid_pending(struct chan_voicemngr_ return 0; } -static int chan_voicemngr_stop_ringing_callerid_pending(struct chan_voicemngr_pvt *p) +static int chan_voicemngr_stop_ringing_callerid_pending(struct chan_voicemngr_pvt *p, int hangupcause) { + ast_debug(3, "chan_voicemngr_stop_ringing_callerid_pending(), hangupcause: %d\n", hangupcause); if (channel_config[p->line_id].ringsignal) { - endpt_signal(p->line_id, "callid_ringing", "off", NULL); + if (hangupcause == AST_CAUSE_ANSWERED_ELSEWHERE) + endpt_signal(p->line_id, "callid_ringing", "off", "answered"); + else + endpt_signal(p->line_id, "callid_ringing", "off", NULL); } return 0; @@ -6511,9 +6523,9 @@ static void chan_voicemngr_unattended_call_transfer(struct chan_voicemngr_subcha channel_settings *s = &channel_config[p->line_id]; if (!s->calleridenable) { - p->tech->stop_ringing(p); + p->tech->stop_ringing(p, ast_channel_hangupcause(owner)); } else { - p->tech->stop_ringing_callerid_pending(p); + p->tech->stop_ringing_callerid_pending(p, ast_channel_hangupcause(owner)); } // unattended call transfer: cancel the the call to transfer target diff --git a/src/channels/chan_voicemngr.h b/src/channels/chan_voicemngr.h index 433bba1f7a79aae18399af3dee89c2491f7e6fb8..898b9abcc7b2b1cc895d223aaa5e2ba62cfb23dc 100644 --- a/src/channels/chan_voicemngr.h +++ b/src/channels/chan_voicemngr.h @@ -203,8 +203,8 @@ struct chan_voicemngr_channel_tech { int (* signal_ringing)(struct chan_voicemngr_pvt *p); int (* signal_ringing_callerid_pending)(struct chan_voicemngr_pvt *p); int (* signal_callerid)(struct ast_channel *chan, struct chan_voicemngr_subchannel *s, int callwt); - int (* stop_ringing)(struct chan_voicemngr_pvt *p); - int (* stop_ringing_callerid_pending)(struct chan_voicemngr_pvt *p); + int (* stop_ringing)(struct chan_voicemngr_pvt *p, int hangupcause); + int (* stop_ringing_callerid_pending)(struct chan_voicemngr_pvt *p, int hangupcause); int (* release)(struct chan_voicemngr_pvt *p); };