/** * 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); }
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); }
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; }
/** * 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; }
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; }
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); } }
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); }
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); } } }
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); }
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; }
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; }
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 */ }
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); }
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); }
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); }
/** * 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; }
/** * 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); }
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); }
/** * 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; }
/** * 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; }
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; } }
/** * 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); } } }
/** * 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; }
/** * 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; }