/** * Handle input failure. */ static iks *prompt_component_handle_input_error(struct rayo_actor *prompt, struct rayo_message *msg, void *data) { iks *iq = msg->payload; iks *error = iks_find(iq, "error"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) input error\n", RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); switch (PROMPT_COMPONENT(prompt)->state) { case PCS_START_INPUT_TIMERS: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, <input> error: %s\n", RAYO_JID(prompt), iks_string(iks_stack(iq), iq)); PROMPT_COMPONENT(prompt)->state = PCS_DONE; /* forward IQ error to client */ iq = PROMPT_COMPONENT(prompt)->iq; iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent)); iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); iks_insert_node(iq, iks_copy_within(error, iks_stack(iq))); RAYO_SEND_REPLY(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); /* done */ RAYO_UNLOCK(prompt); RAYO_DESTROY(prompt); break; case PCS_START_INPUT: /* send presence error to client */ PROMPT_COMPONENT(prompt)->state = PCS_DONE; iks_delete(PROMPT_COMPONENT(prompt)->iq); rayo_component_send_complete(RAYO_COMPONENT(prompt), COMPONENT_COMPLETE_ERROR); break; case PCS_START_INPUT_OUTPUT: PROMPT_COMPONENT(prompt)->state = PCS_DONE_STOP_OUTPUT; /* forward IQ error to client */ iq = PROMPT_COMPONENT(prompt)->iq; iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent)); iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); iks_insert_node(iq, iks_copy_within(error, iks_stack(iq))); PROMPT_COMPONENT(prompt)->complete = iq; rayo_component_send_stop(prompt, PROMPT_COMPONENT(prompt)->output_jid); break; case PCS_START_OUTPUT: case PCS_START_OUTPUT_BARGE: case PCS_INPUT_OUTPUT: case PCS_STOP_OUTPUT: case PCS_INPUT: case PCS_OUTPUT: case PCS_DONE_STOP_OUTPUT: case PCS_DONE: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, unexpected start input error event\n", RAYO_JID(prompt)); break; } return NULL; }
iks * iks_copy (iks *x) { ikstack *s; s = iks_stack_new (sizeof (struct iks_tag) * 6, 256); if (!s) return NULL; return iks_copy_within (x, s); }
/** * Start execution of prompt component */ static iks *start_call_prompt_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) { iks *iq = msg->payload; switch_core_session_t *session = (switch_core_session_t *)session_data; switch_memory_pool_t *pool; struct prompt_component *prompt_component = NULL; iks *prompt = iks_find(iq, "prompt"); iks *input; iks *output; iks *cmd; if (!VALIDATE_RAYO_PROMPT(prompt)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bad <prompt> attrib\n"); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Bad <prompt> attrib value"); } output = iks_find(prompt, "output"); if (!output) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Missing <output>\n"); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing <output>"); } input = iks_find(prompt, "input"); if (!input) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Missing <input>\n"); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing <input>"); } /* create prompt component, linked to call */ switch_core_new_memory_pool(&pool); prompt_component = switch_core_alloc(pool, sizeof(*prompt_component)); rayo_component_init(RAYO_COMPONENT(prompt_component), pool, RAT_CALL_COMPONENT, "prompt", NULL, call, iks_find_attrib(iq, "from")); prompt_component->iq = iks_copy(iq); /* start output */ if (iks_find_bool_attrib(prompt, "barge-in")) { prompt_component->state = PCS_START_OUTPUT_BARGE; } else { prompt_component->state = PCS_START_OUTPUT; } cmd = iks_new("iq"); iks_insert_attrib(cmd, "from", RAYO_JID(prompt_component)); iks_insert_attrib(cmd, "to", RAYO_JID(call)); iks_insert_attrib(cmd, "id", iks_find_attrib(iq, "id")); iks_insert_attrib(cmd, "type", "set"); output = iks_copy_within(output, iks_stack(cmd)); iks_insert_node(cmd, output); RAYO_SEND_MESSAGE(prompt_component, RAYO_JID(call), cmd); return NULL; }
/** * Start input component */ static void start_input(struct prompt_component *prompt, int start_timers, int barge_event) { iks *iq = iks_new("iq"); iks *input = iks_find(PROMPT_COMPONENT(prompt)->iq, "prompt"); 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-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"); iks_insert_attrib(input, "barge-event", barge_event ? "true" : "false"); iks_insert_node(iq, input); RAYO_SEND_MESSAGE(prompt, RAYO_JID(RAYO_COMPONENT(prompt)->parent), iq); }
/** * Create component complete event * @param component the component * @param reason_str the completion reason * @param reason_namespace the completion reason namespace * @param meta metadata to add as child * @param child_of_complete if true metadata is child of complete instead of reason * @return the event */ iks *rayo_component_create_complete_event_with_metadata(struct rayo_component *component, const char *reason_str, const char *reason_namespace, iks *meta, int child_of_complete) { iks *response = iks_new("presence"); iks *complete; iks *reason; iks_insert_attrib(response, "from", RAYO_JID(component)); iks_insert_attrib(response, "to", component->client_jid); iks_insert_attrib(response, "type", "unavailable"); complete = iks_insert(response, "complete"); iks_insert_attrib(complete, "xmlns", RAYO_EXT_NS); reason = iks_insert(complete, reason_str); iks_insert_attrib(reason, "xmlns", reason_namespace); if (meta) { meta = iks_copy_within(meta, iks_stack(response)); if (child_of_complete) { iks_insert_node(complete, meta); } else { iks_insert_node(reason, meta); } } return response; }
iks * iks_copy (iks *x) { return iks_copy_within (x, iks_stack_new (sizeof (struct iks_tag) * 6, 256)); }