mod_rayo: add <sendfax> component

This commit is contained in:
Chris Rienzo 2013-11-07 20:31:58 -05:00
parent f0335d0f51
commit f97ca68f8e
8 changed files with 257 additions and 57 deletions

View File

@ -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

View File

@ -16,11 +16,11 @@
<param name="default-recognizer" value="pocketsphinx"/>
</input>
<!-- receivefax component params -->
<receivefax>
<!-- send/receivefax component params -->
<fax>
<!-- where to store incoming faxes -->
<param name="file-prefix" value="/tmp/"/>
</receivefax>
<param name="receivefax-file-prefix" value="/tmp/"/>
</fax>
<!-- XMPP server domain -->
<domain name="$${rayo_domain_name}" shared-secret="ClueCon">

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -49,6 +49,17 @@ ELEMENT(RAYO_INPUT)
ATTRIB(start-timers, true, bool)
ELEMENT_END
/**
* <join> 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
/**
* <output> component validation
*/
@ -80,6 +91,13 @@ ELEMENT(RAYO_PROMPT)
ATTRIB(barge-in, true, bool)
ELEMENT_END
/**
* <receivefax> command validation
*/
ELEMENT(RAYO_RECEIVEFAX)
ATTRIB(xmlns,, any)
ELEMENT_END
/**
* <record> component validation
*/
@ -97,22 +115,12 @@ ELEMENT(RAYO_RECORD)
ELEMENT_END
/**
* <join> command validation
* <sendfax> 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
/**
* <receivefax> command validation
*/
ELEMENT(RAYO_RECEIVEFAX)
ATTRIB(xmlns,, any)
ELEMENT_END
/* For Emacs:
* Local Variables:

View File

@ -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

View File

@ -23,7 +23,7 @@
* Contributor(s):
* Chris Rienzo <chris.rienzo@grasshopper.com>
*
* 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
*/