[Core] switch_ivr: Restrict the misuse of uuid_hold API. Add switch_hold unit-test.
This commit is contained in:
parent
6040f3bf48
commit
fcaaf20c7d
|
@ -7896,6 +7896,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||||
switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid");
|
switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid");
|
||||||
switch_console_set_complete("add uuid_getvar ::console::list_uuid");
|
switch_console_set_complete("add uuid_getvar ::console::list_uuid");
|
||||||
switch_console_set_complete("add uuid_hold ::console::list_uuid");
|
switch_console_set_complete("add uuid_hold ::console::list_uuid");
|
||||||
|
switch_console_set_complete("add uuid_hold off ::console::list_uuid");
|
||||||
|
switch_console_set_complete("add uuid_hold toggle ::console::list_uuid");
|
||||||
switch_console_set_complete("add uuid_send_info ::console::list_uuid");
|
switch_console_set_complete("add uuid_send_info ::console::list_uuid");
|
||||||
switch_console_set_complete("add uuid_jitterbuffer ::console::list_uuid");
|
switch_console_set_complete("add uuid_jitterbuffer ::console::list_uuid");
|
||||||
switch_console_set_complete("add uuid_kill ::console::list_uuid");
|
switch_console_set_complete("add uuid_kill ::console::list_uuid");
|
||||||
|
|
|
@ -1530,6 +1530,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_hold(switch_core_session_t *session,
|
||||||
const char *other_uuid;
|
const char *other_uuid;
|
||||||
switch_event_t *event;
|
switch_event_t *event;
|
||||||
|
|
||||||
|
if (channel) {
|
||||||
|
switch_channel_callstate_t callstate;
|
||||||
|
|
||||||
|
callstate = switch_channel_get_callstate(channel);
|
||||||
|
if (callstate == CCS_HELD) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Call is already on hold. No need to hold again.\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msg.message_id = SWITCH_MESSAGE_INDICATE_HOLD;
|
msg.message_id = SWITCH_MESSAGE_INDICATE_HOLD;
|
||||||
msg.string_arg = message;
|
msg.string_arg = message;
|
||||||
msg.from = __FILE__;
|
msg.from = __FILE__;
|
||||||
|
@ -1557,13 +1567,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_hold(switch_core_session_t *session,
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_hold_uuid(const char *uuid, const char *message, switch_bool_t moh)
|
SWITCH_DECLARE(switch_status_t) switch_ivr_hold_uuid(const char *uuid, const char *message, switch_bool_t moh)
|
||||||
{
|
{
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
if ((session = switch_core_session_locate(uuid))) {
|
if ((session = switch_core_session_locate(uuid))) {
|
||||||
switch_ivr_hold(session, message, moh);
|
status = switch_ivr_hold(session, message, moh);
|
||||||
switch_core_session_rwunlock(session);
|
switch_core_session_rwunlock(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_hold_toggle_uuid(const char *uuid, const char *message, switch_bool_t moh)
|
SWITCH_DECLARE(switch_status_t) switch_ivr_hold_toggle_uuid(const char *uuid, const char *message, switch_bool_t moh)
|
||||||
|
@ -1571,21 +1582,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_hold_toggle_uuid(const char *uuid, co
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
switch_channel_t *channel;
|
switch_channel_t *channel;
|
||||||
switch_channel_callstate_t callstate;
|
switch_channel_callstate_t callstate;
|
||||||
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
if ((session = switch_core_session_locate(uuid))) {
|
if ((session = switch_core_session_locate(uuid))) {
|
||||||
if ((channel = switch_core_session_get_channel(session))) {
|
if ((channel = switch_core_session_get_channel(session))) {
|
||||||
callstate = switch_channel_get_callstate(channel);
|
callstate = switch_channel_get_callstate(channel);
|
||||||
|
|
||||||
if (callstate == CCS_ACTIVE) {
|
if (callstate == CCS_ACTIVE || callstate == CCS_UNHELD) {
|
||||||
switch_ivr_hold(session, message, moh);
|
status = switch_ivr_hold(session, message, moh);
|
||||||
} else if (callstate == CCS_HELD) {
|
} else if (callstate == CCS_HELD) {
|
||||||
switch_ivr_unhold(session);
|
status = switch_ivr_unhold(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch_core_session_rwunlock(session);
|
switch_core_session_rwunlock(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_unhold(switch_core_session_t *session)
|
SWITCH_DECLARE(switch_status_t) switch_ivr_unhold(switch_core_session_t *session)
|
||||||
|
@ -1596,6 +1608,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_unhold(switch_core_session_t *session
|
||||||
switch_core_session_t *b_session;
|
switch_core_session_t *b_session;
|
||||||
switch_event_t *event;
|
switch_event_t *event;
|
||||||
|
|
||||||
|
if (channel) {
|
||||||
|
switch_channel_callstate_t callstate;
|
||||||
|
|
||||||
|
callstate = switch_channel_get_callstate(channel);
|
||||||
|
if (callstate != CCS_HELD) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Call is not on hold. No need to unhold.\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msg.message_id = SWITCH_MESSAGE_INDICATE_UNHOLD;
|
msg.message_id = SWITCH_MESSAGE_INDICATE_UNHOLD;
|
||||||
msg.from = __FILE__;
|
msg.from = __FILE__;
|
||||||
|
|
||||||
|
@ -1624,13 +1646,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_unhold(switch_core_session_t *session
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_unhold_uuid(const char *uuid)
|
SWITCH_DECLARE(switch_status_t) switch_ivr_unhold_uuid(const char *uuid)
|
||||||
{
|
{
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
if ((session = switch_core_session_locate(uuid))) {
|
if ((session = switch_core_session_locate(uuid))) {
|
||||||
switch_ivr_unhold(session);
|
status = switch_ivr_unhold(session);
|
||||||
switch_core_session_rwunlock(session);
|
switch_core_session_rwunlock(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ switch_core_video
|
||||||
switch_eavesdrop
|
switch_eavesdrop
|
||||||
switch_event
|
switch_event
|
||||||
switch_hash
|
switch_hash
|
||||||
|
switch_hold
|
||||||
switch_ivr_async
|
switch_ivr_async
|
||||||
switch_ivr_originate
|
switch_ivr_originate
|
||||||
switch_ivr_play_say
|
switch_ivr_play_say
|
||||||
|
|
|
@ -4,6 +4,7 @@ noinst_PROGRAMS = switch_event switch_hash switch_ivr_originate switch_utils swi
|
||||||
switch_ivr_play_say switch_core_codec switch_rtp switch_xml
|
switch_ivr_play_say switch_core_codec switch_rtp switch_xml
|
||||||
noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_packetizer switch_core_session test_sofia switch_ivr_async switch_core_asr switch_log
|
noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_packetizer switch_core_session test_sofia switch_ivr_async switch_core_asr switch_log
|
||||||
|
|
||||||
|
noinst_PROGRAMS+= switch_hold
|
||||||
AM_LDFLAGS += -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS)
|
AM_LDFLAGS += -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS)
|
||||||
AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
|
AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<document type="freeswitch/xml">
|
||||||
|
<X-PRE-PROCESS cmd="exec-set" data="test=echo 1234"/>
|
||||||
|
<X-PRE-PROCESS cmd="set" data="default_password=$${test}"/>
|
||||||
|
<X-PRE-PROCESS cmd="set" data="core_video_blank_image=$${conf_dir}/freeswitch-logo.png"/>
|
||||||
|
<section name="configuration" description="Various Configuration">
|
||||||
|
<configuration name="modules.conf" description="Modules">
|
||||||
|
<modules>
|
||||||
|
<load module="mod_sofia"/>
|
||||||
|
<load module="mod_console"/>
|
||||||
|
<load module="mod_loopback"/>
|
||||||
|
<load module="mod_commands"/>
|
||||||
|
<load module="mod_dptools"/>
|
||||||
|
<load module="mod_dialplan_xml"/>
|
||||||
|
<load module="mod_tone_stream"/>
|
||||||
|
<load module="mod_commands"/>
|
||||||
|
<load module="mod_sndfile"/>
|
||||||
|
</modules>
|
||||||
|
</configuration>
|
||||||
|
|
||||||
|
<configuration name="console.conf" description="Console Logger">
|
||||||
|
<mappings>
|
||||||
|
<map name="all" value="console,debug,info,notice,warning,err,crit,alert"/>
|
||||||
|
</mappings>
|
||||||
|
<settings>
|
||||||
|
<param name="colorize" value="true"/>
|
||||||
|
<param name="loglevel" value="debug"/>
|
||||||
|
</settings>
|
||||||
|
</configuration>
|
||||||
|
|
||||||
|
<configuration name="timezones.conf" description="Timezones">
|
||||||
|
<timezones>
|
||||||
|
<zone name="GMT" value="GMT0" />
|
||||||
|
</timezones>
|
||||||
|
</configuration>
|
||||||
|
|
||||||
|
<configuration name="sofia.conf" description="SofiaSIP">
|
||||||
|
<profiles>
|
||||||
|
<profile name="external">
|
||||||
|
<gateways>
|
||||||
|
|
||||||
|
<gateway name="hold_unhold_test">
|
||||||
|
<param name="username" value="not-used"/>
|
||||||
|
<param name="password" value="not-used"/>
|
||||||
|
<param name="proxy" value="$${local_ip_v4}:61068"/>
|
||||||
|
<param name="register" value="false"/>
|
||||||
|
<param name="retry-seconds" value="30"/>
|
||||||
|
<param name="dtmf-type" value="rfc2833"/>
|
||||||
|
<variables>
|
||||||
|
<variable name="rtp_secure_media" value="false" direction="outbound"/>
|
||||||
|
</variables>
|
||||||
|
</gateway>
|
||||||
|
</gateways>
|
||||||
|
|
||||||
|
<domains>
|
||||||
|
<domain name="all" alias="false" parse="true"/>
|
||||||
|
</domains>
|
||||||
|
|
||||||
|
<settings>
|
||||||
|
<param name="debug" value="1"/>
|
||||||
|
<param name="shutdown-on-fail" value="true"/>
|
||||||
|
<param name="p-asserted-id-parse" value="verbatim"/>
|
||||||
|
<param name="username" value="SignalWire-STACK"/>
|
||||||
|
<param name="user-agent-string" value="SignalWire STACK Unit Test"/>
|
||||||
|
<param name="sip-trace" value="yes"/>
|
||||||
|
<param name="sip-capture" value="no"/>
|
||||||
|
<param name="rfc2833-pt" value="101"/>
|
||||||
|
<param name="sip-port" value="61068"/>
|
||||||
|
<param name="dialplan" value="XML"/>
|
||||||
|
<param name="context" value="default"/>
|
||||||
|
<param name="dtmf-duration" value="2000"/>
|
||||||
|
<param name="inbound-codec-prefs" value="PCMU"/>
|
||||||
|
<param name="outbound-codec-prefs" value="PCMU"/>
|
||||||
|
<param name="rtp-timer-name" value="soft"/>
|
||||||
|
<param name="local-network-acl" value="localnet.auto"/>
|
||||||
|
<param name="manage-presence" value="false"/>
|
||||||
|
<param name="inbound-codec-negotiation" value="generous"/>
|
||||||
|
<param name="nonce-ttl" value="60"/>
|
||||||
|
<param name="inbound-late-negotiation" value="true"/>
|
||||||
|
<param name="inbound-zrtp-passthru" value="false"/>
|
||||||
|
<param name="rtp-ip" value="$${local_ip_v4}"/>
|
||||||
|
<param name="sip-ip" value="$${local_ip_v4}"/>
|
||||||
|
<param name="ext-rtp-ip" value="$${local_ip_v4}"/>
|
||||||
|
<param name="ext-sip-ip" value="$${local_ip_v4}"/>
|
||||||
|
<param name="rtp-timeout-sec" value="300"/>
|
||||||
|
<param name="rtp-hold-timeout-sec" value="1800"/>
|
||||||
|
<param name="session-timeout" value="600"/>
|
||||||
|
<param name="minimum-session-expires" value="90"/>
|
||||||
|
<param name="tls" value="false"/>
|
||||||
|
</settings>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile name="internal">
|
||||||
|
<gateways>
|
||||||
|
</gateways>
|
||||||
|
|
||||||
|
<domains>
|
||||||
|
<domain name="all" alias="false" parse="true"/>
|
||||||
|
</domains>
|
||||||
|
|
||||||
|
<settings>
|
||||||
|
<param name="debug" value="1"/>
|
||||||
|
<param name="shutdown-on-fail" value="true"/>
|
||||||
|
<param name="p-asserted-id-parse" value="verbatim"/>
|
||||||
|
<param name="username" value="SignalWire-STACK"/>
|
||||||
|
<param name="user-agent-string" value="SignalWire STACK Unit Test"/>
|
||||||
|
<param name="sip-trace" value="yes"/>
|
||||||
|
<param name="sip-capture" value="no"/>
|
||||||
|
<param name="rfc2833-pt" value="101"/>
|
||||||
|
<param name="sip-port" value="61069"/>
|
||||||
|
<param name="dialplan" value="XML"/>
|
||||||
|
<param name="context" value="default"/>
|
||||||
|
<param name="dtmf-duration" value="2000"/>
|
||||||
|
<param name="inbound-codec-prefs" value="PCMU"/>
|
||||||
|
<param name="outbound-codec-prefs" value="PCMU"/>
|
||||||
|
<param name="rtp-timer-name" value="soft"/>
|
||||||
|
<param name="local-network-acl" value="localnet.auto"/>
|
||||||
|
<param name="manage-presence" value="false"/>
|
||||||
|
<param name="inbound-codec-negotiation" value="generous"/>
|
||||||
|
<param name="nonce-ttl" value="60"/>
|
||||||
|
<param name="inbound-late-negotiation" value="true"/>
|
||||||
|
<param name="inbound-zrtp-passthru" value="false"/>
|
||||||
|
<param name="rtp-ip" value="$${local_ip_v4}"/>
|
||||||
|
<param name="sip-ip" value="$${local_ip_v4}"/>
|
||||||
|
<param name="ext-rtp-ip" value="$${local_ip_v4}"/>
|
||||||
|
<param name="ext-sip-ip" value="$${local_ip_v4}"/>
|
||||||
|
<param name="rtp-timeout-sec" value="300"/>
|
||||||
|
<param name="rtp-hold-timeout-sec" value="1800"/>
|
||||||
|
<param name="session-timeout" value="600"/>
|
||||||
|
<param name="minimum-session-expires" value="90"/>
|
||||||
|
<param name="tls" value="false"/>
|
||||||
|
</settings>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
</profiles>
|
||||||
|
</configuration>
|
||||||
|
|
||||||
|
<configuration name="switch.conf" description="Switch">
|
||||||
|
<param name="rtp-start-port" value="20000"/>
|
||||||
|
<param name="rtp-end-port" value="30000"/>
|
||||||
|
<param name="threaded-system-exec" value="true"/>
|
||||||
|
</configuration>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section name="dialplan" description="Regex/XML Dialplan">
|
||||||
|
<context name="default">
|
||||||
|
<extension name="one">
|
||||||
|
<condition field="destination_number" expression="^\+15553332900$">
|
||||||
|
<action application="set" data="absolute_codec_string=PCMU@20i"/>
|
||||||
|
<action application="info"/>
|
||||||
|
<action application="answer"/>
|
||||||
|
<action application="park""/>
|
||||||
|
</condition>
|
||||||
|
</extension>
|
||||||
|
</context>
|
||||||
|
</section>
|
||||||
|
</document>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<include/>
|
||||||
|
<gateway name="hold_unhold_test">
|
||||||
|
<param name="username" value="not-used"/>
|
||||||
|
<param name="password" value="not-used"/>
|
||||||
|
<param name="proxy" value="127.0.0.1"/>
|
||||||
|
<param name="register" value="false"/>
|
||||||
|
<param name="retry-seconds" value="30"/>
|
||||||
|
<param name="dtmf-type" value="rfc2833"/>
|
||||||
|
<variables>
|
||||||
|
<variable name="rtp_secure_media" value="false" direction="outbound"/>
|
||||||
|
</variables>
|
||||||
|
</gateway>
|
||||||
|
</include>
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
#include <switch.h>
|
||||||
|
#include <test/switch_test.h>
|
||||||
|
|
||||||
|
FST_CORE_DB_BEGIN("./conf_hold")
|
||||||
|
{
|
||||||
|
FST_SUITE_BEGIN(switch_hold)
|
||||||
|
{
|
||||||
|
FST_SETUP_BEGIN()
|
||||||
|
{
|
||||||
|
fst_requires_module("mod_sofia");
|
||||||
|
fst_requires_module("mod_commands");
|
||||||
|
}
|
||||||
|
FST_SETUP_END()
|
||||||
|
|
||||||
|
FST_TEARDOWN_BEGIN()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
FST_TEARDOWN_END()
|
||||||
|
|
||||||
|
FST_TEST_BEGIN(hold_unhold_restriction)
|
||||||
|
{
|
||||||
|
switch_core_session_t *session = NULL;
|
||||||
|
switch_status_t status;
|
||||||
|
switch_call_cause_t cause;
|
||||||
|
|
||||||
|
status = switch_ivr_originate(NULL, &session, &cause, "{ignore_early_media=true}sofia/gateway/hold_unhold_test/+15553332900", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
|
||||||
|
fst_requires(session);
|
||||||
|
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
const char *uuid = switch_core_session_get_uuid(session);
|
||||||
|
switch_channel_t *channel = NULL;
|
||||||
|
|
||||||
|
channel = switch_core_session_get_channel(session);
|
||||||
|
fst_requires(channel);
|
||||||
|
|
||||||
|
if (uuid) {
|
||||||
|
char *off_uuid = switch_mprintf("off %s", uuid);
|
||||||
|
char *toggle_uuid = switch_mprintf("toggle %s", uuid);
|
||||||
|
|
||||||
|
switch_stream_handle_t stream = { 0 };
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "firing the api.\n");
|
||||||
|
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_hold", off_uuid, NULL, &stream);
|
||||||
|
fst_check_string_equals(stream.data, "-ERR Operation failed\n");
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
switch_sleep(200000);
|
||||||
|
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_hold", uuid, NULL, &stream);
|
||||||
|
fst_check_string_equals(stream.data, "+OK Success\n");
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
switch_sleep(200000);
|
||||||
|
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_hold", uuid, NULL, &stream);
|
||||||
|
fst_check_string_equals(stream.data, "-ERR Operation failed\n");
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
switch_sleep(200000);
|
||||||
|
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_hold", uuid, NULL, &stream);
|
||||||
|
fst_check_string_equals(stream.data, "-ERR Operation failed\n");
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
switch_sleep(200000);
|
||||||
|
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_hold", toggle_uuid, NULL, &stream);
|
||||||
|
fst_check_string_equals(stream.data, "+OK Success\n");
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
switch_sleep(200000);
|
||||||
|
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_hold", off_uuid, NULL, &stream);
|
||||||
|
fst_check_string_equals(stream.data, "-ERR Operation failed\n");
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
switch_sleep(200000);
|
||||||
|
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_hold", toggle_uuid, NULL, &stream);
|
||||||
|
fst_check_string_equals(stream.data, "+OK Success\n");
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
switch_sleep(200000);
|
||||||
|
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_hold", uuid, NULL, &stream);
|
||||||
|
fst_check_string_equals(stream.data, "-ERR Operation failed\n");
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
switch_sleep(200000);
|
||||||
|
|
||||||
|
switch_safe_free(off_uuid);
|
||||||
|
switch_safe_free(toggle_uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||||
|
switch_core_session_rwunlock(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FST_TEST_END()
|
||||||
|
}
|
||||||
|
FST_SUITE_END()
|
||||||
|
}
|
||||||
|
FST_CORE_END()
|
||||||
|
|
Loading…
Reference in New Issue