FS-5865 --resolve mod_rayo: fix join/unjoin IQ result for mixers
This commit is contained in:
parent
0f0816aac2
commit
b29a4eb39f
|
@ -941,10 +941,11 @@ static void rayo_call_cleanup(struct rayo_actor *actor)
|
|||
|
||||
/* lost the race: pending join failed... send IQ result to client now. */
|
||||
if (call->pending_join_request) {
|
||||
iks *result = iks_new_error_detailed(call->pending_join_request, STANZA_ERROR_ITEM_NOT_FOUND, "call ended");
|
||||
RAYO_SEND_REPLY(call, iks_find_attrib_soft(call->pending_join_request, "from"), result);
|
||||
iks_delete(call->pending_join_request);
|
||||
iks *request = call->pending_join_request;
|
||||
iks *result = iks_new_error_detailed(request, STANZA_ERROR_ITEM_NOT_FOUND, "call ended");
|
||||
call->pending_join_request = NULL;
|
||||
RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result);
|
||||
iks_delete(call->pending_join_request);
|
||||
}
|
||||
|
||||
iks_delete(revent);
|
||||
|
@ -1765,9 +1766,11 @@ static iks *join_call(struct rayo_call *call, switch_core_session_t *session, st
|
|||
}
|
||||
call->pending_join_request = iks_copy(node);
|
||||
if (switch_ivr_uuid_bridge(rayo_call_get_uuid(call), rayo_call_get_uuid(b_call)) != SWITCH_STATUS_SUCCESS) {
|
||||
response = iks_new_error_detailed(node, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to bridge call");
|
||||
iks_delete(call->pending_join_request);
|
||||
iks *request = call->pending_join_request;
|
||||
iks *result = iks_new_error_detailed(request, STANZA_ERROR_ITEM_NOT_FOUND, "failed to bridge call");
|
||||
call->pending_join_request = NULL;
|
||||
RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result);
|
||||
iks_delete(call->pending_join_request);
|
||||
}
|
||||
RAYO_UNLOCK(b_call);
|
||||
}
|
||||
|
@ -1776,14 +1779,66 @@ static iks *join_call(struct rayo_call *call, switch_core_session_t *session, st
|
|||
|
||||
/**
|
||||
* Execute command on session's conference
|
||||
* @param session to execute conference API on
|
||||
* @param conf_name of conference
|
||||
* @param command to send to conference
|
||||
* @param node IQ request
|
||||
* @return response on failure
|
||||
*/
|
||||
static void exec_conference_api(switch_core_session_t *session, const char *conf_name, const char *command)
|
||||
static iks *exec_conference_api(switch_core_session_t *session, const char *conf_name, const char *command, iks *node)
|
||||
{
|
||||
iks *response = NULL;
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
const char *conf_member_id = switch_channel_get_variable(switch_core_session_get_channel(session), "conference_member_id");
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
switch_api_execute("conference", switch_core_session_sprintf(session, "%s %s %s", conf_name, command, conf_member_id), NULL, &stream);
|
||||
if (!zstr(stream.data) && strncmp("OK", stream.data, 2)) {
|
||||
response = iks_new_error_detailed_printf(node, STANZA_ERROR_INTERNAL_SERVER_ERROR, "%s", stream.data);
|
||||
}
|
||||
switch_safe_free(stream.data);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute conference app on session
|
||||
* @param session to execute conference API on
|
||||
* @param command to send to conference (conference name, member flags, etc)
|
||||
* @param node IQ request
|
||||
* @return response on failure
|
||||
*/
|
||||
static iks *exec_conference_app(switch_core_session_t *session, const char *command, iks *node)
|
||||
{
|
||||
iks *response = NULL;
|
||||
switch_event_t *execute_event = NULL;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
/* conference requires local media on channel */
|
||||
if (!switch_channel_media_ready(channel) && switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
|
||||
/* shit */
|
||||
response = iks_new_error_detailed(node, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to start media");
|
||||
return response;
|
||||
}
|
||||
|
||||
/* send execute conference event to session */
|
||||
if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute");
|
||||
switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "conference");
|
||||
switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", command);
|
||||
//switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event_uuid", uuid);
|
||||
switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true");
|
||||
if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) {
|
||||
switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA);
|
||||
}
|
||||
|
||||
if (switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
|
||||
response = iks_new_error_detailed(node, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to join mixer (queue event failed)");
|
||||
if (execute_event) {
|
||||
switch_event_destroy(&execute_event);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1803,14 +1858,20 @@ static iks *join_mixer(struct rayo_call *call, switch_core_session_t *session, s
|
|||
if (call->joined_id) {
|
||||
/* adjust join conference params */
|
||||
if (!strcmp("duplex", direction)) {
|
||||
exec_conference_api(session, mixer_name, "unmute");
|
||||
exec_conference_api(session, mixer_name, "undeaf");
|
||||
if ((response = exec_conference_api(session, mixer_name, "unmute", node)) ||
|
||||
(response = exec_conference_api(session, mixer_name, "undeaf", node))) {
|
||||
return response;
|
||||
}
|
||||
} else if (!strcmp("recv", direction)) {
|
||||
exec_conference_api(session, mixer_name, "mute");
|
||||
exec_conference_api(session, mixer_name, "undeaf");
|
||||
if ((response = exec_conference_api(session, mixer_name, "mute", node)) ||
|
||||
(response = exec_conference_api(session, mixer_name, "undeaf", node))) {
|
||||
return response;
|
||||
}
|
||||
} else {
|
||||
exec_conference_api(session, mixer_name, "unmute");
|
||||
exec_conference_api(session, mixer_name, "deaf");
|
||||
if ((response = exec_conference_api(session, mixer_name, "unmute", node)) ||
|
||||
(response = exec_conference_api(session, mixer_name, "deaf", node))) {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
response = iks_new_iq_result(node);
|
||||
} else {
|
||||
|
@ -1821,10 +1882,12 @@ static iks *join_mixer(struct rayo_call *call, switch_core_session_t *session, s
|
|||
} else if (!strcmp("recv", direction)) {
|
||||
conf_args = switch_core_session_sprintf(session, "%s+flags{mute}", conf_args);
|
||||
}
|
||||
if (switch_core_session_execute_application_async(session, "conference", conf_args) == SWITCH_STATUS_SUCCESS) {
|
||||
response = iks_new_iq_result(node);
|
||||
} else {
|
||||
response = iks_new_error_detailed(node, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed execute conference app");
|
||||
|
||||
call->pending_join_request = iks_copy(node);
|
||||
response = exec_conference_app(session, conf_args, node);
|
||||
if (response) {
|
||||
iks_delete(call->pending_join_request);
|
||||
call->pending_join_request = NULL;
|
||||
}
|
||||
}
|
||||
return response;
|
||||
|
@ -1951,11 +2014,12 @@ static iks *unjoin_mixer(struct rayo_call *call, switch_core_session_t *session,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* ack command */
|
||||
response = iks_new_iq_result(node);
|
||||
|
||||
/* kick the member */
|
||||
exec_conference_api(session, mixer_name, "hup");
|
||||
response = exec_conference_api(session, mixer_name, "hup", node);
|
||||
if (!response) {
|
||||
/* ack command */
|
||||
response = iks_new_iq_result(node);
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
|
@ -2538,6 +2602,15 @@ static void on_mixer_add_member_event(struct rayo_mixer *mixer, switch_event_t *
|
|||
call->joined = JOINED_MIXER;
|
||||
call->joined_id = switch_core_strdup(RAYO_POOL(call), rayo_mixer_get_name(mixer));
|
||||
|
||||
/* send IQ result to client now. */
|
||||
if (call->pending_join_request) {
|
||||
iks *request = call->pending_join_request;
|
||||
iks *result = iks_new_iq_result(request);
|
||||
call->pending_join_request = NULL;
|
||||
RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result);
|
||||
iks_delete(request);
|
||||
}
|
||||
|
||||
/* send mixer joined event to member DCP */
|
||||
add_member_event = iks_new_presence("joined", RAYO_NS, RAYO_JID(call), call->dcp_jid);
|
||||
x = iks_find(add_member_event, "joined");
|
||||
|
@ -2705,14 +2778,13 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev
|
|||
call->joined_id = switch_core_strdup(RAYO_POOL(call), b_uuid);
|
||||
|
||||
/* send IQ result to client now. */
|
||||
switch_mutex_lock(RAYO_ACTOR(call)->mutex);
|
||||
if (call->pending_join_request) {
|
||||
iks *result = iks_new_iq_result(call->pending_join_request);
|
||||
RAYO_SEND_REPLY(call, iks_find_attrib_soft(call->pending_join_request, "from"), result);
|
||||
iks_delete(call->pending_join_request);
|
||||
iks *request = call->pending_join_request;
|
||||
iks *result = iks_new_iq_result(request);
|
||||
call->pending_join_request = NULL;
|
||||
RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result);
|
||||
iks_delete(request);
|
||||
}
|
||||
switch_mutex_unlock(RAYO_ACTOR(call)->mutex);
|
||||
|
||||
/* send A-leg event */
|
||||
revent = iks_new_presence("joined", RAYO_NS,
|
||||
|
@ -2760,14 +2832,13 @@ static void on_call_unbridge_event(struct rayo_client *rclient, switch_event_t *
|
|||
call->joined_id = NULL;
|
||||
|
||||
/* send IQ result to client now. */
|
||||
switch_mutex_lock(RAYO_ACTOR(call)->mutex);
|
||||
if (call->pending_join_request) {
|
||||
iks *result = iks_new_iq_result(call->pending_join_request);
|
||||
RAYO_SEND_REPLY(call, iks_find_attrib_soft(call->pending_join_request, "from"), result);
|
||||
iks_delete(call->pending_join_request);
|
||||
iks *request = call->pending_join_request;
|
||||
iks *result = iks_new_iq_result(request);
|
||||
call->pending_join_request = NULL;
|
||||
RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result);
|
||||
iks_delete(request);
|
||||
}
|
||||
switch_mutex_unlock(RAYO_ACTOR(call)->mutex);
|
||||
|
||||
/* send A-leg event */
|
||||
revent = iks_new_presence("unjoined", RAYO_NS,
|
||||
|
@ -2793,6 +2864,36 @@ static void on_call_unbridge_event(struct rayo_client *rclient, switch_event_t *
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle call execute application event
|
||||
* @param rclient the Rayo client
|
||||
* @param event the execute event
|
||||
*/
|
||||
static void on_call_execute_event(struct rayo_client *rclient, switch_event_t *event)
|
||||
{
|
||||
struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID"));
|
||||
if (call) {
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Application %s execute\n", switch_event_get_header(event, "Application"));
|
||||
RAYO_UNLOCK(call);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle call execute application complete event
|
||||
* @param rclient the Rayo client
|
||||
* @param event the execute complete event
|
||||
*/
|
||||
static void on_call_execute_complete_event(struct rayo_client *rclient, switch_event_t *event)
|
||||
{
|
||||
struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(switch_event_get_header(event, "Unique-ID"));
|
||||
if (call) {
|
||||
const char *app = switch_event_get_header(event, "Application");
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Application %s execute complete: %s \n",
|
||||
app,
|
||||
switch_event_get_header(event, "Application-Response"));
|
||||
RAYO_UNLOCK(call);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle events to deliver to client connection
|
||||
|
@ -2819,6 +2920,12 @@ static void rayo_client_handle_event(struct rayo_client *rclient, switch_event_t
|
|||
case SWITCH_EVENT_CHANNEL_UNBRIDGE:
|
||||
on_call_unbridge_event(rclient, event);
|
||||
break;
|
||||
case SWITCH_EVENT_CHANNEL_EXECUTE:
|
||||
on_call_execute_event(rclient, event);
|
||||
break;
|
||||
case SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE:
|
||||
on_call_execute_complete_event(rclient, event);
|
||||
break;
|
||||
default:
|
||||
/* don't care */
|
||||
break;
|
||||
|
@ -2944,7 +3051,9 @@ static switch_status_t rayo_call_on_read_frame(switch_core_session_t *session, s
|
|||
switch_time_t idle_start = call->idle_start_time;
|
||||
int idle_duration_ms = (now - idle_start) / 1000;
|
||||
/* detect idle session (rayo-client has stopped controlling call) and terminate call */
|
||||
if (!rayo_call_is_joined(call) && idle_duration_ms > globals.max_idle_ms) {
|
||||
if (rayo_call_is_joined(call)) {
|
||||
call->idle_start_time = now;
|
||||
} else if (idle_duration_ms > globals.max_idle_ms) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Ending abandoned call. idle_duration_ms = %i ms\n", idle_duration_ms);
|
||||
switch_channel_hangup(channel, RAYO_CAUSE_HANGUP);
|
||||
}
|
||||
|
@ -3891,6 +4000,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load)
|
|||
switch_event_bind(modname, SWITCH_EVENT_CHANNEL_ANSWER, NULL, route_call_event, NULL);
|
||||
switch_event_bind(modname, SWITCH_EVENT_CHANNEL_BRIDGE, NULL, route_call_event, NULL);
|
||||
switch_event_bind(modname, SWITCH_EVENT_CHANNEL_UNBRIDGE, NULL, route_call_event, NULL);
|
||||
switch_event_bind(modname, SWITCH_EVENT_CHANNEL_EXECUTE, NULL, route_call_event, NULL);
|
||||
switch_event_bind(modname, SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, route_call_event, NULL);
|
||||
|
||||
switch_event_bind(modname, SWITCH_EVENT_CHANNEL_DESTROY, NULL, on_call_end_event, NULL);
|
||||
|
||||
|
|
Loading…
Reference in New Issue