From f97ca68f8e47299954b3854f0606552b9a0d7144 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 7 Nov 2013 20:31:58 -0500 Subject: [PATCH] mod_rayo: add component --- src/mod/event_handlers/mod_rayo/Makefile | 4 +- .../conf/autoload_configs/rayo.conf.xml | 8 +- src/mod/event_handlers/mod_rayo/mod_rayo.c | 14 +- .../event_handlers/mod_rayo/rayo_components.c | 4 +- .../event_handlers/mod_rayo/rayo_components.h | 4 +- .../event_handlers/mod_rayo/rayo_elements.c | 32 ++- .../event_handlers/mod_rayo/rayo_elements.h | 5 +- ...efax_component.c => rayo_fax_components.c} | 243 +++++++++++++++--- 8 files changed, 257 insertions(+), 57 deletions(-) rename src/mod/event_handlers/mod_rayo/{rayo_receivefax_component.c => rayo_fax_components.c} (60%) diff --git a/src/mod/event_handlers/mod_rayo/Makefile b/src/mod/event_handlers/mod_rayo/Makefile index bfb38dbd6c..a3bfc45d47 100644 --- a/src/mod/event_handlers/mod_rayo/Makefile +++ b/src/mod/event_handlers/mod_rayo/Makefile @@ -11,10 +11,10 @@ LOCAL_OBJS= $(IKS_LA) \ nlsml.o \ rayo_components.o \ rayo_elements.o \ + rayo_fax_components.o \ rayo_input_component.o \ rayo_output_component.o \ rayo_prompt_component.o \ - rayo_receivefax_component.o \ rayo_record_component.o \ sasl.o \ srgs.o \ @@ -24,11 +24,11 @@ LOCAL_SOURCES= \ nlsml.c \ rayo_components.c \ rayo_elements.c \ + rayo_fax_components.c \ rayo_input_component.c \ rayo_output_component.c \ rayo_prompt_component.c \ rayo_record_component.c \ - rayo_receivefax_component.c \ sasl.c \ srgs.c \ xmpp_streams.c diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index c8171569af..3fdc772daf 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -16,11 +16,11 @@ - - + + - - + + diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 51d1614751..f852d2c5f8 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -952,6 +952,7 @@ static void rayo_call_cleanup(struct rayo_actor *actor) iks_delete(revent); switch_event_destroy(&event); + switch_core_hash_destroy(&call->pcps); } /** @@ -1130,13 +1131,23 @@ static struct rayo_call *_rayo_call_create(const char *uuid, const char *file, i return rayo_call_init(call, pool, uuid, file, line); } +/** + * Mixer destructor + */ +static void rayo_mixer_cleanup(struct rayo_actor *actor) +{ + struct rayo_mixer *mixer = RAYO_MIXER(actor); + switch_core_hash_destroy(&mixer->members); + switch_core_hash_destroy(&mixer->subscribers); +} + /** * Initialize mixer */ static struct rayo_mixer *rayo_mixer_init(struct rayo_mixer *mixer, switch_memory_pool_t *pool, const char *name, const char *file, int line) { char *mixer_jid = switch_mprintf("%s@%s", name, RAYO_JID(globals.server)); - rayo_actor_init(RAYO_ACTOR(mixer), pool, RAT_MIXER, "", name, mixer_jid, NULL, rayo_mixer_send, file, line); + rayo_actor_init(RAYO_ACTOR(mixer), pool, RAT_MIXER, "", name, mixer_jid, rayo_mixer_cleanup, rayo_mixer_send, file, line); switch_core_hash_init(&mixer->members, pool); switch_core_hash_init(&mixer->subscribers, pool); switch_safe_free(mixer_jid); @@ -1307,6 +1318,7 @@ static void rayo_peer_server_cleanup(struct rayo_actor *actor) RAYO_UNLOCK(client); RAYO_DESTROY(client); } + switch_core_hash_destroy(&rserver->clients); switch_mutex_unlock(globals.clients_mutex); } diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.c b/src/mod/event_handlers/mod_rayo/rayo_components.c index 2448e166a8..7ad96d2a7d 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_components.c @@ -227,7 +227,7 @@ switch_status_t rayo_components_load(switch_loadable_module_interface_t **module rayo_output_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || rayo_prompt_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || rayo_record_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || - rayo_receivefax_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS) { + rayo_fax_components_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_TERM; } return SWITCH_STATUS_SUCCESS; @@ -242,7 +242,7 @@ switch_status_t rayo_components_shutdown(void) rayo_output_component_shutdown(); rayo_prompt_component_shutdown(); rayo_record_component_shutdown(); - rayo_receivefax_component_shutdown(); + rayo_fax_components_shutdown(); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.h b/src/mod/event_handlers/mod_rayo/rayo_components.h index 8d3909dd4d..5d1367d645 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.h +++ b/src/mod/event_handlers/mod_rayo/rayo_components.h @@ -61,14 +61,14 @@ extern switch_status_t rayo_input_component_load(switch_loadable_module_interfac extern switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -extern switch_status_t rayo_receivefax_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); +extern switch_status_t rayo_fax_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_components_shutdown(void); extern switch_status_t rayo_input_component_shutdown(void); extern switch_status_t rayo_output_component_shutdown(void); extern switch_status_t rayo_prompt_component_shutdown(void); extern switch_status_t rayo_record_component_shutdown(void); -extern switch_status_t rayo_receivefax_component_shutdown(void); +extern switch_status_t rayo_fax_components_shutdown(void); extern void rayo_component_send_start(struct rayo_component *component, iks *iq); extern void rayo_component_send_iq_error(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type); diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.c b/src/mod/event_handlers/mod_rayo/rayo_elements.c index a6e4f09140..78209c3bd6 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.c +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.c @@ -49,6 +49,17 @@ ELEMENT(RAYO_INPUT) ATTRIB(start-timers, true, bool) ELEMENT_END +/** + * command validation + */ +ELEMENT(RAYO_JOIN) + ATTRIB(xmlns,, any) + STRING_ATTRIB(direction, duplex, "send,recv,duplex") + STRING_ATTRIB(media, bridge, "bridge,direct") + ATTRIB(call-uri,, any) + ATTRIB(mixer-name,, any) +ELEMENT_END + /** * component validation */ @@ -80,6 +91,13 @@ ELEMENT(RAYO_PROMPT) ATTRIB(barge-in, true, bool) ELEMENT_END +/** + * command validation + */ +ELEMENT(RAYO_RECEIVEFAX) + ATTRIB(xmlns,, any) +ELEMENT_END + /** * component validation */ @@ -97,22 +115,12 @@ ELEMENT(RAYO_RECORD) ELEMENT_END /** - * command validation + * command validation */ -ELEMENT(RAYO_JOIN) +ELEMENT(RAYO_SENDFAX) ATTRIB(xmlns,, any) - STRING_ATTRIB(direction, duplex, "send,recv,duplex") - STRING_ATTRIB(media, bridge, "bridge,direct") - ATTRIB(call-uri,, any) - ATTRIB(mixer-name,, any) ELEMENT_END -/** - * command validation - */ -ELEMENT(RAYO_RECEIVEFAX) - ATTRIB(xmlns,, any) -ELEMENT_END /* For Emacs: * Local Variables: diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.h b/src/mod/event_handlers/mod_rayo/rayo_elements.h index 4c061dc35e..e76809cc9e 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.h +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.h @@ -32,12 +32,13 @@ #include "iks_helpers.h" ELEMENT_DECL(RAYO_INPUT) +ELEMENT_DECL(RAYO_JOIN) ELEMENT_DECL(RAYO_OUTPUT) ELEMENT_DECL(RAYO_OUTPUT_SEEK) ELEMENT_DECL(RAYO_PROMPT) -ELEMENT_DECL(RAYO_RECORD) -ELEMENT_DECL(RAYO_JOIN) ELEMENT_DECL(RAYO_RECEIVEFAX) +ELEMENT_DECL(RAYO_RECORD) +ELEMENT_DECL(RAYO_SENDFAX) #endif diff --git a/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c similarity index 60% rename from src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c rename to src/mod/event_handlers/mod_rayo/rayo_fax_components.c index 75528f8b52..9cd48e2c2c 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c @@ -23,7 +23,7 @@ * Contributor(s): * Chris Rienzo * - * rayo_receivefax_component.c -- Rayo receivefax component implementation + * rayo_fax_components.c -- Rayo receivefax and sendfax components implementation * */ #include "rayo_components.h" @@ -36,23 +36,197 @@ static struct { const char *file_prefix; } globals; -struct receivefax_component { +struct fax_component { /** component base class */ struct rayo_component base; + /** Flag to stop fax */ + int stop; +}; + +#define FAX_COMPONENT(x) ((struct fax_component *)x) + +struct receivefax_component { + /** fax component base class */ + struct fax_component base; /** true if HTTP PUT needs to be done after fax is received */ int http_put_after_receive; /** fax stored on local filesystem */ const char *local_filename; /** fax final target (may be same as local filename) */ const char *filename; - /** Flag to stop fax */ - int stop; }; -#define RECEIVEFAX_FINISH "finish", RAYO_FAX_COMPLETE_NS - #define RECEIVEFAX_COMPONENT(x) ((struct receivefax_component *)x) +#define FAX_FINISH "finish", RAYO_FAX_COMPLETE_NS + +/** + * 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_set_faxing(RAYO_CALL(call), 1)) { + 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) && !strncasecmp(fax_document, SWITCH_PATH_SEPARATOR, sizeof(SWITCH_PATH_SEPARATOR) - 1)) { + 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, sizeof(SWITCH_PATH_SEPARATOR) - 1)) { + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "unsupported url type"); + } + + /* does document exist? */ + if (!switch_file_exists(fax_document, pool)) { + 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); + + /* 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); + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); + 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_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_UNLOCK(sendfax_component); + } + + return response; +} + /** * Start execution of call receivefax component * @param call the call to receive fax from @@ -153,9 +327,9 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess } /** - * Stop execution of receivefax component + * Stop execution of fax component */ -static iks *stop_receivefax_component(struct rayo_actor *component, struct rayo_message *msg, void *data) +static iks *stop_fax_component(struct rayo_actor *component, struct rayo_message *msg, void *data) { iks *iq = msg->payload; switch_core_session_t *session = switch_core_session_locate(RAYO_COMPONENT(component)->parent->id); @@ -164,7 +338,7 @@ static iks *stop_receivefax_component(struct rayo_actor *component, struct rayo_ switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", RAYO_JID(component)); switch_core_session_rwunlock(session); } - RECEIVEFAX_COMPONENT(component)->stop = 1; + FAX_COMPONENT(component)->stop = 1; return iks_new_iq_result(iq); } @@ -190,18 +364,19 @@ static void insert_fax_metadata(switch_event_t *event, const char *name, iks *re } /** - * Handle rxfax completion event from FreeSWITCH core + * 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")) { + + 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))) { - const char *url = RECEIVEFAX_COMPONENT(component)->filename; iks *result; iks *complete; iks *fax; @@ -216,11 +391,8 @@ static void on_execute_complete_event(switch_event_t *event) switch_core_session_rwunlock(session); } - /* flag faxing as done */ - rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0); - - /* transfer HTTP document and delete local copy */ - if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component))) { + /* 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_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); @@ -237,16 +409,16 @@ static void on_execute_complete_event(switch_event_t *event) /* 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), RECEIVEFAX_FINISH); - } else if (have_fax_document && RECEIVEFAX_COMPONENT(component)->stop) { + 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"); - /* add fax document information */ - if (have_fax_document) { + /* 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"); @@ -256,10 +428,10 @@ static void on_execute_complete_event(switch_event_t *event) iks_insert_attrib(fax, "xmlns", RAYO_FAX_COMPLETE_NS); if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive) { - iks_insert_attrib(fax, "url", url); + iks_insert_attrib(fax, "url", RECEIVEFAX_COMPONENT(component)->filename); } else { /* convert absolute path to file:// URI */ - iks_insert_attrib_printf(fax, "url", "file://%s", url); + iks_insert_attrib_printf(fax, "url", "file://%s", RECEIVEFAX_COMPONENT(component)->filename); } if (!zstr(resolution)) { @@ -286,6 +458,9 @@ static void on_execute_complete_event(switch_event_t *event) 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); @@ -313,14 +488,14 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ /* get params */ { - switch_xml_t settings = switch_xml_child(cfg, "receivefax"); + switch_xml_t settings = switch_xml_child(cfg, "fax"); if (settings) { switch_xml_t param; for (param = switch_xml_child(settings, "param"); param; param = param->next) { const char *var = switch_xml_attr_soft(param, "name"); const char *val = switch_xml_attr_soft(param, "value"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); - if (!strcasecmp(var, "file-prefix")) { + if (!strcasecmp(var, "receivefax-file-prefix")) { if (!zstr(val)) { globals.file_prefix = switch_core_strdup(pool, val); } @@ -331,7 +506,7 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "receivefax file-prefix = %s\n", globals.file_prefix); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "receivefax-file-prefix = %s\n", globals.file_prefix); switch_xml_free(xml); @@ -339,31 +514,34 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ } /** - * Initialize receivefax component + * Initialize fax components * @param module_interface * @param pool memory pool to allocate from * @param config_file to use * @return SWITCH_STATUS_SUCCESS if successful */ -switch_status_t rayo_receivefax_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) +switch_status_t rayo_fax_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) { if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_TERM; } - switch_event_bind("rayo_receivefax_component", SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, on_execute_complete_event, NULL); + switch_event_bind("rayo_fax_components", SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, on_execute_complete_event, NULL); rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_FAX_NS":receivefax", start_receivefax_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "receivefax", "set:"RAYO_EXT_NS":stop", stop_receivefax_component); + rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "receivefax", "set:"RAYO_EXT_NS":stop", stop_fax_component); + + rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_FAX_NS":sendfax", start_sendfax_component); + rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "sendfax", "set:"RAYO_EXT_NS":stop", stop_fax_component); return SWITCH_STATUS_SUCCESS; } /** - * Shutdown receivefax component + * Shutdown fax components * @return SWITCH_STATUS_SUCCESS if successful */ -switch_status_t rayo_receivefax_component_shutdown(void) +switch_status_t rayo_fax_components_shutdown(void) { switch_event_unbind_callback(on_execute_complete_event); @@ -380,3 +558,4 @@ switch_status_t rayo_receivefax_component_shutdown(void) * For VIM: * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet */ +