/**
 * Start execution of call output component
 */
static iks *start_call_output_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;
	struct rayo_component *output_component = NULL;
	iks *output = iks_find(iq, "output");
	iks *document = NULL;

	/* validate output attributes */
	if (!VALIDATE_RAYO_OUTPUT(output)) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	/* check if <document> exists */
	document = iks_find(output, "document");
	if (!document) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	output_component = create_output_component(call, RAT_CALL_COMPONENT, output, iks_find_attrib(iq, "from"));
	if (!output_component) {
		return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create output entity");
	}
	return start_call_output(output_component, session, output, iq);
}
示例#2
0
void
tag (char *name, ...)
{
	iks *x;
	va_list ap;

	x = my_x;
	va_start (ap, name);
	while (1) {
		char *name = iks_name (x);
		char *tmp = va_arg (ap, char*);
		if (NULL == tmp) break;
		x = iks_find (x, tmp);
		if (!x) {
			PR_TEST;
			printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name);
			exit (1);
		}
	}
	if (!x || NULL == iks_find (x, name)) {
		PR_TEST;
		printf ("Tag <%s> is not a child of tag <%s>\n", name, iks_name (x));
		exit (1);
	}
	va_end (ap);
}
示例#3
0
文件: f_oasis.c 项目: Bisheg/evince
int
_imp_oasis_load(ImpDoc *doc)
{
	ImpPage *page;
	iks *x, *pres;
	int i;

	pres = iks_find(iks_find(doc->content, "office:body"), "office:presentation");
	if (!pres) return IMP_NOTIMP;

	x = iks_find(pres, "draw:page");
	if (!x) return IMP_NOTIMP;
	i = 0;
	for (; x; x = iks_next_tag(x)) {
		if (strcmp(iks_name(x), "draw:page") == 0) {
			page = iks_stack_alloc(doc->stack, sizeof(ImpPage));
			if (!page) return IMP_NOMEM;
			memset(page, 0, sizeof(ImpPage));
			page->page = x;
			page->nr = ++i;
			page->name = iks_find_attrib(x, "draw:name");
			page->doc = doc;
			if (!doc->pages) doc->pages = page;
			page->prev = doc->last_page;
			if (doc->last_page) doc->last_page->next = page;
			doc->last_page = page;
		}
	}
	doc->nr_pages = i;
	doc->get_geometry = get_geometry;
	doc->render_page = render_page;

	return 0;
}
/**
 * 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;
}
示例#5
0
/**
 * Forward CPA signal to client
 */
static void rayo_cpa_detector_event(const char *jid, void *user_data)
{
    struct rayo_actor *component = RAYO_LOCATE(jid);
    if (component) {
        if (CPA_COMPONENT(component)->ready) {
            switch_event_t *event = (switch_event_t *)user_data;
            const char *signal_type = switch_event_get_header(event, "signal-type");
            struct cpa_signal *cpa_signal = switch_core_hash_find(CPA_COMPONENT(component)->signals, signal_type);
            switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_COMPONENT(component)->parent->id), SWITCH_LOG_DEBUG, "Handling CPA event\n");
            if (cpa_signal) {
                const char *value = switch_event_get_header(event, "value");
                const char *duration = switch_event_get_header(event, "duration");
                if (cpa_signal->terminate) {
                    iks *complete_event;
                    iks *signal_xml;

                    stop_cpa_detectors(CPA_COMPONENT(component));

                    /* send complete event to client */
                    complete_event = rayo_component_create_complete_event(RAYO_COMPONENT(component), "signal", RAYO_CPA_NS);
                    signal_xml = iks_find(complete_event, "complete");
                    signal_xml = iks_find(signal_xml, "signal");
                    iks_insert_attrib(signal_xml, "type", signal_type);
                    if (!zstr(value)) {
                        iks_insert_attrib(signal_xml, "value", value);
                    }
                    if (!zstr(duration)) {
                        iks_insert_attrib(signal_xml, "duration", duration);
                    }
                    rayo_component_send_complete_event(RAYO_COMPONENT(component), complete_event);
                } else {
                    /* send event to client */
                    iks *signal_event = iks_new_presence("signal", RAYO_CPA_NS, RAYO_JID(component), RAYO_COMPONENT(component)->client_jid);
                    iks *signal_xml = iks_find(signal_event, "signal");
                    iks_insert_attrib(signal_xml, "type", signal_type);
                    if (!zstr(value)) {
                        iks_insert_attrib(signal_xml, "value", value);
                    }
                    if (!zstr(duration)) {
                        iks_insert_attrib(signal_xml, "duration", duration);
                    }
                    RAYO_SEND_REPLY(component, RAYO_COMPONENT(component)->client_jid, signal_event);
                }
            }
        } else {
            switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_COMPONENT(component)->parent->id), SWITCH_LOG_DEBUG, "Skipping CPA event\n");
        }
        RAYO_UNLOCK(component);
    }
}
/**
 * Start execution of mixer output component
 */
static iks *start_mixer_output_component(struct rayo_actor *mixer, struct rayo_message *msg, void *data)
{
	iks *iq = msg->payload;
	struct rayo_component *component = NULL;
	iks *output = iks_find(iq, "output");
	iks *document = NULL;
	switch_stream_handle_t stream = { 0 };

	/* validate output attributes */
	if (!VALIDATE_RAYO_OUTPUT(output)) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	/* check if <document> exists */
	document = iks_find(output, "document");
	if (!document) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	component = create_output_component(mixer, RAT_MIXER_COMPONENT, output, iks_find_attrib(iq, "from"));
	if (!component) {
		return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create output entity");
	}

	/* build conference command */
	SWITCH_STANDARD_STREAM(stream);
	stream.write_function(&stream, "%s play ", rayo_mixer_get_name(RAYO_MIXER(mixer)), RAYO_ID(component));

	stream.write_function(&stream, "{id=%s,pause=%s",
		RAYO_JID(component),
		OUTPUT_COMPONENT(component)->start_paused ? "true" : "false");
	if (OUTPUT_COMPONENT(component)->max_time_ms > 0) {
		stream.write_function(&stream, ",timeout=%i", OUTPUT_COMPONENT(component)->max_time_ms);
	}
	if (OUTPUT_COMPONENT(component)->start_offset_ms > 0) {
		stream.write_function(&stream, ",start_offset_ms=%i", OUTPUT_COMPONENT(component)->start_offset_ms);
	}
	stream.write_function(&stream, "}fileman://rayo://%s", RAYO_JID(component));

	/* acknowledge command */
	rayo_component_send_start(component, iq);

	rayo_component_api_execute_async(component, "conference", stream.data);

	switch_safe_free(stream.data);
	RAYO_RELEASE(component);

	return NULL;
}
示例#7
0
文件: f_oasis.c 项目: Bisheg/evince
static void
get_geometry(ImpRenderCtx *ctx)
{
	char *tmp;
	iks *x, *y;

	tmp = iks_find_attrib(ctx->page->page, "draw:master-page-name");
	x = iks_find(ctx->page->doc->styles, "office:master-styles");
	y = iks_find_with_attrib(x, "style:master-page", "style:name", tmp);
	x = iks_find(ctx->page->doc->styles, "office:automatic-styles");
	y = iks_find_with_attrib(x, "style:page-layout", "style:name",
		iks_find_attrib(y, "style:page-layout-name"));
	ctx->cm_w = atof(iks_find_attrib(iks_find(y, "style:page-layout-properties"), "fo:page-width"));
	ctx->cm_h = atof(iks_find_attrib(iks_find(y, "style:page-layout-properties"), "fo:page-height"));
}
/**
 * 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);
}
/**
 * Start execution of mixer record component
 */
static iks *start_mixer_record_component(struct rayo_actor *client, struct rayo_actor *mixer, iks *iq, void *data)
{
	struct rayo_component *component = NULL;
	iks *record = iks_find(iq, "record");

	component = record_component_create(mixer, iks_find_attrib(iq, "from"), record);
	if (!component) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	/* mixer doesn't allow "send" */
	if (!strcmp("send", iks_find_attrib_soft(record, "direction"))) {
		RAYO_UNLOCK(component);
		RAYO_DESTROY(component);
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	if (start_mixer_record(component)) {
		rayo_component_send_start(component, iq);
	} else {
		RAYO_UNLOCK(component);
		RAYO_DESTROY(component);
		return iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR);
	}

	return NULL;
}
示例#10
0
文件: f_oasis.c 项目: Bisheg/evince
static void
render_page(ImpRenderCtx *ctx, void *drw_data)
{
	iks *x;
	char *element;
	int i;

	i = _imp_fill_back(ctx, drw_data, ctx->page->page);
	element = iks_find_attrib(ctx->page->page, "draw:master-page-name");
	if (element) {
		x = iks_find_with_attrib(
			iks_find(ctx->page->doc->styles, "office:master-styles"),
			"style:master-page", "style:name", element
		);
		if (x) {
			if (i == 0) _imp_fill_back(ctx, drw_data, x);
			for (x = iks_first_tag(x); x; x = iks_next_tag(x)) {
				if (iks_find_attrib(x, "presentation:class"))
					continue;
				render_object(ctx, drw_data, x);
			}
		}
	}
	for (x = iks_first_tag(ctx->page->page); x; x = iks_next_tag(x)) {
		render_object(ctx, drw_data, x);
	}
}
示例#11
0
void
cdata (char *data, ...)
{
	iks *x;
	va_list ap;

	x = my_x;
	va_start (ap, data);
	while (1) {
		char *name = iks_name (x);
		char *tmp = va_arg (ap, char*);
		if (NULL == tmp) break;
		x = iks_find (x, tmp);
		if (!x) {
			PR_TEST;
			printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name);
			exit (1);
		}
	}
	if (iks_strcmp ( iks_cdata (iks_child (x)), data) != 0) {
		PR_TEST;
		printf ("CDATA [%s] not found.\n", data);
		exit (1);
	}
	va_end (ap);
}
示例#12
0
void
acl_init(void)
{
    iks *policy;
    iks *model;
    int class_no;
    int e;

    // parse security policy file
    e = iks_load("/etc/comar/security-policy.xml", &policy);
    if (e) {
        log_error("Cannot process security policy file '%s', error %d\n",
                  "/etc/comar/security-policy.xml", e);
        return;
    }
    if (iks_strcmp(iks_name(policy), "comarSecurityPolicy") != 0) {
        log_error("Not a security policy file '%s'\n",
                  "/etc/comar/security-policy.xml");
        return;
    }

    // call permissions on the model
    model = iks_find(policy, "model");
    if (model) {
        class_no = -1;
        while (model_next_class(&class_no)) {
            set_class(model, class_no);
        }
    }
}
示例#13
0
void
attrib (char *att, char *val, ...)
{
	iks *x;
	va_list ap;

	x = my_x;
	va_start (ap, val);
	while (1) {
		char *name = iks_name (x);
		char *tmp = va_arg (ap, char*);
		if (NULL == tmp) break;
		x = iks_find (x, tmp);
		if (!x) {
			PR_TEST;
			printf ("Tag <%s> is not a child of tag <%s>\n", tmp, name);
			exit (1);
		}
	}
	if (iks_strcmp (val, iks_find_attrib (x, att)) != 0) {
		PR_TEST;
		printf ("Attribute '%s' not found.\n", att);
		exit (1);
	}
	va_end (ap);
}
示例#14
0
static void
add_groups(iks *tag, int class_no, int level, struct acl_class *ac)
{
    iks *x;
    // global permissions
    for (x = iks_find(tag, "group"); x; x = iks_next_tag(x)) {
        if (iks_strcmp(iks_name(x), "group") == 0)
            add_group(x, level, ac);
    }
    // class permissions
    x = iks_find_with_attrib(tag, "class", "name", model_get_path(class_no));
    for (x = iks_find(x, "group"); x; x = iks_next_tag(x)) {
        if (iks_strcmp(iks_name(x), "group") == 0)
            add_group(x, level, ac);
    }
}
/**
 * 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;
}
示例#16
0
static int
count_groups(iks *tag, int class_no)
{
    iks *x;
    unsigned int nr = 0;
    // global permissions
    for (x = iks_find(tag, "group"); x; x = iks_next_tag(x)) {
        if (iks_strcmp(iks_name(x), "group") == 0)
            ++nr;
    }
    // class permissions
    x = iks_find_with_attrib(tag, "class", "name", model_get_path(class_no));
    for (x = iks_find(x, "group"); x; x = iks_next_tag(x)) {
        if (iks_strcmp(iks_name(x), "group") == 0)
            ++nr;
    }
    return nr;
}
示例#17
0
int axis2_xmpp_client_on_message(
    void *user_data,
    ikspak *pak)
{
    axis2_xmpp_session_data_t *session = NULL;
    axutil_env_t *env = NULL;
    iks* body_elem = NULL;
    iks* soap_elem = NULL;
    char *soap_str = NULL;
    char *from = NULL;
    char request_uri[500] = "";
    axis2_status_t status = AXIS2_SUCCESS;

    session = (axis2_xmpp_session_data_t*) user_data;
    env = session->env;
    /* Serialize the message and pass it up */

    /* extract the body of message */
    body_elem = iks_find(pak->x, "body");
    if(!body_elem)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[xmpp]Failed to extract body of "
            "message stanza");
        return IKS_FILTER_EAT;
    }

    soap_elem = iks_child(body_elem);
    if(!soap_elem)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[xmpp]Failed to extract soap envelope"
            "from message stanza");
        return IKS_FILTER_EAT;
    }

    soap_str = iks_string(iks_stack(soap_elem), soap_elem);
    if(!soap_str)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[xmpp]Failed to serialize the soap "
            "envelope");
        return IKS_FILTER_EAT;
    }

    snprintf(request_uri, 500, "xmpp://localhost/axis2/services/%s", axis2_svc_get_name(
        session->svc, env));

    from = iks_find_attrib(pak->x, "from");
    status = axis2_xmpp_transport_utils_process_message_client(session->env, session, soap_str,
        from, request_uri);

    /* TODO: Check whether we need to return IKS_HOOK on failure. I think not,
     * because, failure here means the failure of a single request. We should
     * keep running for other requests */
    session->in_msg = 1;
    return IKS_FILTER_EAT; /* no need to pass to other filters */
}
示例#18
0
char *
iks_find_cdata (iks *x, const char *name)
{
	iks *y;

	y = iks_find (x, name);
	if (!y) return NULL;
	y = IKS_TAG_CHILDREN (y);
	if (!y || IKS_CDATA != y->type) return NULL;
	return IKS_CDATA_CDATA (y);
}
示例#19
0
static void test_empty_cdata(void)
{
	iks *iq = NULL;
	iks *input = NULL;
	iksparser *p = iks_dom_new(&iq);
	const char *cdata;
	ASSERT_EQUALS(IKS_OK, iks_parse(p, empty_cdata, 0, 1));
	iks_parser_delete(p);
	ASSERT_NOT_NULL((input = iks_find(iq, "input")));
	ASSERT_NULL((cdata = iks_find_cdata(input, "grammar")));
	iks_delete(iq);
}
示例#20
0
static void test_repeating_bracket(void)
{
	iks *iq = NULL;
	iks *input = NULL;
	iksparser *p = iks_dom_new(&iq);
	const char *cdata;
	ASSERT_EQUALS(IKS_OK, iks_parse(p, repeating_bracket, 0, 1));
	iks_parser_delete(p);
	ASSERT_NOT_NULL((input = iks_find(iq, "input")));
	ASSERT_NOT_NULL((cdata = iks_find_cdata(input, "grammar")));
	ASSERT_STRING_EQUALS("[1 DIGITS]>]]]]]]]]] ]] ", cdata);
	iks_delete(iq);
}
示例#21
0
/**
 * Create new output component
 */
static struct rayo_component *create_output_component(struct rayo_actor *actor, const char *type, iks *output, const char *client_jid)
{
	switch_memory_pool_t *pool;
	struct output_component *output_component = NULL;

	switch_core_new_memory_pool(&pool);
	output_component = switch_core_alloc(pool, sizeof(*output_component));
	output_component = OUTPUT_COMPONENT(rayo_component_init((struct rayo_component *)output_component, pool, type, "output", NULL, actor, client_jid));
	if (output_component) {
		output_component->document = iks_copy(output);
		output_component->start_offset_ms = iks_find_int_attrib(output, "start-offset");
		output_component->repeat_interval_ms = iks_find_int_attrib(output, "repeat-interval");
		output_component->repeat_times = iks_find_int_attrib(output, "repeat-times");
		output_component->max_time_ms = iks_find_int_attrib(output, "max-time");
		output_component->start_paused = iks_find_bool_attrib(output, "start-paused");
		output_component->renderer = switch_core_strdup(RAYO_POOL(output_component), iks_find_attrib_soft(output, "renderer"));
		/* get custom headers */
		{
			switch_stream_handle_t headers = { 0 };
			iks *header = NULL;
			int first = 1;
			SWITCH_STANDARD_STREAM(headers);
			for (header = iks_find(output, "header"); header; header = iks_next_tag(header)) {
				if (!strcmp("header", iks_name(header))) {
					const char *name = iks_find_attrib_soft(header, "name");
					const char *value = iks_find_attrib_soft(header, "value");
					if (!zstr(name) && !zstr(value)) {
						headers.write_function(&headers, "%s%s=%s", first ? "{" : ",", name, value);
						first = 0;
					}
				}
			}
			if (headers.data) {
				headers.write_function(&headers, "}");
				output_component->headers = switch_core_strdup(RAYO_POOL(output_component), (char *)headers.data);
				free(headers.data);
			}
		}
	} else {
		switch_core_destroy_memory_pool(&pool);
	}

	return RAYO_COMPONENT(output_component);
}
/**
 * Start execution of call record component
 */
static iks *start_call_record_component(struct rayo_actor *client, struct rayo_actor *call, iks *iq, void *session_data)
{
	switch_core_session_t *session = (switch_core_session_t *)session_data;
	struct rayo_component *component = NULL;
	iks *record = iks_find(iq, "record");

	component = record_component_create(call, iks_find_attrib(iq, "from"), record);
	if (!component) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	if (start_call_record(session, component)) {
		rayo_component_send_start(component, iq);
	} else {
		RAYO_UNLOCK(component);
		RAYO_DESTROY(component);
		return iks_new_error(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR);
	}

	return NULL;
}
示例#23
0
/**
 * Seek output component
 */
static iks *seek_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data)
{
	iks *iq = msg->payload;
	iks *seek = iks_find(iq, "seek");

	if (VALIDATE_RAYO_OUTPUT_SEEK(seek)) {
		int is_forward = !strcmp("forward", iks_find_attrib(seek, "direction"));
		int amount_ms = iks_find_int_attrib(seek, "amount");
		char *command = switch_mprintf("%s seek:%s%i", RAYO_JID(component),
			is_forward ? "+" : "-", amount_ms);
		switch_stream_handle_t stream = { 0 };
		SWITCH_STANDARD_STREAM(stream);

		switch_api_execute("fileman", command, NULL, &stream);

		switch_safe_free(stream.data);
		switch_safe_free(command);

		return iks_new_iq_result(iq);
	}
	return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
}
示例#24
0
static void
set_class(iks *model, int class_no)
{
    struct acl_class *ac;
    int nr_groups = 0;

    nr_groups += count_groups(iks_find(model, "admin"), class_no);
    nr_groups += count_groups(iks_find(model, "user"), class_no);
    nr_groups += count_groups(iks_find(model, "guest"), class_no);

    ac = calloc(1, sizeof(struct acl_class) + (nr_groups * sizeof(struct acl_group)));
    if (!ac) return;
    ac->nr_groups = nr_groups;

    add_groups(iks_find(model, "admin"), class_no, ACL_ADMIN, ac);
    add_groups(iks_find(model, "user"), class_no, ACL_USER, ac);
    add_groups(iks_find(model, "guest"), class_no, ACL_GUEST, ac);

    model_acl_set(class_no, ac);
}
示例#25
0
/**
 * Start execution of call receivefax component
 * @param call the call to receive fax from
 * @param msg the original request
 * @param session_data the call's session
 */
static iks *start_receivefax_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;
	struct receivefax_component *receivefax_component = NULL;
	iks *receivefax = iks_find(iq, "receivefax");
	iks *response = NULL;
	switch_event_t *execute_event = NULL;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_memory_pool_t *pool;
	int file_no;

	/* validate attributes */
	if (!VALIDATE_RAYO_RECEIVEFAX(receivefax)) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	/* fax is only allowed if the call is not currently joined */
	if (rayo_call_is_joined(RAYO_CALL(call))) {
		return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't receive fax on a joined call");
	}

	if (rayo_call_is_faxing(RAYO_CALL(call))) {
		return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress");
	}

	/* create receivefax component */
	switch_core_new_memory_pool(&pool);
	receivefax_component = switch_core_alloc(pool, sizeof(*receivefax_component));
	rayo_component_init((struct rayo_component *)receivefax_component, pool, RAT_CALL_COMPONENT, "receivefax", NULL, call, iks_find_attrib(iq, "from"));
	file_no = rayo_actor_seq_next(call);
	receivefax_component->filename = switch_core_sprintf(pool, "%s%s%s-%d.tif",
		globals.file_prefix, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no);
	if (!strncmp(receivefax_component->filename, "http://", 7) || !strncmp(receivefax_component->filename, "https://", 8)) {
		/* This is an HTTP URL, need to PUT after fax is received */
		receivefax_component->local_filename = switch_core_sprintf(pool, "%s%s%s-%d",
			SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no);
		receivefax_component->http_put_after_receive = 1;
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s save fax to HTTP URL\n", RAYO_JID(receivefax_component));
	} else {
		/* assume file.. */
		receivefax_component->local_filename = receivefax_component->filename;
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s save fax to local file\n", RAYO_JID(receivefax_component));
	}

	/* add channel variable so that fax component can be located from fax events */
	switch_channel_set_variable(channel, "rayo_fax_jid", RAYO_JID(receivefax_component));

	/* clear fax result variables */
	switch_channel_set_variable(channel, "fax_success", NULL);
	switch_channel_set_variable(channel, "fax_result_code", NULL);
	switch_channel_set_variable(channel, "fax_result_text", NULL);
	switch_channel_set_variable(channel, "fax_document_transferred_pages", NULL);
	switch_channel_set_variable(channel, "fax_document_total_pages", NULL);
	switch_channel_set_variable(channel, "fax_image_resolution", NULL);
	switch_channel_set_variable(channel, "fax_image_size", NULL);
	switch_channel_set_variable(channel, "fax_bad_rows", NULL);
	switch_channel_set_variable(channel, "fax_transfer_rate", NULL);
	switch_channel_set_variable(channel, "fax_ecm_used", NULL);
	switch_channel_set_variable(channel, "fax_local_station_id", NULL);
	switch_channel_set_variable(channel, "fax_remote_station_id", NULL);

	/* clear fax interrupt variable */
	switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL);

	rayo_call_set_faxing(RAYO_CALL(call), 1);

	/* execute rxfax APP */
	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", "rxfax");
		switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", receivefax_component->local_filename);
		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(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to rxfax (queue event failed)");
			if (execute_event) {
				switch_event_destroy(&execute_event);
			}
			rayo_call_set_faxing(RAYO_CALL(call), 0);
			RAYO_UNLOCK(receivefax_component);
		} else {
			/* component starting... */
			rayo_component_send_start(RAYO_COMPONENT(receivefax_component), iq);
		}
	} else {
		response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create rxfax event");
		rayo_call_set_faxing(RAYO_CALL(call), 0);
		RAYO_UNLOCK(receivefax_component);
	}

	return response;
}
示例#26
0
/**
 * open next file for reading
 * @param handle the file handle
 */
static switch_status_t next_file(switch_file_handle_t *handle)
{
	int loops = 0;
	struct rayo_file_context *context = handle->private_info;
	struct output_component *output = context->component ? OUTPUT_COMPONENT(context->component) : NULL;

  top:

	if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) {
		switch_core_file_close(&context->fh);
	}

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
		/* unsupported */
		return SWITCH_STATUS_FALSE;
	}

	if (!context->cur_doc) {
		context->cur_doc = iks_find(output->document, "document");
		if (!context->cur_doc) {
			iks_delete(output->document);
			output->document = NULL;
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document>\n");
			return SWITCH_STATUS_FALSE;
		}
	} else {
		context->cur_doc = iks_next_tag(context->cur_doc);
	}

	/* done? */
	if (!context->cur_doc) {
		if (context->could_open && ++loops < 2 && (output->repeat_times == 0 || ++context->play_count < output->repeat_times)) {
			/* repeat all document(s) */
			if (!output->repeat_interval_ms) {
				goto top;
			}
		} else {
			/* no more files to play */
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Done playing\n");
			return SWITCH_STATUS_FALSE;
		}
	}

	if (!context->cur_doc) {
		/* play silence between repeats */
		switch_safe_free(context->ssml);
		context->ssml = switch_mprintf("silence_stream://%i", output->repeat_interval_ms);
	} else {
		/* play next document */
		iks *speak = NULL;

		switch_safe_free(context->ssml);
		context->ssml = NULL;
 		speak = iks_find(context->cur_doc, "speak");
		if (speak) {
			/* <speak> is child node */
			char *ssml_str = iks_string(NULL, speak);
			if (zstr(output->renderer)) {
				/* FS must parse the SSML */
				context->ssml = switch_mprintf("ssml://%s", ssml_str);
			} else {
				/* renderer will parse the SSML */
				if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) {
					/* pass MRCP headers */
					context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str);
				} else {
					context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str);
				}
			}
			iks_free(ssml_str);
		} else if (iks_has_children(context->cur_doc)) {
			/* check if <speak> is in CDATA */
			const char *ssml_str = NULL;
			iks *ssml = iks_child(context->cur_doc);
			if (ssml && iks_type(ssml) == IKS_CDATA) {
				ssml_str = iks_cdata(ssml);
			}
			if (zstr(ssml_str)) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document> CDATA\n");
				return SWITCH_STATUS_FALSE;
			}
			if (zstr(output->renderer)) {
				/* FS must parse the SSML */
				context->ssml = switch_mprintf("ssml://%s", ssml_str);
			} else {
				/* renderer will parse the SSML */
				if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) {
					/* pass MRCP headers */
					context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str);
				} else {
					context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str);
				}
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <speak>\n");
			return SWITCH_STATUS_FALSE;
		}
	}
	if (switch_core_file_open(&context->fh, context->ssml, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to open %s\n", context->ssml);
		goto top;
	} else {
		context->could_open = 1;
	}

	handle->samples = context->fh.samples;
	handle->format = context->fh.format;
	handle->sections = context->fh.sections;
	handle->seekable = context->fh.seekable;
	handle->speed = context->fh.speed;
	handle->vol = context->fh.vol;
	handle->offset_pos = context->fh.offset_pos;
	handle->interval = context->fh.interval;

	if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
		switch_set_flag(handle, SWITCH_FILE_NATIVE);
	} else {
		switch_clear_flag(handle, SWITCH_FILE_NATIVE);
	}

	return SWITCH_STATUS_SUCCESS;
}
示例#27
0
void
r_draw_gradient (ImpRenderCtx *ctx, void *drw_data, iks *node)
{
//	GdkGC *gc;
	Gradient grad;
	char *stil, *tmp;
	iks *x;

	stil = r_get_style (ctx, node, "draw:fill-gradient-name");
	x = iks_find_with_attrib (iks_find (ctx->styles, "office:styles"),
		"draw:gradient", "draw:name", stil);
	if (x) {
		memset (&grad, 0, sizeof (Gradient));
		grad.type = -1;
		grad.offset_x = 50;
		grad.offset_y = 50;

		tmp = iks_find_attrib (x, "draw:start-color");
		if (tmp) r_parse_color (tmp, &grad.start);
		tmp = iks_find_attrib (x, "draw:start-intensity");
		if (tmp) {
			int val = atoi (tmp);
			grad.start.red = grad.start.red * val / 100;
			grad.start.green = grad.start.green * val / 100;
			grad.start.blue = grad.start.blue * val / 100;
		}
		tmp = iks_find_attrib (x, "draw:end-color");
		if (tmp) r_parse_color (tmp, &grad.end);
		tmp = iks_find_attrib (x, "draw:end-intensity");
		if (tmp) {
			int val = atoi (tmp);
			grad.end.red = grad.end.red * val / 100;
			grad.end.green = grad.end.green * val / 100;
			grad.end.blue = grad.end.blue * val / 100;
		}
		tmp = iks_find_attrib (x, "draw:angle");
		if (tmp) grad.angle = atoi(tmp) % 3600;
		tmp = iks_find_attrib (x, "draw:border");
		if (tmp) grad.border = atoi(tmp);
		tmp = r_get_style (ctx, node, "draw:gradient-step-count");
		if (tmp) grad.steps = atoi (tmp);
		tmp = iks_find_attrib (x, "draw:cx");
		if (tmp) grad.offset_x = atoi (tmp);
		tmp = iks_find_attrib (x, "draw:cy");
		if (tmp) grad.offset_y = atoi (tmp);
		tmp = iks_find_attrib (x, "draw:style");
		if (iks_strcmp (tmp, "linear") == 0)
			grad.type = GRAD_LINEAR;
		else if (iks_strcmp (tmp, "axial") == 0)
			grad.type = GRAD_AXIAL;
		else if (iks_strcmp (tmp, "radial") == 0)
			grad.type = GRAD_RADIAL;
		else if (iks_strcmp (tmp, "rectangular") == 0)
			grad.type = GRAD_RECTANGULAR;
		else if (iks_strcmp (tmp, "ellipsoid") == 0)
			grad.type = GRAD_ELLIPTICAL;
		else if (iks_strcmp (tmp, "square") == 0)
			grad.type = GRAD_SQUARE;

		if (grad.type == -1) return;

//		gc = ctx->gc;
//		ctx->gc = gdk_gc_new (ctx->d);
//		gdk_gc_copy (ctx->gc, gc);

		if (grad.type == GRAD_LINEAR || grad.type == GRAD_AXIAL)
			r_draw_gradient_simple (ctx, drw_data, &grad);
		else
			r_draw_gradient_complex (ctx, drw_data, &grad);

//		g_object_unref (ctx->gc);
//		ctx->gc = gc;
	}
}
示例#28
0
/**
 * Handle fax completion event from FreeSWITCH core
 * @param event received from FreeSWITCH core.  It will be destroyed by the core after this function returns.
 */
static void on_execute_complete_event(switch_event_t *event)
{
	const char *application = switch_event_get_header(event, "Application");
	
	if (!zstr(application) && (!strcmp(application, "rxfax") || !strcmp(application, "txfax"))) {
		int is_rxfax = !strcmp(application, "rxfax");
		const char *uuid = switch_event_get_header(event, "Unique-ID");
		const char *fax_jid = switch_event_get_header(event, "variable_rayo_fax_jid");
		struct rayo_actor *component;
		if (!zstr(fax_jid) && (component = RAYO_LOCATE(fax_jid))) {
			iks *result;
			iks *complete;
			iks *fax;
			int have_fax_document = 1;
			switch_core_session_t *session;
			switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got result for %s\n", fax_jid);

			/* clean up channel */
			session = switch_core_session_locate(uuid);
			if (session) {
				switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL);
				switch_core_session_rwunlock(session);
			}

			/* RX only: transfer HTTP document and delete local copy */
			if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) {
				switch_stream_handle_t stream = { 0 };
				SWITCH_STANDARD_STREAM(stream);
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename);
				switch_api_execute("http_put", RECEIVEFAX_COMPONENT(component)->filename, NULL, &stream);
				/* check if successful */
				if (!zstr(stream.data) && strncmp(stream.data, "+OK", 3)) {
					/* PUT failed */
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s failed: %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename, (char *)stream.data);
					have_fax_document = 0;
				}
				switch_safe_free(stream.data)
				switch_file_remove(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component));
			}

			/* successful fax? */
			if (have_fax_document && switch_true(switch_event_get_header(event, "variable_fax_success"))) {
				result = rayo_component_create_complete_event(RAYO_COMPONENT(component), FAX_FINISH);
			} else if (have_fax_document && FAX_COMPONENT(component)->stop)  {
				result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP);
			} else {
				result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR);
			}
			complete = iks_find(result, "complete");

			/* RX only: add fax document information */
			if (is_rxfax && have_fax_document) {
				const char *pages = switch_event_get_header(event, "variable_fax_document_transferred_pages");
				if (!zstr(pages) && switch_is_number(pages) && atoi(pages) > 0) {
					const char *resolution = switch_event_get_header(event, "variable_fax_file_image_resolution");
					const char *size = switch_event_get_header(event, "variable_fax_image_size");

					fax = iks_insert(complete, "fax");
					iks_insert_attrib(fax, "xmlns", RAYO_FAX_COMPLETE_NS);

					if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive) {
						iks_insert_attrib(fax, "url", RECEIVEFAX_COMPONENT(component)->filename);
					} else {
						/* convert absolute path to file:// URI */
						iks_insert_attrib_printf(fax, "url", "file://%s", RECEIVEFAX_COMPONENT(component)->filename);
					}

					if (!zstr(resolution)) {
						iks_insert_attrib(fax, "resolution", resolution);
					}
					if (!zstr(size)) {
						iks_insert_attrib(fax, "size", size);
					}
					iks_insert_attrib(fax, "pages", pages);
				}
			}

			/* add metadata from event */
			insert_fax_metadata(event, "fax_success", complete);
			insert_fax_metadata(event, "fax_result_code", complete);
			insert_fax_metadata(event, "fax_result_text", complete);
			insert_fax_metadata(event, "fax_document_transferred_pages", complete);
			insert_fax_metadata(event, "fax_document_total_pages", complete);
			insert_fax_metadata(event, "fax_image_resolution", complete);
			insert_fax_metadata(event, "fax_image_size", complete);
			insert_fax_metadata(event, "fax_bad_rows", complete);
			insert_fax_metadata(event, "fax_transfer_rate", complete);
			insert_fax_metadata(event, "fax_ecm_used", complete);
			insert_fax_metadata(event, "fax_local_station_id", complete);
			insert_fax_metadata(event, "fax_remote_station_id", complete);

			/* flag faxing as done */
			rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0);

			rayo_component_send_complete_event(RAYO_COMPONENT(component), result);

			RAYO_UNLOCK(component);
		}
	}
}
示例#29
0
/**
 * Start execution of call sendfax component
 * @param call the call to send fax to
 * @param msg the original request
 * @param session_data the call's session
 */
static iks *start_sendfax_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;
	struct fax_component *sendfax_component = NULL;
	iks *sendfax = iks_find(iq, "sendfax");
	iks *response = NULL;
	switch_event_t *execute_event = NULL;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_memory_pool_t *pool;
	iks *document;
	const char *fax_document;
	const char *fax_header;
	const char *fax_identity;
	const char *pages;

	/* validate attributes */
	if (!VALIDATE_RAYO_SENDFAX(sendfax)) {
		return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST);
	}

	/* fax is only allowed if the call is not currently joined */
	if (rayo_call_is_joined(RAYO_CALL(call))) {
		return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't send fax on a joined call");
	}

	if (rayo_call_is_faxing(RAYO_CALL(call))) {
		return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress");
	}

	/* get fax document */
	document = iks_find(sendfax, "document");
	if (!document) {
		return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "missing document");
	}
	fax_document = iks_find_attrib_soft(document, "url");
	if (zstr(fax_document)) {
		return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "missing document url");
	}

	/* is valid URL type? */
	if (!strncasecmp(fax_document, "http://", 7) || !strncasecmp(fax_document, "https://", 8)) {
		switch_stream_handle_t stream = { 0 };
		SWITCH_STANDARD_STREAM(stream);
		/* need to fetch document from server... */
		switch_api_execute("http_get", fax_document, session, &stream);
		if (!zstr(stream.data) && !strncmp(fax_document, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) {
			fax_document = switch_core_session_strdup(session, stream.data);
		} else {
			switch_safe_free(stream.data);
			return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to fetch document");
		}
		switch_safe_free(stream.data);
	} else if (!strncasecmp(fax_document, "file://", 7)) {
		fax_document = fax_document + 7;
		if (zstr(fax_document)) {
			return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid file:// url");
		}
	} else if (strncasecmp(fax_document, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) {
		return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "unsupported url type");
	}

	/* does document exist? */
	if (switch_file_exists(fax_document, pool) != SWITCH_STATUS_SUCCESS) {
		return iks_new_error_detailed_printf(iq, STANZA_ERROR_BAD_REQUEST, "file not found: %s", fax_document);
	}

	/* get fax identity and header */
	fax_identity = iks_find_attrib_soft(document, "identity");
	if (!zstr(fax_identity)) {
		switch_channel_set_variable(channel, "fax_ident", fax_identity);
	} else {
		switch_channel_set_variable(channel, "fax_ident", NULL);
	}
	fax_header = iks_find_attrib_soft(document, "header");
	if (!zstr(fax_header)) {
		switch_channel_set_variable(channel, "fax_header", fax_header);
	} else {
		switch_channel_set_variable(channel, "fax_header", NULL);
	}

	/* get pages to send */
	pages = iks_find_attrib_soft(document, "pages");
	if (!zstr(pages)) {
		if (switch_regex_match(pages, "[1-9][0-9]*(-[1-9][0-9]*)?") == SWITCH_STATUS_FALSE) {
			return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid pages value");
		} else {
			int start = 0;
			int end = 0;
			char *pages_dup = switch_core_session_strdup(session, pages);
			char *sep = strchr(pages_dup, '-');
			if (sep) {
				*sep = '\0';
				sep++;
				end = atoi(sep);
			}
			start = atoi(pages_dup);
			if (end && end < start) {
				return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid pages value");
			}
			switch_channel_set_variable(channel, "fax_start_page", pages_dup);
			switch_channel_set_variable(channel, "fax_end_page", sep);
		}
	} else {
		switch_channel_set_variable(channel, "fax_start_page", NULL);
		switch_channel_set_variable(channel, "fax_end_page", NULL);
	}

	/* create sendfax component */
	switch_core_new_memory_pool(&pool);
	sendfax_component = switch_core_alloc(pool, sizeof(*sendfax_component));
	rayo_component_init((struct rayo_component *)sendfax_component, pool, RAT_CALL_COMPONENT, "sendfax", NULL, call, iks_find_attrib(iq, "from"));

	/* add channel variable so that fax component can be located from fax events */
	switch_channel_set_variable(channel, "rayo_fax_jid", RAYO_JID(sendfax_component));

	/* clear fax result variables */
	switch_channel_set_variable(channel, "fax_success", NULL);
	switch_channel_set_variable(channel, "fax_result_code", NULL);
	switch_channel_set_variable(channel, "fax_result_text", NULL);
	switch_channel_set_variable(channel, "fax_document_transferred_pages", NULL);
	switch_channel_set_variable(channel, "fax_document_total_pages", NULL);
	switch_channel_set_variable(channel, "fax_image_resolution", NULL);
	switch_channel_set_variable(channel, "fax_image_size", NULL);
	switch_channel_set_variable(channel, "fax_bad_rows", NULL);
	switch_channel_set_variable(channel, "fax_transfer_rate", NULL);
	switch_channel_set_variable(channel, "fax_ecm_used", NULL);
	switch_channel_set_variable(channel, "fax_local_station_id", NULL);
	switch_channel_set_variable(channel, "fax_remote_station_id", NULL);

	/* clear fax interrupt variable */
	switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL);

	rayo_call_set_faxing(RAYO_CALL(call), 1);

	/* execute txfax APP */
	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", "txfax");
		switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", fax_document);
		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(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to txfax (queue event failed)");
			if (execute_event) {
				switch_event_destroy(&execute_event);
			}
			rayo_call_set_faxing(RAYO_CALL(call), 0);
			RAYO_UNLOCK(sendfax_component);
		} else {
			/* component starting... */
			rayo_component_send_start(RAYO_COMPONENT(sendfax_component), iq);
		}
	} else {
		response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create txfax event");
		rayo_call_set_faxing(RAYO_CALL(call), 0);
		RAYO_UNLOCK(sendfax_component);
	}

	return response;
}
示例#30
0
/**
 * Start CPA
 */
iks *rayo_cpa_component_start(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;
    iks *input = iks_find(iq, "input");
    switch_memory_pool_t *pool = NULL;
    struct cpa_component *component = NULL;
    int have_grammar = 0;
    iks *grammar = NULL;

    /* create CPA component */
    switch_core_new_memory_pool(&pool);
    component = switch_core_alloc(pool, sizeof(*component));
    component = CPA_COMPONENT(rayo_component_init((struct rayo_component *)component, pool, RAT_CALL_COMPONENT, "cpa", NULL, call, iks_find_attrib(iq, "from")));
    if (!component) {
        switch_core_destroy_memory_pool(&pool);
        return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to create CPA entity");
    }

    switch_core_hash_init(&component->signals);

    /* start CPA detectors */
    for (grammar = iks_find(input, "grammar"); grammar; grammar = iks_next_tag(grammar)) {
        if (!strcmp("grammar", iks_name(grammar))) {
            const char *error_str = "";
            const char *url = iks_find_attrib_soft(grammar, "url");
            char *url_dup;
            char *url_params;

            if (zstr(url)) {
                stop_cpa_detectors(component);
                RAYO_UNLOCK(component);
                RAYO_DESTROY(component);
                return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing grammar URL");
            }
            have_grammar = 1;

            url_dup = strdup(url);
            if ((url_params = strchr(url_dup, '?'))) {
                *url_params = '\0';
                url_params++;
            }

            if (switch_core_hash_find(component->signals, url)) {
                free(url_dup);
                stop_cpa_detectors(component);
                RAYO_UNLOCK(component);
                RAYO_DESTROY(component);
                return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Duplicate URL");
            }

            /* start detector */
            /* TODO return better reasons... */
            if (rayo_cpa_detector_start(switch_core_session_get_uuid(session), url_dup, &error_str)) {
                struct cpa_signal *cpa_signal = switch_core_alloc(pool, sizeof(*cpa_signal));
                cpa_signal->terminate = !zstr(url_params) && strstr(url_params, "terminate=true");
                cpa_signal->name = switch_core_strdup(pool, url_dup);
                switch_core_hash_insert(component->signals, cpa_signal->name, cpa_signal);
                subscribe(switch_core_session_get_uuid(session), cpa_signal->name, RAYO_JID(component));
            } else {
                free(url_dup);
                stop_cpa_detectors(component);
                RAYO_UNLOCK(component);
                RAYO_DESTROY(component);
                return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, error_str);
            }

            free(url_dup);
        }
    }

    if (!have_grammar) {
        stop_cpa_detectors(component);
        RAYO_UNLOCK(component);
        RAYO_DESTROY(component);
        return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "No grammar defined");
    }

    /* acknowledge command */
    rayo_component_send_start(RAYO_COMPONENT(component), iq);

    /* TODO hangup race condition */
    subscribe(switch_core_session_get_uuid(session), "hangup", RAYO_JID(component));

    /* ready to forward detector events */
    component->ready = 1;

    return NULL;
}