static cid_data_t *check_cache(switch_memory_pool_t *pool, const char *number) { char *cmd; char *name = NULL; char *area = NULL; char *src = NULL; cid_data_t *cid = NULL; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); cmd = switch_core_sprintf(pool, "get fs:cidlookup:name:%s", number); if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) { if (strncmp("-ERR", stream.data, 4)) { name = switch_core_strdup(pool, stream.data); } else { name = NULL; } } SWITCH_REWIND_STREAM(stream); cmd = switch_core_sprintf(pool, "get fs:cidlookup:area:%s", number); if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) { if (strncmp("-ERR", stream.data, 4)) { area = switch_core_strdup(pool, stream.data); } else { area = NULL; } } SWITCH_REWIND_STREAM(stream); cmd = switch_core_sprintf(pool, "get fs:cidlookup:src:%s", number); if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) { if (strncmp("-ERR", stream.data, 4)) { src = switch_core_strdup(pool, stream.data); } else { src = NULL; } } if (name || area || src) { cid = switch_core_alloc(pool, sizeof(cid_data_t)); switch_assert(cid); cid->name = name; cid->area = area; cid->src = src; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "memcache: k:'%s', vn:'%s', va:'%s', vs:'%s'\n", cmd, (name) ? name : "(null)", (area) ? area : "(null)", (src) ? src : "(null)"); switch_safe_free(stream.data); return cid; }
SWITCH_DECLARE(const char *) API::executeString(const char *cmd) { char *arg; switch_stream_handle_t stream = { 0 }; char *mycmd = NULL; this_check(""); SWITCH_STANDARD_STREAM(stream); if (zstr(cmd)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No application specified\n"); stream.write_function(&stream, "-ERR No application specified"); } else { mycmd = strdup(cmd); switch_assert(mycmd); if ((arg = strchr(mycmd, ' '))) { *arg++ = '\0'; } switch_api_execute(mycmd, arg, session, &stream); switch_safe_free(mycmd); } return (char *) stream.data; }
/** * Thread to prefetch URLs * @param thread the thread * @param obj started flag * @return NULL */ static void *SWITCH_THREAD_FUNC prefetch_thread(switch_thread_t *thread, void *obj) { int *started = obj; void *url = NULL; switch_thread_rwlock_rdlock(gcache.shutdown_lock); *started = 1; // process prefetch requests while (!gcache.shutdown) { if (switch_queue_pop(gcache.prefetch_queue, &url) == SWITCH_STATUS_SUCCESS) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_api_execute("http_get", url, NULL, &stream); switch_safe_free(stream.data); switch_safe_free(url); } url = NULL; } // shutting down- clear the queue while (switch_queue_trypop(gcache.prefetch_queue, &url) == SWITCH_STATUS_SUCCESS) { switch_safe_free(url); url = NULL; } switch_thread_rwlock_unlock(gcache.shutdown_lock); return NULL; }
static void api_hook(switch_core_session_t *session, const char *hook_var, int use_session) { if (!zstr(hook_var)) { switch_stream_handle_t stream = { 0 }; char *cmd = switch_core_session_strdup(session, hook_var); char *arg = NULL; char *expanded = NULL; if ((arg = strchr(cmd, ':')) && *(arg + 1) == ':') { *arg++ = '\0'; *arg++ = '\0'; } else { if ((arg = strchr(cmd, ' '))) { *arg++ = '\0'; } } SWITCH_STANDARD_STREAM(stream); switch_channel_get_variables(session->channel, &stream.param_event); switch_channel_event_set_data(session->channel, stream.param_event); expanded = switch_channel_expand_variables(session->channel, arg); switch_api_execute(cmd, expanded, use_session ? session : NULL, &stream); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Hangup Command %s %s(%s):\n%s\n", use_session ? "with Session" : "with no Session", cmd, switch_str_nil(expanded), switch_str_nil((char *) stream.data) ); if (expanded != arg) { switch_safe_free(expanded); } switch_safe_free(stream.data); } }
switch_status_t utils_start_sofia_profile(char *profile_name) { char cmd[128]; char arg[128]; switch_stream_handle_t mystream = { 0 }; if (!zstr(profile_name)) { if (utils_profile_control(profile_name) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "profile %s doesn't exist in sip_profiles directory\n",profile_name); return SWITCH_STATUS_FALSE; } switch_snprintf(cmd, sizeof(cmd),"sofia"); switch_snprintf(arg, sizeof(arg), "profile %s start",profile_name); SWITCH_STANDARD_STREAM(mystream); if (switch_api_execute(cmd, arg, NULL, &mystream) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"cannot execute sofia api %s\n", profile_name); return SWITCH_STATUS_FALSE; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,"profile %s started\n", profile_name); switch_safe_free(mystream.data); return SWITCH_STATUS_SUCCESS; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Invalid profile name\n"); return SWITCH_STATUS_FALSE; } }
static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_t *profile, listing_callback_t *cbt) { char buf[2] = ""; char macro[256] = ""; char recorded_name[256] = ""; /* Try to use the recorded name from voicemail if it exist */ if (switch_loadable_module_exists("mod_voicemail") == SWITCH_STATUS_SUCCESS) { char *cmd = NULL; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); cmd = switch_core_session_sprintf(session, "%s/%s@%s|name_path", cbt->params->profile, cbt->extension, cbt->params->domain); switch_api_execute("vm_prefs", cmd, session, &stream); if (strncmp("-ERR", stream.data, 4)) { switch_copy_string(recorded_name, (char *) stream.data, sizeof(recorded_name)); } switch_safe_free(stream.data); } if (zstr_buf(buf)) { switch_snprintf(macro, sizeof(macro), "phrase:%s:%d", DIR_RESULT_ITEM, cbt->want + 1); switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0); } if (!zstr_buf(recorded_name) && zstr_buf(buf)) { switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0); } if (zstr_buf(recorded_name) && zstr_buf(buf)) { switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", DIR_RESULT_SAY_NAME, cbt->fullname); switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0); } if (cbt->exten_visible && zstr_buf(buf)) { switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", DIR_RESULT_AT, cbt->extension); switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0); } if (zstr_buf(buf)) { switch_snprintf(macro, sizeof(macro), "phrase:%s:%c,%c,%c,%c", DIR_RESULT_MENU, *profile->select_name_key, *profile->next_key, *profile->prev_key, *profile->new_search_key); switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), profile->digit_timeout, profile->terminator_key, 0); } if (!zstr_buf(buf)) { if (buf[0] == *profile->select_name_key) { switch_copy_string(cbt->transfer_to, cbt->extension, 255); } if (buf[0] == *profile->new_search_key) { cbt->new_search = 1; } if (buf[0] == *profile->prev_key) { cbt->move = ENTRY_MOVE_PREV; } } else { return SWITCH_STATUS_TIMEOUT; } return SWITCH_STATUS_SUCCESS; }
switch_bool_t set_cache(switch_memory_pool_t *pool, char *number, cid_data_t *cid) { char *cmd; switch_bool_t success = SWITCH_TRUE; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); cmd = switch_core_sprintf(pool, "set fs:cidlookup:name:%s '%s' %d", number, cid->name, globals.cache_expire); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "memcache: %s\n", cmd); if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) { if (strncmp("-ERR", stream.data, 4)) { success = SWITCH_TRUE; } else { success = SWITCH_FALSE; goto done; } } SWITCH_REWIND_STREAM(stream); cmd = switch_core_sprintf(pool, "set fs:cidlookup:area:%s '%s' %d", number, cid->area, globals.cache_expire); if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) { if (strncmp("-ERR", stream.data, 4)) { success = SWITCH_TRUE; } else { success = SWITCH_FALSE; goto done; } } SWITCH_REWIND_STREAM(stream); cmd = switch_core_sprintf(pool, "set fs:cidlookup:src:%s '%s' %d", number, cid->src, globals.cache_expire); if (switch_api_execute("memcache", cmd, NULL, &stream) == SWITCH_STATUS_SUCCESS) { if (strncmp("-ERR", stream.data, 4)) { success = SWITCH_TRUE; } else { success = SWITCH_FALSE; goto done; } } done: switch_safe_free(stream.data); return success; }
SWITCH_DECLARE(const char *) API::execute(const char *cmd, const char *arg) { switch_stream_handle_t stream = { 0 }; this_check(""); SWITCH_STANDARD_STREAM(stream); switch_api_execute(cmd, arg, NULL, &stream); switch_safe_free(last_data); last_data = (char *) stream.data; return last_data; }
switch_event_t *jsonapi2event(switch_core_session_t *session, const char *api, const char *data) { switch_event_t *phrases_event = NULL; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_api_execute(api, data, session, &stream); switch_event_create_json(&phrases_event, (char *) stream.data); switch_safe_free(stream.data); return phrases_event; }
static xmlrpc_value *freeswitch_api(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, void *const userData, void *const callInfo) { char *command = NULL, *arg = NULL; switch_stream_handle_t stream = { 0 }; xmlrpc_value *val = NULL; switch_bool_t freed = 0; /* Parse our argument array. */ xmlrpc_decompose_value(envP, paramArrayP, "(ss)", &command, &arg); if (envP->fault_occurred) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Request!\n"); return NULL; } if (!is_authorized((const TSession *) callInfo, command)) { val = xmlrpc_build_value(envP, "s", "UNAUTHORIZED!"); goto end; } if (switch_stristr("unload", command) && switch_stristr("mod_xml_rpc", arg)) { switch_safe_free(command); switch_safe_free(arg); freed = 1; command = "bgapi"; arg = "unload mod_xml_rpc"; } else if (switch_stristr("reload", command) && switch_stristr("mod_xml_rpc", arg)) { switch_safe_free(command); switch_safe_free(arg); freed = 1; command = "bgapi"; arg = "reload mod_xml_rpc"; } SWITCH_STANDARD_STREAM(stream); if (switch_api_execute(command, arg, NULL, &stream) == SWITCH_STATUS_SUCCESS) { /* Return our result. */ val = xmlrpc_build_value(envP, "s", stream.data); free(stream.data); } else { val = xmlrpc_build_value(envP, "s", "ERROR!"); } end: /* xmlrpc-c requires us to free memory it malloced from xmlrpc_decompose_value */ if (!freed) { switch_safe_free(command); switch_safe_free(arg); } return val; }
void MainWindow::applyPreprocessors(QStringList cmds) { if (g_FSHost->getCurrentActiveCall().isNull()) return; QString uuid = g_FSHost->getCurrentActiveCall().data()->getUuid(); foreach(QString cmd, cmds) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_api_execute("uuid_preprocess", QString("%1 %2").arg(uuid, cmd).toAscii().data(), NULL, &stream); switch_safe_free(stream.data); }
switch_status_t FSHost::sendCmd(const char *cmd, const char *args, QString *res) { switch_status_t status = SWITCH_STATUS_FALSE; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); //qDebug() << "Sending command: " << cmd << args << endl; status = switch_api_execute(cmd, args, NULL, &stream); *res = switch_str_nil((char *) stream.data); switch_safe_free(stream.data); return status; }
SWITCH_DECLARE(switch_status_t) switch_console_execute(char *xcmd, int rec, switch_stream_handle_t *istream) { char *arg = NULL, *alias = NULL; char *delim = ";;"; int argc; char *argv[128]; int x; char *dup = strdup(xcmd); char *cmd; switch_status_t status = SWITCH_STATUS_FALSE; if (rec > 100) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Too much recursion!\n"); goto end; } if (!strncasecmp(xcmd, "alias", 5)) { argc = 1; argv[0] = xcmd; } else { argc = switch_separate_string_string(dup, delim, argv, 128); } for (x = 0; x < argc; x++) { cmd = argv[x]; if ((arg = strchr(cmd, '\r')) != 0 || (arg = strchr(cmd, '\n')) != 0) { *arg = '\0'; arg = NULL; } if ((arg = strchr(cmd, ' ')) != 0) { *arg++ = '\0'; } if ((alias = switch_console_expand_alias(cmd, arg)) && alias != cmd) { istream->write_function(istream, "\nExpand Alias [%s]->[%s]\n\n", cmd, alias); status = switch_console_execute(alias, ++rec, istream); free(alias); continue; } status = switch_api_execute(cmd, arg, NULL, istream); } end: switch_safe_free(dup); return status; }
/** * Lower volume of output component */ static iks *volume_down_output_component(struct rayo_actor *component, struct rayo_message *msg, void *data) { iks *iq = msg->payload; switch_stream_handle_t stream = { 0 }; char *command = switch_mprintf("%s volume:-", RAYO_JID(component)); SWITCH_STANDARD_STREAM(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s lowering volume\n", RAYO_JID(component)); switch_api_execute("fileman", command, NULL, &stream); switch_safe_free(stream.data); switch_safe_free(command); return iks_new_iq_result(iq); }
SWITCH_DECLARE(char *) switch_nat_status(void) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); stream.write_function(&stream, "Nat Type: %s, ExtIP: %s\n", (nat_globals.nat_type == SWITCH_NAT_TYPE_UPNP) ? "UPNP" : (nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "NAT-PMP" : "UNKNOWN"), nat_globals.pub_addr); switch_api_execute("show", "nat_map", NULL, &stream); return stream.data; /* caller frees */ }
switch_status_t vmivr_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments) { switch_status_t status = SWITCH_STATUS_SUCCESS; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_api_execute(apiname, arguments, session, &stream); if (!strncasecmp(stream.data, "-ERR", 4)) { status = SWITCH_STATUS_GENERR; } switch_safe_free(stream.data); return status; }
/** * Start recording mixer * @param record the record component */ static int start_mixer_record(struct rayo_component *component) { switch_stream_handle_t stream = { 0 }; char *args; SWITCH_STANDARD_STREAM(stream); args = switch_mprintf("%s recording start %s", component->parent->id, RAYO_ID(component)); switch_api_execute("conference", args, NULL, &stream); switch_safe_free(args); switch_safe_free(stream.data); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Recording started: file = %s\n", RAYO_ID(component)); return 1; }
/** * Stop execution of record component */ static iks *stop_mixer_record_component(struct rayo_actor *client, struct rayo_actor *component, iks *iq, void *data) { char *args; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); RECORD_COMPONENT(component)->stop = 1; args = switch_mprintf("%s recording stop %s", RAYO_COMPONENT(component)->parent->id, RAYO_ID(component)); switch_api_execute("conference", args, NULL, &stream); switch_safe_free(args); switch_safe_free(stream.data); return iks_new_iq_result(iq); }
SWITCH_DECLARE(const char *) API::execute(const char *cmd, const char *arg) { switch_stream_handle_t stream = { 0 }; this_check(""); SWITCH_STANDARD_STREAM(stream); if (zstr(cmd)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No application specified\n"); stream.write_function(&stream, "-ERR No application specified"); } else { switch_api_execute(cmd, arg, session, &stream); } return (char *) stream.data; }
/** * Resume execution of record component */ static iks *resume_record_component(struct rayo_actor *client, struct rayo_actor *component, iks *iq, void *data) { struct record_component *record = RECORD_COMPONENT(component); switch_stream_handle_t stream = { 0 }; char *command = switch_mprintf("%s resume", record->local_file_path); SWITCH_STANDARD_STREAM(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s resuming\n", RAYO_ID(component)); if (!record->start_time) { record->start_time = switch_micro_time_now(); } switch_api_execute("fileman", command, NULL, &stream); switch_safe_free(stream.data); switch_safe_free(command); return iks_new_iq_result(iq); }
SWITCH_DECLARE(void) switch_nat_republish(void) { switch_xml_t natxml = NULL; switch_xml_t row = NULL; switch_xml_t child = NULL; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Refreshing nat maps\n"); switch_api_execute("show", "nat_map as xml", NULL, &stream); if (!(natxml = switch_xml_parse_str_dup(stream.data))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to parse XML: %s\n", (char *) stream.data); switch_safe_free(stream.data); return; } /* iterate the xml and publish the mappings */ row = switch_xml_find_child(natxml, "row", "row_id", "1"); while (row != NULL) { char *sport = NULL; char *sproto = NULL; switch_port_t port; switch_nat_ip_proto_t proto; if ((child = switch_xml_child(row, "port"))) { sport = child->txt; } if ((child = switch_xml_child(row, "proto_num"))) { sproto = child->txt; } if (sport && sproto) { port = (switch_port_t) (atoi(sport)); proto = (switch_nat_ip_proto_t) (atoi(sproto)); switch_nat_add_mapping_internal(port, proto, NULL, SWITCH_FALSE, SWITCH_FALSE); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to parse port/proto info: XML: %s\n", (char *) stream.data); } row = switch_xml_next(row); } switch_safe_free(stream.data); switch_xml_free(natxml); }
void utils_hupall(char *profile_name) { char cmd[128]; char arg[128]; switch_stream_handle_t mystream = { 0 }; switch_snprintf(cmd, sizeof(cmd),"hupall"); switch_snprintf(arg, sizeof(arg),"normal_clearing sofia_profile_name %s",profile_name); SWITCH_STANDARD_STREAM(mystream); if (switch_api_execute(cmd, arg, NULL, &mystream) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"cannot hupall for %s\n",profile_name); return; } switch_safe_free(mystream.data); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,"hupall for %s done\n",profile_name); return; }
/* Api helper */ switch_status_t eventpipe_execute_api(switch_core_session_t *session, char *cmd, char *args) { switch_status_t status; switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "api: cmd %s, args %s\n", cmd, switch_str_nil(args)); status = switch_api_execute(cmd, args, session, &stream); if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "api: %s(%s) failed\n", cmd, switch_str_nil(args)); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "api: %s(%s) %s\n", cmd, switch_str_nil(args), (char *) stream.data); } free(stream.data); return status; }
void jsonapi_populate_event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data) { switch_event_t *phrases_event = NULL; switch_stream_handle_t stream = { 0 }; switch_event_header_t *hp; switch_assert(apply_event); SWITCH_STANDARD_STREAM(stream); switch_api_execute(api, data, session, &stream); switch_event_create_json(&phrases_event, (char *) stream.data); switch_safe_free(stream.data); for (hp = phrases_event->headers; hp; hp = hp->next) { if (!strncasecmp(hp->name, "VM-", 3)) { switch_event_add_header(apply_event, SWITCH_STACK_BOTTOM, hp->name, "%s", hp->value); } } switch_event_destroy(&phrases_event); phrases_event = apply_event; return; }
/** * 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); }
SWITCH_DECLARE(const char *) API::executeString(const char *cmd) { char *arg; switch_stream_handle_t stream = { 0 }; char *mycmd = strdup(cmd); switch_assert(mycmd); this_check(""); if ((arg = strchr(mycmd, ' '))) { *arg++ = '\0'; } switch_safe_free(last_data); SWITCH_STANDARD_STREAM(stream); switch_api_execute(mycmd, arg, NULL, &stream); last_data = (char *) stream.data; switch_safe_free(mycmd); return last_data; }
switch_status_t utils_recover(char *profile_name) { char arg[128]; switch_stream_handle_t mystream = { 0 }; if (!zstr(profile_name)) { switch_snprintf(arg, sizeof(arg),"profile %s recover",profile_name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"sofia %s\n", arg); SWITCH_STANDARD_STREAM(mystream); if (switch_api_execute("sofia", arg, NULL, &mystream) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"cannot recover profile %s\n", profile_name); return SWITCH_STATUS_FALSE; } switch_safe_free(mystream.data); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,"profile %s recovered\n", profile_name); return SWITCH_STATUS_SUCCESS; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Invalid profile name\n"); return SWITCH_STATUS_FALSE; } return SWITCH_STATUS_FALSE; }
/** * 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); } } }
static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj) { switch_bool_t r = SWITCH_TRUE; struct api_command_struct *acs = (struct api_command_struct *) obj; switch_stream_handle_t stream = { 0 }; char *reply, *freply = NULL; switch_status_t status; if (!acs) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Internal error.\n"); return NULL; } if (!acs->listener || !acs->listener->rwlock || switch_thread_rwlock_tryrdlock(acs->listener->rwlock) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! cannot get read lock.\n"); goto done; } SWITCH_STANDARD_STREAM(stream); if ((status = switch_api_execute(acs->api_cmd, acs->arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) { reply = stream.data; } else { freply = switch_mprintf("%s: Command not found!\n", acs->api_cmd); reply = freply; r = SWITCH_FALSE; } if (!reply) { reply = "Command returned no output!"; r = SWITCH_FALSE; } if (*reply == '-') r = SWITCH_FALSE; if (acs->bg) { switch_event_t *event; if (switch_event_create(&event, SWITCH_EVENT_BACKGROUND_JOB) == SWITCH_STATUS_SUCCESS) { ei_x_buff ebuf; switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-UUID", acs->uuid_str); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command", acs->api_cmd); ei_x_new_with_version(&ebuf); if (acs->arg) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command-Arg", acs->arg); } switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Successful", r ? "true" : "false"); switch_event_add_body(event, "%s", reply); switch_event_fire(&event); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending bgapi reply to %s\n", acs->pid.node); ei_x_encode_tuple_header(&ebuf, 3); if (r) ei_x_encode_atom(&ebuf, "bgok"); else ei_x_encode_atom(&ebuf, "bgerror"); _ei_x_encode_string(&ebuf, acs->uuid_str); _ei_x_encode_string(&ebuf, reply); switch_mutex_lock(acs->listener->sock_mutex); ei_send(acs->listener->sockfd, &acs->pid, ebuf.buff, ebuf.index); switch_mutex_unlock(acs->listener->sock_mutex); #ifdef EI_DEBUG ei_x_print_msg(&ebuf, &acs->pid, 1); #endif ei_x_free(&ebuf); } } else { ei_x_buff rbuf; ei_x_new_with_version(&rbuf); ei_x_encode_tuple_header(&rbuf, 2); if (!strlen(reply)) { reply = "Command returned no output!"; r = SWITCH_FALSE; } if (r) { ei_x_encode_atom(&rbuf, "ok"); } else { ei_x_encode_atom(&rbuf, "error"); } _ei_x_encode_string(&rbuf, reply); switch_mutex_lock(acs->listener->sock_mutex); ei_send(acs->listener->sockfd, &acs->pid, rbuf.buff, rbuf.index); switch_mutex_unlock(acs->listener->sock_mutex); #ifdef EI_DEBUG ei_x_print_msg(&rbuf, &acs->pid, 1); #endif ei_x_free(&rbuf); } switch_safe_free(stream.data); switch_safe_free(freply); if (acs->listener->rwlock) { switch_thread_rwlock_unlock(acs->listener->rwlock); } done: if (acs->bg) { switch_memory_pool_t *pool = acs->pool; acs = NULL; switch_core_destroy_memory_pool(&pool); pool = NULL; } return NULL; }
/** * 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; }