mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-22 20:56:39 +00:00
bridge core: Add owed T.38 terminate when channel leaves a bridge.
The channel is now going to get T.38 terminated when it leaves the bridging system and the bridged peers are going to get T.38 terminated as well. ASTERISK-25582 Change-Id: I77a9205979910210e3068e1ddff400dbf35c4ca7
This commit is contained in:
@@ -162,6 +162,8 @@ struct ast_bridge_channel {
|
|||||||
struct timeval dtmf_tv;
|
struct timeval dtmf_tv;
|
||||||
/*! Digit currently sending into the bridge. (zero if not sending) */
|
/*! Digit currently sending into the bridge. (zero if not sending) */
|
||||||
char dtmf_digit;
|
char dtmf_digit;
|
||||||
|
/*! Non-zero if a T.38 session terminate is owed to the bridge. */
|
||||||
|
char t38_terminate;
|
||||||
} owed;
|
} owed;
|
||||||
/*! DTMF hook sequence state */
|
/*! DTMF hook sequence state */
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -637,6 +637,8 @@ void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int caus
|
|||||||
*/
|
*/
|
||||||
static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
|
static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
|
||||||
{
|
{
|
||||||
|
const struct ast_control_t38_parameters *t38_parameters;
|
||||||
|
|
||||||
ast_assert(frame->frametype != AST_FRAME_BRIDGE_ACTION_SYNC);
|
ast_assert(frame->frametype != AST_FRAME_BRIDGE_ACTION_SYNC);
|
||||||
|
|
||||||
ast_bridge_channel_lock_bridge(bridge_channel);
|
ast_bridge_channel_lock_bridge(bridge_channel);
|
||||||
@@ -663,6 +665,27 @@ static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel,
|
|||||||
* We explicitly will not remember HOLD/UNHOLD frames because
|
* We explicitly will not remember HOLD/UNHOLD frames because
|
||||||
* things like attended transfers will handle them.
|
* things like attended transfers will handle them.
|
||||||
*/
|
*/
|
||||||
|
switch (frame->subclass.integer) {
|
||||||
|
case AST_CONTROL_T38_PARAMETERS:
|
||||||
|
t38_parameters = frame->data.ptr;
|
||||||
|
switch (t38_parameters->request_response) {
|
||||||
|
case AST_T38_REQUEST_NEGOTIATE:
|
||||||
|
case AST_T38_NEGOTIATED:
|
||||||
|
bridge_channel->owed.t38_terminate = 1;
|
||||||
|
break;
|
||||||
|
case AST_T38_REQUEST_TERMINATE:
|
||||||
|
case AST_T38_TERMINATED:
|
||||||
|
case AST_T38_REFUSED:
|
||||||
|
bridge_channel->owed.t38_terminate = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -689,6 +712,7 @@ static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel,
|
|||||||
static void bridge_channel_cancel_owed_events(struct ast_bridge_channel *bridge_channel)
|
static void bridge_channel_cancel_owed_events(struct ast_bridge_channel *bridge_channel)
|
||||||
{
|
{
|
||||||
bridge_channel->owed.dtmf_digit = '\0';
|
bridge_channel->owed.dtmf_digit = '\0';
|
||||||
|
bridge_channel->owed.t38_terminate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
|
void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
|
||||||
@@ -710,6 +734,23 @@ void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct as
|
|||||||
bridge_channel->owed.dtmf_digit = '\0';
|
bridge_channel->owed.dtmf_digit = '\0';
|
||||||
orig_bridge->technology->write(orig_bridge, NULL, &frame);
|
orig_bridge->technology->write(orig_bridge, NULL, &frame);
|
||||||
}
|
}
|
||||||
|
if (bridge_channel->owed.t38_terminate) {
|
||||||
|
struct ast_control_t38_parameters t38_parameters = {
|
||||||
|
.request_response = AST_T38_TERMINATED,
|
||||||
|
};
|
||||||
|
struct ast_frame frame = {
|
||||||
|
.frametype = AST_FRAME_CONTROL,
|
||||||
|
.subclass.integer = AST_CONTROL_T38_PARAMETERS,
|
||||||
|
.data.ptr = &t38_parameters,
|
||||||
|
.datalen = sizeof(t38_parameters),
|
||||||
|
.src = "Bridge channel owed T.38 terminate",
|
||||||
|
};
|
||||||
|
|
||||||
|
ast_debug(1, "T.38 terminate simulated to bridge %s because %s left.\n",
|
||||||
|
orig_bridge->uniqueid, ast_channel_name(bridge_channel->chan));
|
||||||
|
bridge_channel->owed.t38_terminate = 0;
|
||||||
|
orig_bridge->technology->write(orig_bridge, NULL, &frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -2736,6 +2777,18 @@ int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel,
|
|||||||
ast_channel_sending_dtmf_tv(bridge_channel->chan), "bridge end");
|
ast_channel_sending_dtmf_tv(bridge_channel->chan), "bridge end");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Complete any T.38 session before exiting the bridge. */
|
||||||
|
if (ast_channel_is_t38_active(bridge_channel->chan)) {
|
||||||
|
struct ast_control_t38_parameters t38_parameters = {
|
||||||
|
.request_response = AST_T38_TERMINATED,
|
||||||
|
};
|
||||||
|
|
||||||
|
ast_debug(1, "Channel %s simulating T.38 terminate for bridge end.\n",
|
||||||
|
ast_channel_name(bridge_channel->chan));
|
||||||
|
ast_indicate_data(bridge_channel->chan, AST_CONTROL_T38_PARAMETERS,
|
||||||
|
&t38_parameters, sizeof(t38_parameters));
|
||||||
|
}
|
||||||
|
|
||||||
/* Indicate a source change since this channel is leaving the bridge system. */
|
/* Indicate a source change since this channel is leaving the bridge system. */
|
||||||
ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
|
ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
|
||||||
|
|
||||||
|
|||||||
@@ -4479,6 +4479,7 @@ static int indicate_data_internal(struct ast_channel *chan, int _condition, cons
|
|||||||
* in switch statements. */
|
* in switch statements. */
|
||||||
enum ast_control_frame_type condition = _condition;
|
enum ast_control_frame_type condition = _condition;
|
||||||
struct ast_tone_zone_sound *ts = NULL;
|
struct ast_tone_zone_sound *ts = NULL;
|
||||||
|
const struct ast_control_t38_parameters *t38_parameters;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
switch (condition) {
|
switch (condition) {
|
||||||
@@ -4498,6 +4499,22 @@ static int indicate_data_internal(struct ast_channel *chan, int _condition, cons
|
|||||||
case AST_CONTROL_UNHOLD:
|
case AST_CONTROL_UNHOLD:
|
||||||
ast_channel_hold_state_set(chan, _condition);
|
ast_channel_hold_state_set(chan, _condition);
|
||||||
break;
|
break;
|
||||||
|
case AST_CONTROL_T38_PARAMETERS:
|
||||||
|
t38_parameters = data;
|
||||||
|
switch (t38_parameters->request_response) {
|
||||||
|
case AST_T38_REQUEST_NEGOTIATE:
|
||||||
|
case AST_T38_NEGOTIATED:
|
||||||
|
ast_channel_set_is_t38_active_nolock(chan, 1);
|
||||||
|
break;
|
||||||
|
case AST_T38_REQUEST_TERMINATE:
|
||||||
|
case AST_T38_TERMINATED:
|
||||||
|
case AST_T38_REFUSED:
|
||||||
|
ast_channel_set_is_t38_active_nolock(chan, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user