switch_status_t utils_profile_control(char *profile_name) { /*TODO trovare un altro modo per controllare che il profilo sofia sia definito. Probabilmente il controllo sul file รจ una idiozia.*/ char pathname[128]; switch_snprintf(pathname,sizeof(pathname),"%s/sip_profiles/%s.xml",SWITCH_GLOBAL_dirs.conf_dir,profile_name); return switch_file_exists(pathname,globals.pool); }
/* rotate the log file */ static switch_status_t mod_logfile_rotate(logfile_profile_t *profile) { unsigned int i = 0; char *filename = NULL; switch_status_t stat = 0; int64_t offset = 0; switch_memory_pool_t *pool = NULL; switch_time_exp_t tm; char date[80] = ""; switch_size_t retsize; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_mutex_lock(globals.mutex); switch_time_exp_lt(&tm, switch_micro_time_now()); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm); profile->log_size = 0; stat = switch_file_seek(profile->log_afd, SWITCH_SEEK_SET, &offset); if (stat != SWITCH_STATUS_SUCCESS) { status = SWITCH_STATUS_FALSE; goto end; } switch_core_new_memory_pool(&pool); filename = switch_core_alloc(pool, strlen(profile->logfile) + WARM_FUZZY_OFFSET); for (i = 1; i < MAX_ROT; i++) { sprintf((char *) filename, "%s.%s.%i", profile->logfile, date, i); if (switch_file_exists(filename, pool) == SWITCH_STATUS_SUCCESS) { continue; } switch_file_close(profile->log_afd); switch_file_rename(profile->logfile, filename, pool); if ((status = mod_logfile_openlogfile(profile, SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Rotating Log!\n"); goto end; } break; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "New log started.\n"); end: if (pool) { switch_core_destroy_memory_pool(&pool); } switch_mutex_unlock(globals.mutex); return status; }
static void tts_commandline_speech_flush_tts(switch_speech_handle_t *sh) { tts_commandline_t *info = (tts_commandline_t *) sh->private_info; assert(info != NULL); if (info->fh != NULL && info->fh->file_interface != NULL) { switch_core_file_close(info->fh); } if (switch_file_exists(info->file, NULL) == SWITCH_STATUS_SUCCESS) { if (unlink(info->file) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sound file [%s] delete failed\n", info->file); } } }
SWITCH_DECLARE(int) switch_core_cert_gen_fingerprint(const char *prefix, dtls_fingerprint_t *fp) { X509* x509 = NULL; BIO* bio = NULL; int ret = 0; char *rsa; rsa = switch_mprintf("%s%s%s.pem", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, prefix); if (switch_file_exists(rsa, NULL) != SWITCH_STATUS_SUCCESS) { free(rsa); rsa = switch_mprintf("%s%s%s.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, prefix); } if (!(bio = BIO_new(BIO_s_file()))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "FP BIO ERR!\n"); goto end; } if (BIO_read_filename(bio, rsa) != 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "FP FILE ERR!\n"); goto end; } if (!(x509 = PEM_read_bio_X509(bio, NULL, 0, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "FP READ ERR!\n"); goto end; } switch_core_cert_extract_fingerprint(x509, fp); ret = 1; end: if (bio) { BIO_free_all(bio); } if (x509) { X509_free(x509); } free(rsa); return ret; }
/** * Get a URL from the cache, add it if it does not exist * @param cache The cache * @param session the (optional) session requesting the URL * @param url The URL * @param download If true, the file will be downloaded if it does not exist in the cache. * @param pool The pool to use for allocating the filename * @return The filename or NULL if there is an error */ static char *url_cache_get(url_cache_t *cache, switch_core_session_t *session, const char *url, int download, switch_memory_pool_t *pool) { char *filename = NULL; cached_url_t *u = NULL; if (zstr(url)) { return NULL; } url_cache_lock(cache, session); u = switch_core_hash_find(cache->map, url); if (u && u->status == CACHED_URL_AVAILABLE) { if (switch_time_now() >= (u->download_time + u->max_age)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cached URL has expired.\n"); url_cache_remove_soft(cache, session, u); /* will get permanently deleted upon replacement */ u = NULL; } else if (switch_file_exists(u->filename, pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cached URL file is missing.\n"); url_cache_remove_soft(cache, session, u); /* will get permanently deleted upon replacement */ u = NULL; } } if (!u && download) { /* URL is not cached, let's add it.*/ /* Set up URL entry and add to map to prevent simultaneous downloads */ cache->misses++; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Cache MISS: size = %zu (%zu MB), hit ratio = %d/%d\n", cache->queue.size, cache->size / 1000000, cache->hits, cache->hits + cache->misses); u = cached_url_create(cache, url); if (url_cache_add(cache, session, u) != SWITCH_STATUS_SUCCESS) { /* This error should never happen */ url_cache_unlock(cache, session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to add URL to cache!\n"); cached_url_destroy(u, cache->pool); return NULL; } /* download the file */ url_cache_unlock(cache, session); if (http_get(cache, u, session) == SWITCH_STATUS_SUCCESS) { /* Got the file, let the waiters know it is available */ url_cache_lock(cache, session); u->status = CACHED_URL_AVAILABLE; filename = switch_core_strdup(pool, u->filename); cache->size += u->size; } else { /* Did not get the file, flag for replacement */ url_cache_lock(cache, session); url_cache_remove_soft(cache, session, u); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Failed to download URL %s\n", url); cache->errors++; } } else if (!u) { filename = DOWNLOAD_NEEDED; } else { /* Wait until file is downloaded */ if (u->status == CACHED_URL_RX_IN_PROGRESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Waiting for URL %s to be available\n", url); u->waiters++; url_cache_unlock(cache, session); while(u->status == CACHED_URL_RX_IN_PROGRESS) { switch_sleep(10 * 1000); /* 10 ms */ } url_cache_lock(cache, session); u->waiters--; } /* grab filename if everything is OK */ if (u->status == CACHED_URL_AVAILABLE) { filename = switch_core_strdup(pool, u->filename); cache->hits++; u->used = 1; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Cache HIT: size = %zu (%zu MB), hit ratio = %d/%d\n", cache->queue.size, cache->size / 1000000, cache->hits, cache->hits + cache->misses); } } url_cache_unlock(cache, session); return filename; }
/* rotate the log file */ static switch_status_t mod_logfile_rotate(logfile_profile_t *profile) { unsigned int i = 0; char *filename = NULL; switch_status_t stat = 0; int64_t offset = 0; switch_memory_pool_t *pool = NULL; switch_time_exp_t tm; char date[80] = ""; switch_size_t retsize; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_mutex_lock(globals.mutex); switch_time_exp_lt(&tm, switch_micro_time_now()); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm); profile->log_size = 0; stat = switch_file_seek(profile->log_afd, SWITCH_SEEK_SET, &offset); if (stat != SWITCH_STATUS_SUCCESS) { status = SWITCH_STATUS_FALSE; goto end; } switch_core_new_memory_pool(&pool); filename = switch_core_alloc(pool, strlen(profile->logfile) + WARM_FUZZY_OFFSET); if (profile->max_rot) { char *from_filename = NULL; char *to_filename = NULL; from_filename = switch_core_alloc(pool, strlen(profile->logfile) + WARM_FUZZY_OFFSET); to_filename = switch_core_alloc(pool, strlen(profile->logfile) + WARM_FUZZY_OFFSET); for (i=profile->suffix; i>1; i--) { sprintf((char *) to_filename, "%s.%i", profile->logfile, i); sprintf((char *) from_filename, "%s.%i", profile->logfile, i-1); if (switch_file_exists(to_filename, pool) == SWITCH_STATUS_SUCCESS) { if ((status = switch_file_remove(to_filename, pool)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error removing log %s\n",to_filename); goto end; } } if ((status = switch_file_rename(from_filename, to_filename, pool)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error renaming log from %s to %s [%s]\n", from_filename, to_filename, strerror(errno)); goto end; } } sprintf((char *) to_filename, "%s.%i", profile->logfile, i); if (switch_file_exists(to_filename, pool) == SWITCH_STATUS_SUCCESS) { if ((status = switch_file_remove(to_filename, pool)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error removing log %s [%s]\n", to_filename, strerror(errno)); goto end; } } switch_file_close(profile->log_afd); if ((status = switch_file_rename(profile->logfile, to_filename, pool)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error renaming log from %s to %s [%s]\n", profile->logfile, to_filename, strerror(errno)); goto end; } if ((status = mod_logfile_openlogfile(profile, SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error reopening log %s\n", profile->logfile); } if (profile->suffix < profile->max_rot) { profile->suffix++; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "New log started.\n"); goto end; } /* XXX This have no real value EXCEPT making sure if we rotate within the same second, the end index will increase */ for (i = 1; i < MAX_ROT; i++) { sprintf((char *) filename, "%s.%s.%i", profile->logfile, date, i); if (switch_file_exists(filename, pool) == SWITCH_STATUS_SUCCESS) { continue; } switch_file_close(profile->log_afd); switch_file_rename(profile->logfile, filename, pool); if ((status = mod_logfile_openlogfile(profile, SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Rotating Log!\n"); goto end; } break; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "New log started.\n"); end: if (pool) { switch_core_destroy_memory_pool(&pool); } switch_mutex_unlock(globals.mutex); return status; }
/** * 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; }
/** * 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); } } }
/*! function to load a grammar to the asr interface */ static switch_status_t pocketsphinx_asr_load_grammar(switch_asr_handle_t *ah, const char *grammar, const char *name) { char *jsgf, *dic, *model, *rate = NULL; pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info; switch_status_t status = SWITCH_STATUS_FALSE; if (switch_test_flag(ps, PSFLAG_READY)) { ps_end_utt(ps->ps); switch_clear_flag(ps, PSFLAG_READY); } if (switch_is_file_path(grammar)) { char *dot = strrchr(grammar, '.'); if (dot && !strcmp(dot, ".gram")) { jsgf = strdup(grammar); } else { jsgf = switch_mprintf("%s.gram", grammar); } } else { jsgf = switch_mprintf("%s%s%s.gram", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, grammar); } if (ah->rate == 8000) { model = switch_mprintf("%s%smodel%s%s", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, SWITCH_PATH_SEPARATOR, globals.model8k); } else { model = switch_mprintf("%s%smodel%s%s", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, SWITCH_PATH_SEPARATOR, globals.model16k); } dic = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_PATH_SEPARATOR, globals.dictionary); if (switch_file_exists(dic, ah->memory_pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open dictionary %s.\n", dic); goto end; } if (switch_file_exists(model, ah->memory_pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open speech model %s.\n", model); goto end; } if (switch_file_exists(jsgf, ah->memory_pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't open grammar file %s.\n", jsgf); goto end; } rate = switch_mprintf("%d", ah->rate); switch_assert(jsgf && dic && model); ps->config = cmd_ln_init(ps->config, ps_args(), FALSE, "-samprate", rate, "-hmm", model, "-jsgf", jsgf, "-lw", globals.language_weight, "-dict", dic, "-frate", "50", "-silprob", "0.005", NULL); if (ps->config == NULL) { status = SWITCH_STATUS_GENERR; goto end; } switch_mutex_lock(ps->flag_mutex); if (switch_test_flag(ps, PSFLAG_ALLOCATED)) { ps_reinit(ps->ps, ps->config); } else { if (!(ps->ps = ps_init(ps->config))) { switch_mutex_unlock(ps->flag_mutex); goto end; } switch_set_flag(ps, PSFLAG_ALLOCATED); } switch_mutex_unlock(ps->flag_mutex); ps_start_utt(ps->ps, NULL); switch_set_flag(ps, PSFLAG_READY); switch_safe_free(ps->grammar); ps->grammar = strdup(grammar); status = SWITCH_STATUS_SUCCESS; end: switch_safe_free(rate); switch_safe_free(jsgf); switch_safe_free(dic); switch_safe_free(model); return status; }
abyss_bool auth_hook(TSession * r) { char *domain_name, *e; abyss_bool ret = FALSE; if (!strncmp(r->requestInfo.uri, "/domains/", 9)) { domain_name = strdup(r->requestInfo.uri + 9); switch_assert(domain_name); if ((e = strchr(domain_name, '/'))) { *e++ = '\0'; } if (!strcmp(domain_name, "this")) { free(domain_name); domain_name = strdup(r->requestInfo.host); } ret = !http_directory_auth(r, domain_name); free(domain_name); } else { char tmp[512]; const char *list[2] = { "index.html", "index.txt" }; int x; if (!strncmp(r->requestInfo.uri, "/pub", 4)) { char *p = (char *) r->requestInfo.uri; char *new_uri = p + 4; if (!new_uri) { new_uri = "/"; } switch_snprintf(tmp, sizeof(tmp), "%s%s", SWITCH_GLOBAL_dirs.htdocs_dir, new_uri); if (switch_directory_exists(tmp, NULL) == SWITCH_STATUS_SUCCESS) { for (x = 0; x < 2; x++) { switch_snprintf(tmp, sizeof(tmp), "%s%s%s%s", SWITCH_GLOBAL_dirs.htdocs_dir, new_uri, end_of(new_uri) == *SWITCH_PATH_SEPARATOR ? "" : SWITCH_PATH_SEPARATOR, list[x] ); if (switch_file_exists(tmp, NULL) == SWITCH_STATUS_SUCCESS) { switch_snprintf(tmp, sizeof(tmp), "%s%s%s", new_uri, end_of(new_uri) == '/' ? "" : "/", list[x] ); new_uri = tmp; break; } } } r->requestInfo.uri = strdup(new_uri); free(p); } else { if (globals.realm && strncmp(r->requestInfo.uri, "/pub", 4)) { ret = !http_directory_auth(r, NULL); } } } return ret; }
SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, const char *func, int line, switch_file_handle_t *fh, const char *file_path, uint32_t channels, uint32_t rate, unsigned int flags, switch_memory_pool_t *pool) { char *ext; switch_status_t status = SWITCH_STATUS_FALSE; char stream_name[128] = ""; char *rhs = NULL; const char *spool_path = NULL; int is_stream = 0; char *fp = NULL; int to = 0; if (switch_test_flag(fh, SWITCH_FILE_OPEN)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Handle already open\n"); return SWITCH_STATUS_FALSE; } fh->samples_in = 0; if (!fh->samplerate) { if (!(fh->samplerate = rate)) { fh->samplerate = 8000; } } if (zstr(file_path)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Filename\n"); return SWITCH_STATUS_FALSE; } fh->flags = flags; if (pool) { fh->memory_pool = pool; } else { if ((status = switch_core_new_memory_pool(&fh->memory_pool)) != SWITCH_STATUS_SUCCESS) { UNPROTECT_INTERFACE(fh->file_interface); return status; } switch_set_flag(fh, SWITCH_FILE_FLAG_FREE_POOL); } if (*file_path == '{') { char *timeout; char *new_fp; fp = switch_core_strdup(fh->memory_pool, file_path); if (switch_event_create_brackets(fp, '{', '}', ',', &fh->params, &new_fp, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { if ((timeout = switch_event_get_header(fh->params, "timeout"))) { if ((to = atoi(timeout)) < 1) { to = 0; } } } else { new_fp = fp; } file_path = new_fp; } if (switch_directory_exists(file_path, fh->memory_pool) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] is a directory not a file.\n", file_path); status = SWITCH_STATUS_GENERR; goto fail; } if ((rhs = strstr(file_path, SWITCH_URL_SEPARATOR))) { switch_copy_string(stream_name, file_path, (rhs + 1) - file_path); ext = stream_name; file_path = rhs + 3; fh->file_path = switch_core_strdup(fh->memory_pool, file_path); is_stream = 1; } else { if ((flags & SWITCH_FILE_FLAG_WRITE)) { char *p, *e; fh->file_path = switch_core_strdup(fh->memory_pool, file_path); p = fh->file_path; if (*p == '[' && *(p + 1) == *SWITCH_PATH_SEPARATOR) { e = switch_find_end_paren(p, '[', ']'); if (e) { *e = '\0'; spool_path = p + 1; fh->file_path = e + 1; } } if (!spool_path) { spool_path = switch_core_get_variable_pdup(SWITCH_AUDIO_SPOOL_PATH_VARIABLE, fh->memory_pool); } file_path = fh->file_path; } if ((ext = strrchr(file_path, '.')) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown file Format [%s]\n", file_path); switch_goto_status(SWITCH_STATUS_FALSE, fail); } ext++; fh->file_path = switch_core_strdup(fh->memory_pool, file_path); } if ((fh->file_interface = switch_loadable_module_get_file_interface(ext)) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid file format [%s] for [%s]!\n", ext, file_path); switch_goto_status(SWITCH_STATUS_GENERR, fail); } fh->file = file; fh->func = func; fh->line = line; if (spool_path) { char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; switch_uuid_t uuid; switch_uuid_get(&uuid); switch_uuid_format(uuid_str, &uuid); fh->spool_path = switch_core_sprintf(fh->memory_pool, "%s%s%s.%s", spool_path, SWITCH_PATH_SEPARATOR, uuid_str, ext); } else { fh->spool_path = NULL; } if (rhs) { fh->handler = switch_core_strdup(fh->memory_pool, rhs); } else { fh->handler = NULL; } if (channels) { fh->channels = channels; } else { fh->channels = 1; } file_path = fh->spool_path ? fh->spool_path : fh->file_path; if ((status = fh->file_interface->file_open(fh, file_path)) != SWITCH_STATUS_SUCCESS) { if (fh->spool_path) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Spool dir is set. Make sure [%s] is also a valid path\n", fh->spool_path); } UNPROTECT_INTERFACE(fh->file_interface); switch_goto_status(status, fail); } fh->real_channels = fh->channels; if (channels) { fh->channels = channels; } if ((flags & SWITCH_FILE_FLAG_WRITE) && !is_stream && (status = switch_file_exists(file_path, fh->memory_pool)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] not created!\n", file_path); fh->file_interface->file_close(fh); UNPROTECT_INTERFACE(fh->file_interface); switch_goto_status(status, fail); } if (to) { fh->max_samples = (fh->samplerate / 1000) * to; } if ((flags & SWITCH_FILE_FLAG_READ)) { fh->native_rate = fh->samplerate; } else { fh->native_rate = rate; } if (fh->samplerate && rate && fh->samplerate != rate) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "File %s sample rate %d doesn't match requested rate %d\n", file_path, fh->samplerate, rate); if ((flags & SWITCH_FILE_FLAG_READ)) { fh->samplerate = rate; } } if (fh->pre_buffer_datalen) { //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Prebuffering %d bytes\n", (int)fh->pre_buffer_datalen); switch_buffer_create_dynamic(&fh->pre_buffer, fh->pre_buffer_datalen * fh->channels, fh->pre_buffer_datalen * fh->channels, 0); fh->pre_buffer_data = switch_core_alloc(fh->memory_pool, fh->pre_buffer_datalen * fh->channels); } if (fh->real_channels != fh->channels && (flags & SWITCH_FILE_FLAG_READ) && !(fh->flags & SWITCH_FILE_NOMUX)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File has %d channels, muxing to %d channel%s will occur.\n", fh->real_channels, fh->channels, fh->channels == 1 ? "" : "s"); } switch_set_flag(fh, SWITCH_FILE_OPEN); return status; fail: switch_clear_flag(fh, SWITCH_FILE_OPEN); if (fh->params) { switch_event_destroy(&fh->params); } fh->samples_in = 0; fh->max_samples = 0; if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) { switch_core_destroy_memory_pool(&fh->memory_pool); } return status; }
SWITCH_DECLARE(int) switch_core_gen_certs(const char *prefix) { //BIO *bio_err; X509 *x509 = NULL; EVP_PKEY *pkey = NULL; char *rsa = NULL, *pvt = NULL; FILE *fp; char *pem = NULL; if (switch_stristr(".pem", prefix)) { if (switch_is_file_path(prefix)) { pem = strdup(prefix); } else { pem = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, prefix); } if (switch_file_exists(pem, NULL) == SWITCH_STATUS_SUCCESS) { goto end; } } else { if (switch_is_file_path(prefix)) { pvt = switch_mprintf("%s.key", prefix); rsa = switch_mprintf("%s.crt", prefix); } else { pvt = switch_mprintf("%s%s%s.key", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, prefix); rsa = switch_mprintf("%s%s%s.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, prefix); } if (switch_file_exists(pvt, NULL) == SWITCH_STATUS_SUCCESS || switch_file_exists(rsa, NULL) == SWITCH_STATUS_SUCCESS) { goto end; } } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); //bio_err=BIO_new_fp(stderr, BIO_NOCLOSE); mkcert(&x509, &pkey, 1024, 0, 36500); //RSA_print_fp(stdout, pkey->pkey.rsa, 0); //X509_print_fp(stdout, x509); if (pem) { if ((fp = fopen(pem, "w"))) { PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL); PEM_write_X509(fp, x509); fclose(fp); } } else { if (pvt && (fp = fopen(pvt, "w"))) { PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL); fclose(fp); } if (rsa && (fp = fopen(rsa, "w"))) { PEM_write_X509(fp, x509); fclose(fp); } } X509_free(x509); EVP_PKEY_free(pkey); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif CRYPTO_cleanup_all_ex_data(); //CRYPTO_mem_leaks(bio_err); //BIO_free(bio_err); end: switch_safe_free(pvt); switch_safe_free(rsa); switch_safe_free(pem); return(0); }
abyss_bool auth_hook(TSession * r) { char *domain_name, *e; abyss_bool ret = FALSE; if (globals.enable_websocket && !strncmp(r->requestInfo.uri, "/socket", 7)) { // Chrome has no Authorization support yet // https://code.google.com/p/chromium/issues/detail?id=123862 return websocket_hook(r); } if (!strncmp(r->requestInfo.uri, "/portal", 7) && strlen(r->requestInfo.uri) <= 8) { ResponseAddField(r, "Location", "/portal/index.html"); ResponseStatus(r, 302); return TRUE; } if (!strncmp(r->requestInfo.uri, "/domains/", 9)) { domain_name = strdup(r->requestInfo.uri + 9); switch_assert(domain_name); if ((e = strchr(domain_name, '/'))) { *e++ = '\0'; } if (!strcmp(domain_name, "this")) { free(domain_name); domain_name = strdup(r->requestInfo.host); } ret = !http_directory_auth(r, domain_name); free(domain_name); } else { char tmp[512]; const char *list[2] = { "index.html", "index.txt" }; int x; if (!strncmp(r->requestInfo.uri, "/pub", 4)) { char *p = (char *) r->requestInfo.uri; char *new_uri = p + 4; if (!new_uri) { new_uri = "/"; } switch_snprintf(tmp, sizeof(tmp), "%s%s", SWITCH_GLOBAL_dirs.htdocs_dir, new_uri); if (switch_directory_exists(tmp, NULL) == SWITCH_STATUS_SUCCESS) { for (x = 0; x < 2; x++) { switch_snprintf(tmp, sizeof(tmp), "%s%s%s%s", SWITCH_GLOBAL_dirs.htdocs_dir, new_uri, end_of(new_uri) == *SWITCH_PATH_SEPARATOR ? "" : SWITCH_PATH_SEPARATOR, list[x] ); if (switch_file_exists(tmp, NULL) == SWITCH_STATUS_SUCCESS) { switch_snprintf(tmp, sizeof(tmp), "%s%s%s", new_uri, end_of(new_uri) == '/' ? "" : "/", list[x] ); new_uri = tmp; break; } } } r->requestInfo.uri = strdup(new_uri); free(p); } else { if (globals.realm && strncmp(r->requestInfo.uri, "/pub", 4)) { ret = !http_directory_auth(r, NULL); } } } return ret; }
static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void *obj) { local_stream_source_t *source = obj; switch_file_handle_t fh = { 0 }; local_stream_context_t *cp; char file_buf[128] = "", path_buf[512] = "", last_path[512], png_buf[512] = "", tmp_buf[512] = ""; switch_timer_t timer = { 0 }; int fd = -1; switch_buffer_t *audio_buffer; switch_byte_t *dist_buf; switch_size_t used; int skip = 0; switch_memory_pool_t *temp_pool = NULL; uint32_t dir_count = 0, do_shuffle = 0; char *p; switch_mutex_lock(globals.mutex); THREADS++; switch_mutex_unlock(globals.mutex); if (!source->prebuf) { source->prebuf = DEFAULT_PREBUFFER_SIZE; } if (source->shuffle) { do_shuffle = 1; } switch_queue_create(&source->video_q, 500, source->pool); switch_buffer_create_dynamic(&audio_buffer, 1024, source->prebuf + 10, 0); dist_buf = switch_core_alloc(source->pool, source->prebuf + 10); switch_thread_rwlock_create(&source->rwlock, source->pool); if (RUNNING) { switch_mutex_lock(globals.mutex); switch_core_hash_insert(globals.source_hash, source->name, source); switch_mutex_unlock(globals.mutex); source->ready = 1; } while (RUNNING && !source->stopped) { const char *fname; if (temp_pool) { switch_core_destroy_memory_pool(&temp_pool); } if (switch_core_new_memory_pool(&temp_pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error creating pool"); goto done; } if (switch_dir_open(&source->dir_handle, source->location, temp_pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't open directory: %s\n", source->location); goto done; } if (fd > -1) { dir_count = 0; while (switch_fd_read_line(fd, path_buf, sizeof(path_buf))) { dir_count++; } lseek(fd, 0, SEEK_SET); } else { dir_count = switch_dir_count(source->dir_handle); } if (do_shuffle) { skip = do_rand(dir_count); do_shuffle = 0; } switch_yield(1000000); while (RUNNING && !source->stopped) { switch_size_t olen; uint8_t abuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; const char *artist = NULL, *title = NULL; if (fd > -1) { char *pb; if (switch_fd_read_line(fd, path_buf, sizeof(path_buf))) { if ((pb = strchr(path_buf, '\r')) || (pb = strchr(path_buf, '\n'))) { *pb = '\0'; } } else { close(fd); fd = -1; continue; } } else { if (!(fname = switch_dir_next_file(source->dir_handle, file_buf, sizeof(file_buf)))) { break; } switch_snprintf(path_buf, sizeof(path_buf), "%s%s%s", source->location, SWITCH_PATH_SEPARATOR, fname); if (switch_stristr(".loc", path_buf)) { if ((fd = open(path_buf, O_RDONLY)) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s\n", fname); switch_yield(1000000); } continue; } } if (dir_count > 1 && !strcmp(last_path, path_buf)) { continue; } if (skip > 0) { skip--; continue; } switch_set_string(last_path, path_buf); fname = path_buf; fh.prebuf = source->prebuf; fh.pre_buffer_datalen = source->prebuf; if (switch_core_file_open(&fh, (char *) fname, source->channels, source->rate, SWITCH_FILE_FLAG_VIDEO | SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s\n", fname); switch_yield(1000000); continue; } if (switch_core_file_has_video(&fh)) { flush_video_queue(source->video_q); } if (switch_core_timer_init(&timer, source->timer_name, source->interval, (int)source->samples, temp_pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't start timer.\n"); switch_dir_close(source->dir_handle); source->dir_handle = NULL; goto done; } switch_img_free(&source->cover_art); switch_set_string(tmp_buf, path_buf); if ((p = strrchr(tmp_buf, '/'))) { *p++ = '\0'; switch_snprintf(png_buf, sizeof(png_buf), "%s/art/%s.png", tmp_buf, p); if (switch_file_exists(png_buf, source->pool) == SWITCH_STATUS_SUCCESS) { source->cover_art = switch_img_read_png(png_buf, SWITCH_IMG_FMT_I420); } } source->serno++; switch_safe_free(source->banner_txt); title = artist = NULL; switch_core_file_get_string(&fh, SWITCH_AUDIO_COL_STR_ARTIST, &artist); switch_core_file_get_string(&fh, SWITCH_AUDIO_COL_STR_TITLE, &title); if (title && (source->cover_art || switch_core_file_has_video(&fh))) { const char *format = "#cccccc:#333333:FreeSans.ttf:3%:"; if (artist) { source->banner_txt = switch_mprintf("%s%s (%s)", format, title, artist); } else { source->banner_txt = switch_mprintf("%s%s", format, title); } } while (RUNNING && !source->stopped) { int is_open; switch_file_handle_t *use_fh = &fh; switch_core_timer_next(&timer); olen = source->samples; if (source->chime_total) { if (source->chime_counter > 0) { source->chime_counter -= (int32_t)source->samples; } if (!switch_test_flag((&source->chime_fh), SWITCH_FILE_OPEN) && source->chime_counter <= 0) { char *val; val = source->chime_list[source->chime_cur++]; if (source->chime_cur >= source->chime_total) { source->chime_cur = 0; } if (switch_core_file_open(&source->chime_fh, (char *) val, source->channels, source->rate, SWITCH_FILE_FLAG_VIDEO | SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s\n", val); } if (switch_core_file_has_video(&source->chime_fh)) { flush_video_queue(source->video_q); } } if (switch_test_flag((&source->chime_fh), SWITCH_FILE_OPEN)) { use_fh = &source->chime_fh; } } retry: source->has_video = switch_core_file_has_video(use_fh) || source->cover_art || source->banner_txt; is_open = switch_test_flag(use_fh, SWITCH_FILE_OPEN); if (source->hup) { source->hup = 0; if (is_open) { is_open = 0; switch_core_file_close(use_fh); flush_video_queue(source->video_q); if (use_fh == &source->chime_fh) { source->chime_counter = source->rate * source->chime_freq; switch_core_file_close(&fh); use_fh = &fh; } goto retry; } } if (is_open) { if (switch_core_has_video() && switch_core_file_has_video(use_fh)) { switch_frame_t vid_frame = { 0 }; if (use_fh == &source->chime_fh && switch_core_file_has_video(&fh)) { if (switch_core_file_read_video(&fh, &vid_frame, SVR_FLUSH) == SWITCH_STATUS_SUCCESS) { switch_img_free(&vid_frame.img); } } if (switch_core_file_read_video(use_fh, &vid_frame, SVR_FLUSH) == SWITCH_STATUS_SUCCESS) { if (vid_frame.img) { int flush = 1; source->has_video = 1; if (source->total) { if (switch_queue_trypush(source->video_q, vid_frame.img) == SWITCH_STATUS_SUCCESS) { flush = 0; } } if (flush) { switch_img_free(&vid_frame.img); flush_video_queue(source->video_q); } } } } else { source->has_video = 0; } if (use_fh == &source->chime_fh) { olen = source->samples; switch_core_file_read(&fh, abuf, &olen); olen = source->samples; } if (switch_core_file_read(use_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) { switch_core_file_close(use_fh); flush_video_queue(source->video_q); if (use_fh == &source->chime_fh) { source->chime_counter = source->rate * source->chime_freq; use_fh = &fh; } else { is_open = 0; } } else { if (use_fh == &source->chime_fh && source->chime_max) { source->chime_max_counter += (int32_t)source->samples; if (source->chime_max_counter >= source->chime_max) { source->chime_max_counter = 0; switch_core_file_close(use_fh); flush_video_queue(source->video_q); source->chime_counter = source->rate * source->chime_freq; use_fh = &fh; goto retry; } } if (source->total) { switch_buffer_write(audio_buffer, abuf, olen * 2 * source->channels); } else { switch_buffer_zero(audio_buffer); } } } used = switch_buffer_inuse(audio_buffer); if (!used && !is_open) { break; } if (!is_open || used >= source->prebuf || (source->total && used > source->samples * 2 * source->channels)) { void *pop; used = switch_buffer_read(audio_buffer, dist_buf, source->samples * 2 * source->channels); if (!source->total) { flush_video_queue(source->video_q); } else { uint32_t bused = 0; switch_mutex_lock(source->mutex); for (cp = source->context_list; cp && RUNNING; cp = cp->next) { if (source->has_video) { switch_set_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO); } else { switch_clear_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO); } if (switch_test_flag(cp->handle, SWITCH_FILE_CALLBACK)) { continue; } switch_mutex_lock(cp->audio_mutex); bused = (uint32_t)switch_buffer_inuse(cp->audio_buffer); if (bused > source->samples * 768) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Flushing Stream Handle Buffer [%s() %s:%d] size: %u samples: %ld\n", cp->func, cp->file, cp->line, bused, (long)source->samples); switch_buffer_zero(cp->audio_buffer); } else { switch_buffer_write(cp->audio_buffer, dist_buf, used); } switch_mutex_unlock(cp->audio_mutex); } switch_mutex_unlock(source->mutex); while (switch_queue_trypop(source->video_q, &pop) == SWITCH_STATUS_SUCCESS) { switch_image_t *img = (switch_image_t *) pop; switch_image_t *imgcp = NULL; if (source->total == 1) { switch_queue_push(source->context_list->video_q, img); } else { if (source->context_list) { switch_mutex_lock(source->mutex); for (cp = source->context_list; cp && RUNNING; cp = cp->next) { if (cp->video_q) { imgcp = NULL; switch_img_copy(img, &imgcp); if (imgcp) { if (switch_queue_trypush(cp->video_q, imgcp) != SWITCH_STATUS_SUCCESS) { flush_video_queue(cp->video_q); } } } } switch_mutex_unlock(source->mutex); } switch_img_free(&img); } } } } } switch_core_timer_destroy(&timer); if (RUNNING && source->shuffle) { skip = do_rand(dir_count); } } switch_dir_close(source->dir_handle); source->dir_handle = NULL; if (source->full_reload) { if (source->rwlock && switch_thread_rwlock_trywrlock(source->rwlock) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Cannot stop local_stream://%s because it is in use.\n",source->name); if (source->part_reload) { switch_xml_t cfg, xml, directory, param; if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); } if ((directory = switch_xml_find_child(cfg, "directory", "name", source->name))) { for (param = switch_xml_child(directory, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "shuffle")) { source->shuffle = switch_true(val); } else if (!strcasecmp(var, "chime-freq")) { int tmp = atoi(val); if (tmp > 1) { source->chime_freq = tmp; } } else if (!strcasecmp(var, "chime-max")) { int tmp = atoi(val); if (tmp > 1) { source->chime_max = tmp; } } else if (!strcasecmp(var, "chime-list")) { char *list_dup = switch_core_strdup(source->pool, val); source->chime_total = switch_separate_string(list_dup, ',', source->chime_list, (sizeof(source->chime_list) / sizeof(source->chime_list[0]))); } else if (!strcasecmp(var, "interval")) { int tmp = atoi(val); if (SWITCH_ACCEPTABLE_INTERVAL(tmp)) { source->interval = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Interval must be multiple of 10 and less than %d, Using default of 20\n", SWITCH_MAX_INTERVAL); } } if (source->chime_max) { source->chime_max *= source->rate; } if (source->chime_total) { source->chime_counter = source->rate * source->chime_freq; } } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "local_stream://%s partially reloaded.\n",source->name); source->part_reload = 0; } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "local_stream://%s fully reloaded.\n",source->name); launch_streams(source->name); goto done; } } } done: switch_safe_free(source->banner_txt); if (switch_test_flag((&fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&fh); } if (switch_test_flag((&source->chime_fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&source->chime_fh); } source->ready = 0; switch_mutex_lock(globals.mutex); switch_core_hash_delete(globals.source_hash, source->name); switch_mutex_unlock(globals.mutex); switch_thread_rwlock_wrlock(source->rwlock); switch_thread_rwlock_unlock(source->rwlock); switch_buffer_destroy(&audio_buffer); flush_video_queue(source->video_q); if (fd > -1) { close(fd); } if (temp_pool) { switch_core_destroy_memory_pool(&temp_pool); } switch_core_destroy_memory_pool(&source->pool); switch_mutex_lock(globals.mutex); THREADS--; switch_mutex_unlock(globals.mutex); return NULL; }