mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 03:20:57 +00:00
When a T.38 happens immediatly after call establishment, the control frame can be lost because the other leg is not yet in the bridge. This patch detects this case an makes sure T.38 negotation happens when the 2nd leg is being made compatible with the negotating first leg ASTERISK-26923 #close Change-Id: If334125ee61ed63550d242fc9efe7987e37e1d94
104 lines
3.1 KiB
C
104 lines
3.1 KiB
C
/*
|
|
* Asterisk -- An open source telephony toolkit.
|
|
*
|
|
* Copyright (C) 2007, Digium, Inc.
|
|
*
|
|
* Joshua Colp <jcolp@digium.com>
|
|
*
|
|
* See http://www.asterisk.org for more information about
|
|
* the Asterisk project. Please do not directly contact
|
|
* any of the maintainers of this project for assistance;
|
|
* the project provides a web site, mailing lists and IRC
|
|
* channels for your use.
|
|
*
|
|
* This program is free software, distributed under the terms of
|
|
* the GNU General Public License Version 2. See the LICENSE file
|
|
* at the top of the source tree.
|
|
*/
|
|
|
|
/*! \file
|
|
*
|
|
* \brief Simple two channel bridging module
|
|
*
|
|
* \author Joshua Colp <jcolp@digium.com>
|
|
*
|
|
* \ingroup bridges
|
|
*/
|
|
|
|
/*** MODULEINFO
|
|
<support_level>core</support_level>
|
|
***/
|
|
|
|
#include "asterisk.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "asterisk/module.h"
|
|
#include "asterisk/channel.h"
|
|
#include "asterisk/bridge.h"
|
|
#include "asterisk/bridge_technology.h"
|
|
#include "asterisk/frame.h"
|
|
|
|
static int simple_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
|
|
{
|
|
struct ast_channel *c0 = AST_LIST_FIRST(&bridge->channels)->chan;
|
|
struct ast_channel *c1 = AST_LIST_LAST(&bridge->channels)->chan;
|
|
|
|
/*
|
|
* If this is the first channel we can't make it compatible...
|
|
* unless we make it compatible with itself. O.o
|
|
*/
|
|
if (c0 == c1) {
|
|
return 0;
|
|
}
|
|
|
|
/* Request resend of T.38 negotiation if in progress and the other leg not yet T.38
|
|
*/
|
|
if (ast_channel_get_t38_state(c0) == T38_STATE_NEGOTIATING && ast_channel_get_t38_state(c1) == T38_STATE_UNKNOWN) {
|
|
struct ast_control_t38_parameters parameters = { .request_response = AST_T38_REQUEST_PARMS, };
|
|
ast_debug(3, "Sending T.38 param renegotiation to first channel %s.\n", ast_channel_name(c0));
|
|
ast_indicate_data(c0, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters));
|
|
}
|
|
if (ast_channel_get_t38_state(c1) == T38_STATE_NEGOTIATING && ast_channel_get_t38_state(c0) == T38_STATE_UNKNOWN) {
|
|
struct ast_control_t38_parameters parameters = { .request_response = AST_T38_REQUEST_PARMS, };
|
|
ast_debug(3, "Sending T.38 param renegotiation to second channel %s.\n", ast_channel_name(c1));
|
|
ast_indicate_data(c1, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters));
|
|
}
|
|
|
|
return ast_channel_make_compatible(c0, c1);
|
|
}
|
|
|
|
static int simple_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
|
|
{
|
|
return ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
|
|
}
|
|
|
|
static struct ast_bridge_technology simple_bridge = {
|
|
.name = "simple_bridge",
|
|
.capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX,
|
|
.preference = AST_BRIDGE_PREFERENCE_BASE_1TO1MIX,
|
|
.join = simple_bridge_join,
|
|
.write = simple_bridge_write,
|
|
};
|
|
|
|
static int unload_module(void)
|
|
{
|
|
ast_bridge_technology_unregister(&simple_bridge);
|
|
return 0;
|
|
}
|
|
|
|
static int load_module(void)
|
|
{
|
|
if (ast_bridge_technology_register(&simple_bridge)) {
|
|
unload_module();
|
|
return AST_MODULE_LOAD_DECLINE;
|
|
}
|
|
return AST_MODULE_LOAD_SUCCESS;
|
|
}
|
|
|
|
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Simple two channel bridging module");
|