diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index 79f20e890e64a1d284afd6997d5d238d6a9f14bd..c342582b353c87c1512767d136ddf11c2c5e9165 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -1190,6 +1190,8 @@ static int matchdigittimeout = 3000; #define SUBSTATE_RINGIN 4 #define SUBSTATE_CONNECTED 5 #define SUBSTATE_BUSY 6 +#define SUBSTATE_CONGESTION 7 +#define SUBSTATE_PROGRESS 12 #define SUBSTATE_DIALING 101 struct skinny_subchannel { @@ -1417,6 +1419,8 @@ static void setsubstate_ringin(struct skinny_subchannel *sub); static void setsubstate_ringout(struct skinny_subchannel *sub); static void setsubstate_connected(struct skinny_subchannel *sub); static void setsubstate_busy(struct skinny_subchannel *sub); +static void setsubstate_congestion(struct skinny_subchannel *sub); +static void setsubstate_progress(struct skinny_subchannel *sub); static struct ast_channel_tech skinny_tech = { .type = "Skinny", @@ -4505,32 +4509,11 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s setsubstate_busy(sub); return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */ case AST_CONTROL_CONGESTION: - if (ast->_state != AST_STATE_UP) { - if (!d->earlyrtp) { - transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); - } - transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONGESTION); - sub->alreadygone = 1; - ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); - if (!d->earlyrtp) { - break; - } - } - return -1; /* Tell asterisk to provide inband signalling */ + setsubstate_congestion(sub); + return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */ case AST_CONTROL_PROGRESS: - if ((ast->_state != AST_STATE_UP) && !sub->progress && !(sub->calldirection == SKINNY_INCOMING)) { - if (!d->earlyrtp) { - transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid); - } - transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_PROGRESS); - transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid); - transmit_callinfo(sub); - sub->progress = 1; - if (!d->earlyrtp) { - break; - } - } - return -1; /* Tell asterisk to provide inband signalling */ + setsubstate_progress(sub); + return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */ case -1: /* STOP_TONE */ transmit_stop_tone(d, l->instance, sub->callid); break; @@ -4690,6 +4673,12 @@ static char *substate2str(int ind) { return "SUBSTATE_RINGIN"; case SUBSTATE_CONNECTED: return "SUBSTATE_CONNECTED"; + case SUBSTATE_BUSY: + return "SUBSTATE_BUSY"; + case SUBSTATE_CONGESTION: + return "SUBSTATE_CONGESTION"; + case SUBSTATE_PROGRESS: + return "SUBSTATE_PROGRESS"; case SUBSTATE_DIALING: return "SUBSTATE_DIALING"; default: @@ -4764,8 +4753,8 @@ static void setsubstate_ringout(struct skinny_subchannel *sub) struct skinny_line *l = sub->parent; struct skinny_device *d = l->device; - if (sub->substate != SUBSTATE_DIALING) { - ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_DIALING from %s (on call-%d)\n", substate2str(sub->substate), sub->callid); + if (!(sub->substate == SUBSTATE_DIALING || sub->substate == SUBSTATE_PROGRESS)) { + ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_RINGOUT from %s (on call-%d)\n", substate2str(sub->substate), sub->callid); return; } @@ -4833,7 +4822,7 @@ static void setsubstate_busy(struct skinny_subchannel *sub) struct skinny_line *l = sub->parent; struct skinny_device *d = l->device; - if (sub->substate != SUBSTATE_DIALING) { + if (!(sub->substate == SUBSTATE_DIALING || sub->substate == SUBSTATE_PROGRESS || sub->substate == SUBSTATE_RINGOUT)) { ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_BUSY from %s (on call-%d)\n", substate2str(sub->substate), sub->callid); return; } @@ -4847,6 +4836,44 @@ static void setsubstate_busy(struct skinny_subchannel *sub) sub->substate = SUBSTATE_BUSY; } +static void setsubstate_congestion(struct skinny_subchannel *sub) +{ + struct skinny_line *l = sub->parent; + struct skinny_device *d = l->device; + + if (!(sub->substate == SUBSTATE_DIALING || sub->substate == SUBSTATE_PROGRESS || sub->substate == SUBSTATE_RINGOUT)) { + ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_CONGESTION from %s (on call-%d)\n", substate2str(sub->substate), sub->callid); + return; + } + + if (!d->earlyrtp) { + transmit_start_tone(d, SKINNY_REORDER, l->instance, sub->callid); + } + transmit_callinfo(sub); + transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_CONGESTION); + transmit_displaypromptstatus(d, "Congestion", 0, l->instance, sub->callid); + sub->substate = SUBSTATE_CONGESTION; +} + +static void setsubstate_progress(struct skinny_subchannel *sub) +{ + struct skinny_line *l = sub->parent; + struct skinny_device *d = l->device; + + if (sub->substate != SUBSTATE_DIALING) { + ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_PROGRESS from %s (on call-%d)\n", substate2str(sub->substate), sub->callid); + return; + } + + if (!d->earlyrtp) { + transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid); + } + transmit_callinfo(sub); + transmit_callstate(d, sub->parent->instance, sub->callid, SKINNY_PROGRESS); + transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid); + sub->substate = SUBSTATE_PROGRESS; +} + static int skinny_hold(struct skinny_subchannel *sub) { struct skinny_line *l = sub->parent;