/*.on_hangup */ on_hangup,\r
/*.on_exchange_media */ FSConnection::on_exchange_media,\r
/*.on_soft_execute */ FSConnection::on_soft_execute,\r
- /*.on_consume_media*/ NULL,\r
- /*.on_hibernate*/ NULL,\r
- /*.on_reset*/ NULL,\r
- /*.on_park*/ NULL,\r
- /*.on_reporting*/ NULL,\r
- /*.on_destroy*/ on_destroy\r
+ /*.on_consume_media*/ NULL,\r
+ /*.on_hibernate*/ NULL,\r
+ /*.on_reset*/ NULL,\r
+ /*.on_park*/ NULL,\r
+ /*.on_reporting*/ NULL,\r
+ /*.on_destroy*/ on_destroy\r
};\r
\r
\r
\r
OpalLocalConnection *FSEndPoint::CreateConnection(OpalCall & call, void *userData)\r
{\r
- return new FSConnection(call, *this, (switch_caller_profile_t *)userData);\r
+ FSManager & mgr = (FSManager &) GetManager();\r
+ switch_core_session_t *fsSession = switch_core_session_request(mgr.GetSwitchInterface(), \r
+ (switch_caller_profile_t *)userData ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND, NULL);\r
+ if (fsSession == NULL)\r
+ return NULL;\r
+\r
+ switch_channel_t *fsChannel = switch_core_session_get_channel(fsSession);\r
+\r
+ if (fsChannel == NULL) {\r
+ switch_core_session_destroy(&fsSession);\r
+ return NULL;\r
+ }\r
+\r
+ return new FSConnection(call, *this, (switch_caller_profile_t *)userData, fsSession, fsChannel);\r
}\r
\r
\r
///////////////////////////////////////////////////////////////////////\r
\r
\r
-FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint, switch_caller_profile_t *outbound_profile)\r
+FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint, switch_caller_profile_t *outbound_profile, switch_core_session_t *fsSession, switch_channel_t *fsChannel)\r
: OpalLocalConnection(call, endpoint, NULL)\r
, m_endpoint(endpoint)\r
+ , m_fsSession(fsSession)\r
+ , m_fsChannel(fsChannel)\r
{\r
opal_private_t *tech_pvt;\r
- FSManager & mgr = (FSManager &) endpoint.GetManager();\r
- m_fsSession = switch_core_session_request(mgr.GetSwitchInterface(), \r
- outbound_profile ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND, NULL);\r
- m_fsChannel = switch_core_session_get_channel(m_fsSession);\r
\r
tech_pvt = (opal_private_t *) switch_core_session_alloc(m_fsSession, sizeof(*tech_pvt));\r
tech_pvt->me = this;\r
PBoolean FSConnection::SendUserInputTone(char tone, unsigned duration)\r
{\r
switch_dtmf_t dtmf = { tone, duration };\r
-\r
- return (switch_channel_queue_dtmf(m_fsChannel, &dtmf) == SWITCH_STATUS_SUCCESS) ? true : false;\r
+ return switch_channel_queue_dtmf(m_fsChannel, &dtmf) == SWITCH_STATUS_SUCCESS;\r
}\r
\r
OpalMediaFormatList FSConnection::GetMediaFormats() const\r
{\r
int numCodecs = 0;\r
const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS]; \r
- const char *codec_string = NULL, *abs, *ocodec;\r
+ const char *codec_string = NULL, *abs, *ocodec;\r
char *tmp_codec_string = NULL;\r
char *codec_order[SWITCH_MAX_CODECS];\r
int codec_order_last;\r
\r
\r
- if ((abs = switch_channel_get_variable(m_fsChannel, "absolute_codec_string"))) {\r
- codec_string = abs;\r
- } else {\r
- if ((abs = switch_channel_get_variable(m_fsChannel, "codec_string"))) {\r
+ if ((abs = switch_channel_get_variable(m_fsChannel, "absolute_codec_string"))) {\r
+ codec_string = abs;\r
+ } else {\r
+ if ((abs = switch_channel_get_variable(m_fsChannel, "codec_string"))) {\r
codec_string = abs;\r
- }\r
+ }\r
\r
- if ((ocodec = switch_channel_get_variable(m_fsChannel, SWITCH_ORIGINATOR_CODEC_VARIABLE))) {\r
+ if ((ocodec = switch_channel_get_variable(m_fsChannel, SWITCH_ORIGINATOR_CODEC_VARIABLE))) {\r
codec_string = switch_core_session_sprintf(m_fsSession, "%s,%s", ocodec, codec_string);\r
- }\r
- }\r
+ }\r
+ }\r
\r
if (!codec_string) {\r
codec_string = mod_opal_globals.codec_string;\r
}\r
\r
- if (codec_string) {\r
- if ((tmp_codec_string = strdup(codec_string))) {\r
- codec_order_last = switch_separate_string(tmp_codec_string, ',', codec_order, SWITCH_MAX_CODECS);\r
+ if (codec_string) {\r
+ if ((tmp_codec_string = strdup(codec_string))) {\r
+ codec_order_last = switch_separate_string(tmp_codec_string, ',', codec_order, SWITCH_MAX_CODECS);\r
numCodecs = switch_loadable_module_get_codecs_sorted(codecs, SWITCH_MAX_CODECS, codec_order, codec_order_last);\r
\r
- }\r
- } else {\r
- numCodecs = switch_loadable_module_get_codecs(codecs, sizeof(codecs) / sizeof(codecs[0]));\r
- }\r
+ }\r
+ } else {\r
+ numCodecs = switch_loadable_module_get_codecs(codecs, sizeof(codecs) / sizeof(codecs[0]));\r
+ }\r
\r
for (int i = 0; i < numCodecs; i++) {\r
const switch_codec_implementation_t *codec = codecs[i];\r
{\r
//switch_channel_t *channel = switch_core_session_get_channel(session);\r
opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session);\r
-\r
+ \r
if (tech_pvt) {\r
- if (tech_pvt->read_codec.implementation) {\r
- switch_core_codec_destroy(&tech_pvt->read_codec);\r
- }\r
+ if (tech_pvt->read_codec.implementation) {\r
+ switch_core_codec_destroy(&tech_pvt->read_codec);\r
+ }\r
\r
- if (tech_pvt->write_codec.implementation) {\r
- switch_core_codec_destroy(&tech_pvt->write_codec);\r
- }\r
+ if (tech_pvt->write_codec.implementation) {\r
+ switch_core_codec_destroy(&tech_pvt->write_codec);\r
+ }\r
\r
- if (tech_pvt->vid_read_codec.implementation) {\r
- switch_core_codec_destroy(&tech_pvt->vid_read_codec);\r
- }\r
+ if (tech_pvt->vid_read_codec.implementation) {\r
+ switch_core_codec_destroy(&tech_pvt->vid_read_codec);\r
+ }\r
\r
- if (tech_pvt->vid_write_codec.implementation) {\r
- switch_core_codec_destroy(&tech_pvt->vid_write_codec);\r
- }\r
+ if (tech_pvt->vid_write_codec.implementation) {\r
+ switch_core_codec_destroy(&tech_pvt->vid_write_codec);\r
+ }\r
\r
- if (tech_pvt->read_timer.timer_interface) {\r
- switch_core_timer_destroy(&tech_pvt->read_timer);\r
- }\r
+ if (tech_pvt->read_timer.timer_interface) {\r
+ switch_core_timer_destroy(&tech_pvt->read_timer);\r
+ }\r
\r
- if (tech_pvt->vid_read_timer.timer_interface) {\r
- switch_core_timer_destroy(&tech_pvt->vid_read_timer);\r
- }\r
+ if (tech_pvt->vid_read_timer.timer_interface) {\r
+ switch_core_timer_destroy(&tech_pvt->vid_read_timer);\r
+ }\r
}\r
\r
- return SWITCH_STATUS_SUCCESS;\r
+ return SWITCH_STATUS_SUCCESS;\r
}\r
\r
/* this function has to be called with the original session beause the FSConnection might already be destroyed and we \r
tech_pvt->me->ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX));\r
tech_pvt->me = NULL;\r
}\r
- \r
+\r
return SWITCH_STATUS_SUCCESS;\r
}\r
\r
OnAlerting();\r
break;\r
\r
+ case SWITCH_MESSAGE_INDICATE_DEFLECT:\r
+ {\r
+ char transfer_to[128] = "";\r
+ switch_set_string(transfer_to, msg->string_arg);\r
+ TransferConnection(transfer_to);\r
+ break;\r
+ }\r
+\r
case SWITCH_MESSAGE_INDICATE_PROGRESS:\r
case SWITCH_MESSAGE_INDICATE_ANSWER:\r
{\r
m_switchCodec->implementation->samples_per_packet,\r
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {\r
switch_core_codec_destroy(m_switchCodec);\r
+ m_switchCodec = NULL;\r
return false;\r
}\r
} else {\r
{\r
if (!IsOpen())\r
return false;\r
- \r
+\r
+ /* forget these FS will properly destroy them for us */\r
+\r
+ m_switchTimer = NULL;\r
+ m_switchCodec = NULL;\r
+\r
return OpalMediaStream::Close();\r
}\r
\r
return false;\r
}\r
\r
+bool FSMediaStream::CheckPatchAndLock()\r
+{\r
+ if (GetConnection().GetPhase() >= GetConnection().ReleasingPhase || !IsOpen())\r
+ return false;\r
+\r
+ if (LockReadWrite()) {\r
+ if (!GetPatch() || !IsOpen()) {\r
+ UnlockReadWrite();\r
+ return false;\r
+ }\r
+ return true;\r
+ } else {\r
+ return false;\r
+ }\r
+}\r
\r
switch_status_t FSMediaStream::read_frame(switch_frame_t **frame, switch_io_flag_t flags)\r
{\r
while(!GetPatch()) {\r
switch_cond_next();\r
}\r
- GetPatch()->OnPatchStart();\r
- m_callOnStart = false;\r
+ if (CheckPatchAndLock()) {\r
+ GetPatch()->OnPatchStart();\r
+ m_callOnStart = false;\r
+ UnlockReadWrite();\r
+ } else {\r
+ return SWITCH_STATUS_FALSE; \r
+ }\r
}\r
\r
m_readFrame.flags = 0;\r
\r
/*\r
while (switch_channel_ready(m_fsChannel)) {\r
- if (!GetPatch()->GetSource().ReadPacket(m_readRTP)) {\r
- return SWITCH_STATUS_FALSE;\r
+ if (CheckPatchAndLock()) {\r
+ if (!GetPatch()->GetSource().ReadPacket(m_readRTP)) {\r
+ UnlockReadWrite();\r
+ return SWITCH_STATUS_FALSE;\r
+ } \r
+ UnlockReadWrite();\r
+ } else {\r
+ return SWITCH_STATUS_FALSE; \r
}\r
\r
if ((m_readFrame.datalen = m_readRTP.GetPayloadSize()) || switch_core_timer_check(&m_switchTimer, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {\r
if (switch_channel_test_private_flag(m_fsChannel, CF_NEED_FLUSH)) {\r
switch_channel_clear_private_flag(m_fsChannel, CF_NEED_FLUSH);\r
for(;;) {\r
- if (!GetPatch()->GetSource().ReadPacket(m_readRTP)) {\r
- return SWITCH_STATUS_FALSE;\r
+ if (CheckPatchAndLock()) {\r
+ if (!GetPatch()->GetSource().ReadPacket(m_readRTP)) {\r
+ UnlockReadWrite();\r
+ return SWITCH_STATUS_FALSE;\r
+ } \r
+ UnlockReadWrite();\r
+ } else {\r
+ return SWITCH_STATUS_FALSE; \r
}\r
+\r
if (!m_readRTP.GetPayloadSize()) {\r
m_readFrame.flags = SFF_CNG;\r
break;\r
}\r
} else {\r
\r
- if (!m_switchTimer || !GetPatch()->GetSource().ReadPacket(m_readRTP)) {\r
- return SWITCH_STATUS_FALSE;\r
+ if (CheckPatchAndLock()) {\r
+ if (!m_switchTimer || !GetPatch()->GetSource().ReadPacket(m_readRTP)) {\r
+ UnlockReadWrite();\r
+ return SWITCH_STATUS_FALSE;\r
+ } \r
+ UnlockReadWrite();\r
+ } else {\r
+ return SWITCH_STATUS_FALSE; \r
}\r
\r
switch_core_timer_next(m_switchTimer);\r
}\r
\r
if (m_callOnStart) {\r
- GetPatch()->OnPatchStart();\r
- m_callOnStart = false;\r
+ if (CheckPatchAndLock()) {\r
+ GetPatch()->OnPatchStart();\r
+ m_callOnStart = false;\r
+ UnlockReadWrite();\r
+ } else {\r
+ return SWITCH_STATUS_FALSE; \r
+ }\r
}\r
\r
if ((frame->flags & SFF_CNG)) {\r
\r
if ((frame->flags & SFF_RAW_RTP) != 0) {\r
RTP_DataFrame rtp((const BYTE *) frame->packet, frame->packetlen, false);\r
- if (GetPatch()->PushFrame(rtp)) {\r
- return SWITCH_STATUS_SUCCESS;\r
+\r
+ if (CheckPatchAndLock()) {\r
+ if (GetPatch()->PushFrame(rtp)) {\r
+ UnlockReadWrite();\r
+ return SWITCH_STATUS_SUCCESS;\r
+ }\r
+ UnlockReadWrite();\r
+ } else {\r
+ return SWITCH_STATUS_FALSE; \r
}\r
} \r
\r
\r
memcpy(rtp.GetPayloadPtr(), frame->data, frame->datalen);\r
\r
- if (GetPatch()->PushFrame(rtp)) {\r
- return SWITCH_STATUS_SUCCESS;\r
+ if (CheckPatchAndLock()) {\r
+ if (GetPatch()->PushFrame(rtp)) {\r
+ UnlockReadWrite();\r
+ return SWITCH_STATUS_SUCCESS;\r
+ }\r
+ UnlockReadWrite();\r
+ } else {\r
+ return SWITCH_STATUS_FALSE; \r
}\r
\r
\r