#define kCHAN_ID "chan"
#define kSPAN_NAME "span_name"
#define kPREBUFFER_LEN "prebuffer_len"
+#define kECHOCANCEL "echo_cancel"
+
static struct {
switch_memory_pool_t *pool;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
return SWITCH_STATUS_GENERR;
}
+
+ if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to set enable echo cancellation.\n");
+ }
switch(codec) {
case FTDM_CODEC_ULAW:
ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
if ((tech_pvt = switch_core_session_get_private(session))) {
+
+ if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to enable echo cancellation.\n");
+ }
if (tech_pvt->read_codec.implementation) {
switch_core_codec_destroy(&tech_pvt->read_codec);
const char *command = switch_event_get_header(event, "command");
ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
- if (!zstr(command) && !strcasecmp(command, kPREBUFFER_LEN)) {
- const char *szval = switch_event_get_header(event, kPREBUFFER_LEN);
- int val = !zstr(szval) ? atoi(szval) : 0;
+ if (!zstr(command)) {
+ if (!strcasecmp(command, kPREBUFFER_LEN)) {
+ const char *szval = switch_event_get_header(event, kPREBUFFER_LEN);
+ int val = !zstr(szval) ? atoi(szval) : 0;
- if (tech_pvt->prebuffer_len == val) {
- tech_pvt->prebuffer_len = val;
- if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
- return SWITCH_STATUS_GENERR;
- }
- }
+ if (tech_pvt->prebuffer_len == val) {
+ tech_pvt->prebuffer_len = val;
+ if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
+ return SWITCH_STATUS_GENERR;
+ }
+ }
+ } else if (!strcasecmp(command, kECHOCANCEL)) {
+ const char *szval = switch_event_get_header(event, kECHOCANCEL);
+ int enabled = !!switch_true(szval);
+
+ if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, enabled ? FTDM_COMMAND_ENABLE_ECHOCANCEL : FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to %s echo cancellation.\n", enable ? "enable" : "disable");
+ }
+ }
}
-
return SWITCH_STATUS_SUCCESS;
}
switch_event_destroy(&event);
}
+
+void mg_term_set_ec(mg_termination_t *term, int enable)
+{
+ switch_event_t *event = NULL, *event2 = NULL;
+ switch_core_session_t *session, *session2;
+
+ if (!zstr(term->uuid) && (session = switch_core_session_locate(term->uuid))) {
+ switch_event_create(&event, SWITCH_EVENT_CLONE);
+
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "command", kECHOCANCEL);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, kECHOCANCEL, enable ? "true" : "false");
+
+ /* Propagate event to bridged session if there is one */
+ if (switch_core_session_get_partner(session, &session2) == SWITCH_STATUS_SUCCESS) {
+ switch_event_dup(&event2, event);
+ switch_core_session_receive_event(session2, &event2);
+ switch_core_session_rwunlock(session2);
+ }
+
+ switch_core_session_receive_event(session, &event);
+ switch_core_session_rwunlock(session);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sent echo_cancel event to [%s] to [%s]\n", term->uuid, enable ? "enable" : "disable");
+ }
+
+ switch_event_destroy(&event);
+}
+
/* For Emacs:
* Local Variables:
* mode:c
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "mg_notify called on a non-supported channel.\n");
return;
}
-
+
if (!strcmp(data, "cng")) {
mg_send_t38_cng_notify(term->profile, term->name);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sent CNG notify\n");
+ /* Disable echo cancellation */
+ mg_term_set_ec(term, 0);
} else if (!strcmp(data, "ced")) {
- mg_send_t38_ans_notify(term->profile, term->name);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sent CED notify\n");
+ mg_send_t38_ans_notify(term->profile, term->name);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sent CED notify\n");
+ /* Disable echo cancellation */
+ mg_term_set_ec(term, 0);
}
}
#define kCHAN_ID "chan"
#define kSPAN_NAME "span_name"
#define kPREBUFFER_LEN "prebuffer_len"
+#define kECHOCANCEL "echo_cancel"
typedef struct mg_termination_s mg_termination_t;
uint32_t mg_rtp_request_id(megaco_profile_t *profile);
void mg_rtp_release_id(megaco_profile_t *profile, uint32_t id);
void mg_term_set_pre_buffer_size(mg_termination_t *term, int newval);
+void mg_term_set_ec(mg_termination_t *term, int enable);
mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id);
mg_context_t *megaco_choose_context(megaco_profile_t *profile);