return ZAP_BREAK;
}
+static void zap_enable_channel_dtmf(zap_channel_t *zchan, switch_channel_t *channel)
+{
+ if (channel) {
+ const char *var;
+ if ((var = switch_channel_get_variable(channel, "openzap_disable_dtmf"))) {
+ if (switch_true(var)) {
+ zap_channel_command(zchan, ZAP_COMMAND_DISABLE_DTMF_DETECT, NULL);
+ zap_log(ZAP_LOG_INFO, "DTMF detection disabled in channel %d:%d\n", zchan->span_id, zchan->chan_id);
+ return;
+ }
+ }
+ /* the variable is not present or has negative value then proceed to enable DTMF */
+ }
+ if (zap_channel_command(zchan, ZAP_COMMAND_ENABLE_DTMF_DETECT, NULL) != ZAP_SUCCESS) {
+ zap_log(ZAP_LOG_ERROR, "Failed to enable DTMF detection in channel %d:%d\n", zchan->span_id, zchan->chan_id);
+ }
+}
+
static ZIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
{
switch_core_session_t *session = NULL;
if ((session = zap_channel_get_session(sigmsg->channel, 0))) {
channel = switch_core_session_get_channel(session);
switch_channel_mark_answered(channel);
+ zap_enable_channel_dtmf(sigmsg->channel, channel);
switch_core_session_rwunlock(session);
}
}
if ((session = zap_channel_get_session(sigmsg->channel, 0))) {
channel = switch_core_session_get_channel(session);
switch_channel_mark_answered(channel);
+ zap_enable_channel_dtmf(sigmsg->channel, channel);
switch_core_session_rwunlock(session);
}
}
case ZAP_SIGEVENT_UP:
{
if ((session = zap_channel_get_session(sigmsg->channel, 0))) {
- zap_tone_type_t tt = ZAP_TONE_DTMF;
channel = switch_core_session_get_channel(session);
switch_channel_mark_answered(channel);
- if (zap_channel_command(sigmsg->channel, ZAP_COMMAND_ENABLE_DTMF_DETECT, &tt) != ZAP_SUCCESS) {
- zap_log(ZAP_LOG_ERROR, "Failed to enable DTMF detection in R2 channel %d:%d\n", sigmsg->channel->span_id, sigmsg->channel->chan_id);
- }
+ zap_enable_channel_dtmf(sigmsg->channel, channel);
switch_core_session_rwunlock(session);
}
}
switch(sigmsg->event_id) {
case ZAP_SIGEVENT_START:
{
- zap_tone_type_t tt = ZAP_TONE_DTMF;
-
- if (zap_channel_command(sigmsg->channel, ZAP_COMMAND_ENABLE_DTMF_DETECT, &tt) != ZAP_SUCCESS) {
- zap_log(ZAP_LOG_ERROR, "TONE ERROR\n");
- }
-
+ zap_enable_channel_dtmf(sigmsg->channel, channel);
return zap_channel_from_event(sigmsg, &session);
}
break;
case ZAP_SIGEVENT_UP:
{
if ((session = zap_channel_get_session(sigmsg->channel, 0))) {
- zap_tone_type_t tt = ZAP_TONE_DTMF;
channel = switch_core_session_get_channel(session);
switch_channel_mark_answered(channel);
- if (zap_channel_command(sigmsg->channel, ZAP_COMMAND_ENABLE_DTMF_DETECT, &tt) != ZAP_SUCCESS) {
- zap_log(ZAP_LOG_ERROR, "TONE ERROR\n");
- }
+ zap_enable_channel_dtmf(sigmsg->channel, channel);
switch_core_session_rwunlock(session);
} else {
const char *uuid = zap_channel_get_uuid(sigmsg->channel, 0);
err = sangoma_tdm_get_hw_dtmf(chan->sockfd, &tdm_api);
if (err > 0) {
- err = sangoma_tdm_enable_dtmf_events(chan->sockfd, &tdm_api);
- if (err == 0) {
- zap_channel_set_feature(chan, ZAP_CHANNEL_FEATURE_DTMF_DETECT);
- dtmf = "hardware";
- }
+ zap_channel_set_feature(chan, ZAP_CHANNEL_FEATURE_DTMF_DETECT);
+ dtmf = "hardware";
}
}
sangoma_wait_obj_delete(&sangoma_wait_obj);
}
#endif
-
if (zchan->sockfd != ZAP_INVALID_SOCKET) {
+ /* enable HW DTMF. As odd as it seems. Why enable when the channel is being destroyed and won't be used anymore?
+ * because that way we can transfer the DTMF state back to the driver, if we're being restarted we will set again
+ * the FEATURE_DTMF flag and use HW DTMF, if we don't enable here, then on module restart we won't see
+ * HW DTMF available and will use software */
+ if (zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_DETECT)) {
+ wanpipe_tdm_api_t tdm_api;
+ int err;
+ memset(&tdm_api, 0, sizeof(tdm_api));
+ err = sangoma_tdm_enable_dtmf_events(zchan->sockfd, &tdm_api);
+ if (err) {
+ zap_log(ZAP_LOG_WARNING, "Failed to enable Sangoma HW DTMF on channel %d:%d at destroy\n",
+ zchan->span_id, zchan->chan_id);
+ }
+ }
sangoma_close(&zchan->sockfd);
}