mod_rayo: fixes for <prompt> and reply loops
This commit is contained in:
parent
7625001e49
commit
f750bcbcc1
|
@ -230,14 +230,22 @@ static void rayo_console_client_send(struct rayo_actor *client, struct rayo_mess
|
|||
|
||||
static void on_client_presence(struct rayo_client *rclient, iks *node);
|
||||
|
||||
/**
|
||||
* @param msg to check
|
||||
* @return true if message was sent by admin client (console)
|
||||
*/
|
||||
static int is_admin_client_message(struct rayo_message *msg)
|
||||
{
|
||||
return !zstr(msg->from_jid) && !strcmp(RAYO_JID(globals.console), msg->from_jid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jid to check
|
||||
* @return true if jid is admin client (console)
|
||||
* @param msg to check
|
||||
* @return true if from/to bare JIDs match
|
||||
*/
|
||||
static int is_admin_client(const char *jid)
|
||||
static int is_internal_message(struct rayo_message *msg)
|
||||
{
|
||||
return !zstr(jid) && !strcmp(RAYO_JID(globals.console), jid);
|
||||
return msg->from && msg->to && (iks_id_cmp(msg->from, msg->to, IKS_ID_PARTIAL) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -580,6 +588,8 @@ iks *rayo_message_remove_payload(struct rayo_message *msg)
|
|||
{
|
||||
iks *payload = msg->payload;
|
||||
msg->payload = NULL;
|
||||
msg->from = NULL;
|
||||
msg->to = NULL;
|
||||
return payload;
|
||||
}
|
||||
|
||||
|
@ -600,6 +610,7 @@ static void *SWITCH_THREAD_FUNC deliver_message_thread(switch_thread_t *thread,
|
|||
if (actor) {
|
||||
/* deliver to actor */
|
||||
switch_mutex_lock(actor->mutex);
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, msg->file, "", msg->line, "", SWITCH_LOG_DEBUG, "Deliver %s => %s %s\n", msg->from_jid, msg->to_jid, iks_string(iks_stack(msg->payload), msg->payload));
|
||||
actor->send_fn(actor, msg);
|
||||
switch_mutex_unlock(actor->mutex);
|
||||
RAYO_UNLOCK(actor);
|
||||
|
@ -665,7 +676,13 @@ void rayo_message_send(struct rayo_actor *from, const char *to, iks *payload, in
|
|||
}
|
||||
msg->is_reply = reply;
|
||||
msg->to_jid = strdup(zstr(to) ? "" : to);
|
||||
if (!zstr(msg->to_jid)) {
|
||||
msg->to = iks_id_new(iks_stack(payload), msg->to_jid);
|
||||
}
|
||||
msg->from_jid = strdup(RAYO_JID(from));
|
||||
if (!zstr(msg->from_jid)) {
|
||||
msg->from = iks_id_new(iks_stack(payload), msg->from_jid);
|
||||
}
|
||||
msg->from_type = strdup(zstr(from->type) ? "" : from->type);
|
||||
msg->from_subtype = strdup(zstr(from->subtype) ? "" : from->subtype);
|
||||
msg->file = strdup(file);
|
||||
|
@ -1239,39 +1256,32 @@ static struct rayo_peer_server *rayo_peer_server_create(const char *jid)
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if client has control of offered call. Take control if nobody else does.
|
||||
* @param rclient the Rayo client
|
||||
* Check if message sender has control of offered call. Take control if nobody else does.
|
||||
* @param call the Rayo call
|
||||
* @param session the session
|
||||
* @param call_jid the call JID
|
||||
* @param call_uuid the internal call UUID
|
||||
* @return 1 if session has call control
|
||||
* @param msg the message
|
||||
* @return 1 if sender has call control
|
||||
*/
|
||||
static int rayo_client_has_call_control(const char *rclient, struct rayo_call *call, switch_core_session_t *session)
|
||||
static int has_call_control(struct rayo_call *call, switch_core_session_t *session, struct rayo_message *msg)
|
||||
{
|
||||
int control = 0;
|
||||
|
||||
if (zstr(rclient)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Null client JID!!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* nobody in charge */
|
||||
if (zstr(call->dcp_jid)) {
|
||||
/* was offered to this session? */
|
||||
if (switch_core_hash_find(call->pcps, rclient)) {
|
||||
if (!zstr(msg->from_jid) && switch_core_hash_find(call->pcps, msg->from_jid)) {
|
||||
/* take charge */
|
||||
call->dcp_jid = switch_core_strdup(RAYO_POOL(call), rclient);
|
||||
call->dcp_jid = switch_core_strdup(RAYO_POOL(call), msg->from_jid);
|
||||
switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_dcp_jid", rayo_call_get_dcp_jid(call));
|
||||
control = 1;
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_INFO, "%s has control of call\n", rayo_call_get_dcp_jid(call));
|
||||
}
|
||||
} else if (is_admin_client(rclient) || !strcmp(rayo_call_get_dcp_jid(call), rclient)) {
|
||||
} else if (!strcmp(rayo_call_get_dcp_jid(call), msg->from_jid) || is_internal_message(msg) || is_admin_client_message(msg)) {
|
||||
control = 1;
|
||||
}
|
||||
|
||||
if (!control) {
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_INFO, "%s does not have control of call\n", rclient);
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_INFO, "%s does not have control of call\n", msg->from_jid);
|
||||
}
|
||||
|
||||
return control;
|
||||
|
@ -1311,7 +1321,7 @@ static iks *rayo_call_command_ok(struct rayo_call *call, switch_core_session_t *
|
|||
|
||||
if (bad) {
|
||||
response = iks_new_error(node, STANZA_ERROR_BAD_REQUEST);
|
||||
} else if (!rayo_client_has_call_control(msg->from_jid, call, session)) {
|
||||
} else if (!has_call_control(call, session, msg)) {
|
||||
response = iks_new_error(node, STANZA_ERROR_CONFLICT);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, %s conflict\n", msg->from_jid, RAYO_JID(call));
|
||||
}
|
||||
|
@ -1335,7 +1345,7 @@ static iks *rayo_component_command_ok(struct rayo_component *component, struct r
|
|||
if (bad) {
|
||||
response = iks_new_error(node, STANZA_ERROR_BAD_REQUEST);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, %s bad request\n", msg->from_jid, RAYO_JID(component));
|
||||
} else if (!is_admin_client(msg->from_jid) && strcmp(component->client_jid, from)) {
|
||||
} else if (strcmp(component->client_jid, from) && !is_admin_client_message(msg) && !is_internal_message(msg)) {
|
||||
/* does not have control of this component */
|
||||
response = iks_new_error(node, STANZA_ERROR_CONFLICT);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, %s conflict\n", msg->from_jid, RAYO_JID(component));
|
||||
|
@ -1369,7 +1379,9 @@ void rayo_server_send(struct rayo_actor *server, struct rayo_message *msg)
|
|||
handler = rayo_actor_command_handler_find(server, msg);
|
||||
if (!handler) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no handler function for command to %s\n", msg->from_jid, RAYO_JID(server));
|
||||
RAYO_SEND_REPLY(server, msg->from_jid, iks_new_error(iq, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED));
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(server, msg->from_jid, iks_new_error(iq, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1379,7 +1391,11 @@ void rayo_server_send(struct rayo_actor *server, struct rayo_message *msg)
|
|||
}
|
||||
|
||||
if (response) {
|
||||
RAYO_SEND_REPLY(server, msg->from_jid, response);
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(server, msg->from_jid, response);
|
||||
} else {
|
||||
iks_delete(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1397,7 +1413,9 @@ void rayo_call_send(struct rayo_actor *call, struct rayo_message *msg)
|
|||
handler = rayo_actor_command_handler_find(call, msg);
|
||||
if (!handler) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no handler function for command\n", RAYO_JID(call));
|
||||
RAYO_SEND_REPLY(call, msg->from_jid, iks_new_error(iq, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED));
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(call, msg->from_jid, iks_new_error(iq, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1405,7 +1423,9 @@ void rayo_call_send(struct rayo_actor *call, struct rayo_message *msg)
|
|||
session = switch_core_session_locate(rayo_call_get_uuid(RAYO_CALL(call)));
|
||||
if (!session) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, session not found\n", RAYO_JID(call));
|
||||
RAYO_SEND_REPLY(call, msg->from_jid, iks_new_error(iq, STANZA_ERROR_SERVICE_UNAVAILABLE));
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(call, msg->from_jid, iks_new_error(iq, STANZA_ERROR_SERVICE_UNAVAILABLE));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1419,7 +1439,11 @@ void rayo_call_send(struct rayo_actor *call, struct rayo_message *msg)
|
|||
switch_core_session_rwunlock(session);
|
||||
|
||||
if (response) {
|
||||
RAYO_SEND_REPLY(call, msg->from_jid, response);
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(call, msg->from_jid, response);
|
||||
} else {
|
||||
iks_delete(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1436,14 +1460,20 @@ void rayo_mixer_send(struct rayo_actor *mixer, struct rayo_message *msg)
|
|||
handler = rayo_actor_command_handler_find(mixer, msg);
|
||||
if (!handler) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no handler function for command\n", RAYO_JID(mixer));
|
||||
RAYO_SEND_REPLY(mixer, msg->from_jid, iks_new_error(iq, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED));
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(mixer, msg->from_jid, iks_new_error(iq, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* execute the command */
|
||||
response = handler(mixer, msg, NULL);
|
||||
if (response) {
|
||||
RAYO_SEND_REPLY(mixer, msg->from_jid, response);
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(mixer, msg->from_jid, response);
|
||||
} else {
|
||||
iks_delete(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1461,7 +1491,9 @@ void rayo_component_send(struct rayo_actor *component, struct rayo_message *msg)
|
|||
handler = rayo_actor_command_handler_find(component, msg);
|
||||
if (!handler) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, no component handler function for command\n", RAYO_JID(component));
|
||||
RAYO_SEND_REPLY(component, msg->from_jid, iks_new_error(xml_msg, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED));
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(component, msg->from_jid, iks_new_error(xml_msg, STANZA_ERROR_FEATURE_NOT_IMPLEMENTED));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1473,7 +1505,11 @@ void rayo_component_send(struct rayo_actor *component, struct rayo_message *msg)
|
|||
}
|
||||
|
||||
if (response) {
|
||||
RAYO_SEND_REPLY(component, msg->from_jid, response);
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(component, msg->from_jid, response);
|
||||
} else {
|
||||
iks_delete(response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (!strcmp("presence", iks_name(xml_msg))) {
|
||||
|
@ -1488,7 +1524,11 @@ void rayo_component_send(struct rayo_actor *component, struct rayo_message *msg)
|
|||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, forwarding event\n", RAYO_JID(component));
|
||||
response = handler(component, msg, NULL);
|
||||
if (response) {
|
||||
RAYO_SEND_REPLY(component, msg->from_jid, response);
|
||||
if (!msg->is_reply) {
|
||||
RAYO_SEND_REPLY(component, msg->from_jid, response);
|
||||
} else {
|
||||
iks_delete(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2245,7 +2285,10 @@ static void rayo_client_command_recv(struct rayo_client *rclient, iks *iq)
|
|||
if (command) {
|
||||
RAYO_SEND_MESSAGE_DUP(rclient, to, iq);
|
||||
} else {
|
||||
RAYO_SEND_REPLY(globals.server, RAYO_JID(rclient), iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "empty IQ request"));
|
||||
const char *type = iks_find_attrib_soft(iq, "type");
|
||||
if (strcmp("error", type) && strcmp("result", type)) {
|
||||
RAYO_SEND_REPLY(globals.server, RAYO_JID(rclient), iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "empty IQ request"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,9 @@ struct rayo_component;
|
|||
struct rayo_message {
|
||||
iks *payload;
|
||||
char *to_jid;
|
||||
iksid *to;
|
||||
char *from_jid;
|
||||
iksid *from;
|
||||
char *from_type;
|
||||
char *from_subtype;
|
||||
int is_reply;
|
||||
|
@ -104,8 +106,6 @@ struct rayo_actor {
|
|||
rayo_actor_send_fn send_fn;
|
||||
/** optional cleanup */
|
||||
rayo_actor_cleanup_fn cleanup_fn;
|
||||
/** incoming message queue */
|
||||
switch_queue_t *msg_queue;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -96,7 +96,7 @@ static void rayo_component_send_stop(struct rayo_actor *from, const char *to)
|
|||
iks_insert_attrib(stop, "from", RAYO_JID(from));
|
||||
iks_insert_attrib(stop, "to", to);
|
||||
iks_insert_attrib(stop, "type", "set");
|
||||
iks_insert_attrib_printf(stop, "id", "mod_rayo-%d", RAYO_SEQ_NEXT(from));
|
||||
iks_insert_attrib_printf(stop, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(from));
|
||||
x = iks_insert(stop, "stop");
|
||||
iks_insert_attrib(x, "xmlns", RAYO_EXT_NS);
|
||||
RAYO_SEND_MESSAGE(from, to, stop);
|
||||
|
@ -112,7 +112,7 @@ static void start_input(struct prompt_component *prompt, int start_timers, int b
|
|||
input = iks_find(input, "input");
|
||||
iks_insert_attrib(iq, "from", RAYO_JID(prompt));
|
||||
iks_insert_attrib(iq, "to", RAYO_JID(RAYO_COMPONENT(prompt)->parent));
|
||||
iks_insert_attrib_printf(iq, "id", "mod_rayo-%d", RAYO_SEQ_NEXT(prompt));
|
||||
iks_insert_attrib_printf(iq, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(prompt));
|
||||
iks_insert_attrib(iq, "type", "set");
|
||||
input = iks_copy_within(input, iks_stack(iq));
|
||||
iks_insert_attrib(input, "start-timers", start_timers ? "true" : "false");
|
||||
|
@ -131,7 +131,7 @@ static void start_input_timers(struct prompt_component *prompt)
|
|||
iks_insert_attrib(iq, "from", RAYO_JID(prompt));
|
||||
iks_insert_attrib(iq, "to", prompt->input_jid);
|
||||
iks_insert_attrib(iq, "type", "set");
|
||||
iks_insert_attrib_printf(iq, "id", "mod_rayo-%d", RAYO_SEQ_NEXT(prompt));
|
||||
iks_insert_attrib_printf(iq, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(prompt));
|
||||
x = iks_insert(iq, "start-timers");
|
||||
iks_insert_attrib(x, "xmlns", RAYO_INPUT_NS);
|
||||
RAYO_SEND_MESSAGE(prompt, prompt->input_jid, iq);
|
||||
|
@ -422,6 +422,22 @@ static iks *prompt_component_handle_input_complete(struct rayo_actor *prompt, st
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward result
|
||||
*/
|
||||
static iks *prompt_component_handle_result(struct rayo_actor *prompt, struct rayo_message *msg, void *data)
|
||||
{
|
||||
iks *iq = msg->payload;
|
||||
|
||||
/* forward all results, except for internal ones... */
|
||||
if (strncmp("mod_rayo-prompt", iks_find_attrib_soft(iq, "id"), 15)) {
|
||||
iks_insert_attrib(iq, "from", RAYO_JID(prompt));
|
||||
iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid);
|
||||
RAYO_SEND_REPLY_DUP(prompt, RAYO_COMPONENT(prompt)->client_jid, iq);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle completion event
|
||||
*/
|
||||
|
@ -582,7 +598,7 @@ static iks *forward_output_component_request(struct rayo_actor *prompt, struct r
|
|||
case PCS_INPUT_OUTPUT: {
|
||||
/* forward request to output component */
|
||||
iks_insert_attrib(iq, "from", RAYO_JID(prompt));
|
||||
iks_insert_attrib(iq, "to", RAYO_JID(PROMPT_COMPONENT(prompt)->output_jid));
|
||||
iks_insert_attrib(iq, "to", PROMPT_COMPONENT(prompt)->output_jid);
|
||||
RAYO_SEND_MESSAGE_DUP(prompt, PROMPT_COMPONENT(prompt)->output_jid, iq);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -590,7 +606,7 @@ static iks *forward_output_component_request(struct rayo_actor *prompt, struct r
|
|||
case PCS_START_OUTPUT:
|
||||
case PCS_START_OUTPUT_BARGE:
|
||||
/* ref hasn't been sent yet */
|
||||
return iks_new_error(iq, STANZA_ERROR_UNEXPECTED_REQUEST);
|
||||
return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "too soon");
|
||||
break;
|
||||
case PCS_START_INPUT:
|
||||
case PCS_STOP_OUTPUT:
|
||||
|
@ -612,6 +628,7 @@ switch_status_t rayo_prompt_component_load(void)
|
|||
rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_PROMPT_NS":prompt", start_call_prompt_component);
|
||||
rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "set:"RAYO_EXT_NS":stop", stop_call_prompt_component);
|
||||
rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "result:"RAYO_NS":ref", prompt_component_handle_io_start);
|
||||
rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "result::", prompt_component_handle_result);
|
||||
rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "error:"RAYO_OUTPUT_NS":output", prompt_component_handle_output_error);
|
||||
rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "error:"RAYO_INPUT_NS":input", prompt_component_handle_input_error);
|
||||
rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "prompt", "error:"RAYO_INPUT_NS":start-timers", prompt_component_handle_input_start_timers_error);
|
||||
|
|
Loading…
Reference in New Issue