spandsp_mod has set it us. So, if not, we actually give to spandsp_mod. */\r
switch_t38_options_t *t38_options = (switch_t38_options_t *)switch_channel_get_private(m_fsChannel, "t38_options");\r
if (t38_options == NULL)\r
- SetT38OptionsFromMediaFormat(t38);\r
+ SetT38OptionsFromMediaFormat(t38, "_preconfigured_t38_options");\r
else {\r
t38.SetOptionInteger("T38FaxVersion", t38_options->T38FaxVersion);\r
t38.SetOptionInteger("T38MaxBitRate", t38_options->T38MaxBitRate);\r
return;\r
\r
if (switch_channel_direction(m_fsChannel) == SWITCH_CALL_DIRECTION_INBOUND) {\r
- if (isSource)\r
- m_rxAudioOpened.Signal();\r
- else\r
- m_txAudioOpened.Signal();\r
+ if (isSource)\r
+ m_rxAudioOpened.Signal();\r
+ else\r
+ m_txAudioOpened.Signal();\r
}\r
else if (GetMediaStream(OpalMediaType::Audio(), !isSource) != NULL) {\r
- // Have open media in both directions.\r
+ // Have open media in both directions.\r
if (IsEstablished())\r
- switch_channel_mark_answered(m_fsChannel);\r
+ switch_channel_mark_answered(m_fsChannel);\r
else if (!IsReleased())\r
- switch_channel_mark_pre_answered(m_fsChannel);\r
- }\r
+ switch_channel_mark_pre_answered(m_fsChannel);\r
+ }\r
}\r
\r
\r
#if HAVE_T38\r
case SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA:\r
{\r
+ PTRACE(2, "mod_opal\tRequesting switch to T.38");\r
PSafePtr<OpalConnection> other = GetOtherPartyConnection();\r
- if (other == NULL || !other->SwitchT38(true)) {\r
+ if (other != NULL && other->SwitchT38(true))\r
+ switch_channel_set_flag(m_fsChannel, CF_REQ_MEDIA);\r
+ else {\r
PTRACE(1, "mod_opal\tMode change request to T.38 failed");\r
}\r
break;\r
}\r
\r
case SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION:\r
+ PTRACE(2, "mod_opal\tSWITCH_MESSAGE_INDICATE_T38_DESCRIPTION");\r
break;\r
\r
case SWITCH_MESSAGE_INDICATE_UDPTL_MODE:\r
+ PTRACE(2, "mod_opal\tSWITCH_MESSAGE_INDICATE_UDPTL_MODE");\r
break;\r
#endif // HAVE_T38\r
\r
\r
\r
#if HAVE_T38\r
-void FSConnection::SetT38OptionsFromMediaFormat(const OpalMediaFormat & mediaFormat)\r
+void FSConnection::SetT38OptionsFromMediaFormat(const OpalMediaFormat & mediaFormat, const char * varname)\r
{\r
- switch_t38_options_t *t38_options = (switch_t38_options_t *)switch_channel_get_private(m_fsChannel, "t38_options");\r
+ switch_t38_options_t *t38_options = (switch_t38_options_t *)switch_channel_get_private(m_fsChannel, varname);\r
if (t38_options == NULL)\r
t38_options = (switch_t38_options_t *)switch_core_session_alloc(m_fsSession, sizeof(switch_t38_options_t));\r
\r
//t38_options->remote_ip = switch_core_session_strdup(session, mediaFormat.something);\r
//t38_options->remote_port = mediaFormat.something;\r
\r
- switch_channel_set_private(m_fsChannel, "t38_options", t38_options);\r
+ switch_channel_set_private(m_fsChannel, varname, t38_options);\r
+ PTRACE(3, "mod_opal\tSet " << varname);\r
}\r
\r
\r
void FSConnection::OnSwitchedT38(bool toT38, bool success)\r
{\r
- PTRACE(3, "mod_opal\tMode change request to fax succeeded");\r
- OnSwitchingT38(toT38 && success);\r
+ if (!toT38 || !success || !IndicateSwitchedT38())\r
+ AbortT38();\r
}\r
\r
\r
void FSConnection::OnSwitchingT38(bool toT38)\r
{\r
- if (!toT38) {\r
- switch_channel_set_private(m_fsChannel, "t38_options", NULL);\r
- switch_channel_clear_app_flag_key("T38", m_fsChannel, CF_APP_T38);\r
- switch_channel_clear_app_flag_key("T38", m_fsChannel, CF_APP_T38_REQ);\r
- switch_channel_set_app_flag_key("T38", m_fsChannel, CF_APP_T38_FAIL);\r
- return;\r
- }\r
+ if (!toT38 || !IndicateSwitchedT38())\r
+ AbortT38();\r
+}\r
+\r
+\r
+void FSConnection::AbortT38()\r
+{\r
+ PTRACE(3, "mod_opal\tMode change request to T.38 failed");\r
+ switch_channel_set_private(m_fsChannel, "t38_options", NULL);\r
+ switch_channel_clear_app_flag_key("T38", m_fsChannel, CF_APP_T38);\r
+ switch_channel_clear_app_flag_key("T38", m_fsChannel, CF_APP_T38_REQ);\r
+ switch_channel_set_app_flag_key("T38", m_fsChannel, CF_APP_T38_FAIL);\r
+}\r
+\r
\r
+bool FSConnection::IndicateSwitchedT38()\r
+{\r
PSafePtr<OpalConnection> other = GetOtherPartyConnection();\r
if (other == NULL)\r
- return;\r
+ return false;\r
\r
OpalMediaFormatList otherFormats = other->GetMediaFormats();\r
OpalMediaFormatList::const_iterator t38 = otherFormats.FindFormat(OpalT38);\r
if (t38 == otherFormats.end())\r
- return;\r
+ return false;\r
\r
- SetT38OptionsFromMediaFormat(*t38);\r
+ SetT38OptionsFromMediaFormat(*t38, "t38_options");\r
\r
switch_channel_set_variable(m_fsChannel, "has_t38", "true");\r
switch_channel_set_app_flag_key("T38", m_fsChannel, CF_APP_T38);\r
\r
- switch_channel_execute_on(m_fsChannel, "opal_execute_on_image");\r
- switch_channel_api_on(m_fsChannel, "opal_api_on_image");\r
-\r
- return;\r
+ switch_channel_execute_on(m_fsChannel, "opal_execute_on_t38");\r
+ switch_channel_api_on(m_fsChannel, "opal_api_on_t38");\r
+ PTRACE(3, "mod_opal\tMode change request to T.38 succeeded");\r
+ return true;\r
}\r
#endif // HAVE_T38\r
\r
\r
switch_status_t FSConnection::read_audio_frame(switch_frame_t **frame, switch_io_flag_t flags, int stream_id)\r
{\r
- return read_frame(OpalMediaType::Audio(), frame, flags);\r
+ // Avoid all the channel closing and re-opening upsetting FS\r
+ if (ownerCall.IsSwitchingT38())\r
+ return SWITCH_STATUS_SUCCESS;\r
+\r
+ return read_frame((flags&SFF_UDPTL_PACKET) ? OpalMediaType::Fax() : OpalMediaType::Audio(), frame, flags);\r
}\r
\r
\r
switch_status_t FSConnection::write_audio_frame(switch_frame_t *frame, switch_io_flag_t flags, int stream_id)\r
{\r
- return write_frame(OpalMediaType::Audio(), frame, flags);\r
+ // Avoid all the channel closing and re-opening upsetting FS\r
+ if (ownerCall.IsSwitchingT38())\r
+ return SWITCH_STATUS_SUCCESS;\r
+\r
+ return write_frame((flags&SFF_UDPTL_PACKET) ? OpalMediaType::Fax() : OpalMediaType::Audio(), frame, flags);\r
}\r
\r
\r
switch_status_t FSConnection::read_frame(const OpalMediaType & mediaType, switch_frame_t **frame, switch_io_flag_t flags)\r
{\r
PSafePtr <FSMediaStream> stream = PSafePtrCast <OpalMediaStream, FSMediaStream>(GetMediaStream(mediaType, false));\r
- return stream != NULL ? stream->read_frame(frame, flags) : SWITCH_STATUS_FALSE;\r
+ if (stream != NULL)\r
+ return stream->read_frame(frame, flags);\r
+\r
+ PTRACE(2, "mod_opal\tNo stream for read of " << mediaType);\r
+ return SWITCH_STATUS_SUCCESS;\r
}\r
\r
\r
switch_status_t FSConnection::write_frame(const OpalMediaType & mediaType, const switch_frame_t *frame, switch_io_flag_t flags)\r
{\r
PSafePtr <FSMediaStream> stream = PSafePtrCast<OpalMediaStream, FSMediaStream>(GetMediaStream(mediaType, true));\r
- return stream != NULL ? stream->write_frame(frame, flags) : SWITCH_STATUS_FALSE;\r
+ if (stream != NULL)\r
+ return stream->write_frame(frame, flags);\r
+\r
+ PTRACE(2, "mod_opal\tNo stream for write of " << mediaType);\r
+ return SWITCH_STATUS_SUCCESS;\r
}\r
\r
\r
int FSMediaStream::StartReadWrite(PatchPtr & mediaPatch) const\r
{\r
if (!IsOpen()) {\r
- PTRACE(2, "mod_opal\tNot open!");\r
+ PTRACE(1, "mod_opal\tNot open!");\r
return -1;\r
}\r
\r
if (!m_switchCodec) {\r
- PTRACE(2, "mod_opal\tNo codec!");\r
+ PTRACE(1, "mod_opal\tNo codec!");\r
return -1;\r
}\r
\r
if (!m_connection.IsChannelReady()) {\r
- PTRACE(2, "mod_opal\tChannel not ready!");\r
+ PTRACE(1, "mod_opal\tChannel not ready!");\r
return -1;\r
}\r
\r
if (mediaPatch == NULL) {\r
/*There is a race here... sometimes we make it here and m_mediaPatch is NULL\r
if we wait it shows up in 1ms, maybe there is a better way to wait. */\r
- PTRACE(3, "mod_opal\tPatch not ready!");\r
+ PTRACE(2, "mod_opal\tPatch not ready!");\r
return 1;\r
}\r
\r
m_readRTP.SetTimestamp(m_readFrame.timestamp + m_switchCodec->implementation->samples_per_packet);\r
\r
if (!mediaPatch->GetSource().ReadPacket(m_readRTP)) {\r
+ PTRACE(1, "mod_opal\tread_frame: no source data!");\r
return SWITCH_STATUS_FALSE;\r
}\r
}\r
\r
if (m_switchCodec != NULL) {\r
if (!switch_core_codec_ready(m_switchCodec)) {\r
- PTRACE(2, "mod_opal\tread_frame: codec not ready!");\r
+ PTRACE(1, "mod_opal\tread_frame: codec not ready!");\r
return SWITCH_STATUS_FALSE;\r
}\r
}\r
timestamp += m_switchCodec->implementation->samples_per_packet;\r
rtp.SetTimestamp(timestamp);\r
\r
- return mediaPatch->PushFrame(rtp) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;\r
+ if (mediaPatch->PushFrame(rtp))\r
+ return SWITCH_STATUS_SUCCESS;\r
+\r
+ PTRACE(1, "mod_opal\tread_frame: push failed!");\r
+ return SWITCH_STATUS_FALSE;\r
}\r
\r
\r