/**
 * 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;
}
/**
 * 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;
}
Esempio n. 3
0
/**
 * 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;
}
/**
 * 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);
}