コード例 #1
0
ファイル: utils.c プロジェクト: PauloFer1/FreeSWITCH
char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, const char *file_extension) {
	char rand_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
	switch_uuid_t srand_uuid;

	switch_uuid_get(&srand_uuid);
	switch_uuid_format(rand_uuid, &srand_uuid);

	return switch_core_session_sprintf(session, "%s%s%s_%s.%s", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, mod_name, rand_uuid, file_extension);

}
コード例 #2
0
ファイル: mod_http_cache.c プロジェクト: AricGod/FreeSWITCH
/**
 * Create a cached URL entry
 * @param cache the cache
 * @param url the URL to cache
 * @return the cached URL
 */
static cached_url_t *cached_url_create(url_cache_t *cache, const char *url)
{
	switch_uuid_t uuid;
	char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
	char *filename = NULL;
	char uuid_dir[3] = { 0 };
	char *dirname = NULL;
	cached_url_t *u = NULL;
	const char *file_extension = "";

	if (zstr(url)) {
		return NULL;
	}
	
	switch_zmalloc(u, sizeof(cached_url_t));

	/* filename is constructed from UUID and is stored in cache dir (first 2 characters of UUID) */
	switch_uuid_get(&uuid);
	switch_uuid_format(uuid_str, &uuid);
	strncpy(uuid_dir, uuid_str, 2);
	dirname = switch_mprintf("%s%s%s", cache->location, SWITCH_PATH_SEPARATOR, uuid_dir);
	filename = &uuid_str[2];

	/* create sub-directory if it doesn't exist */
	switch_dir_make_recursive(dirname, SWITCH_DEFAULT_DIR_PERMS, cache->pool);
	
	/* find extension on the end of URL */
	for(const char *ext = &url[strlen(url) - 1]; ext != url; ext--) {
		if (*ext == '/' || *ext == '\\') {
			break;
		}
		if (*ext == '.') {
			/* found it */
			file_extension = ext;
			break;
		}
	}

	/* intialize cached URL */
	u->filename = switch_mprintf("%s%s%s%s", dirname, SWITCH_PATH_SEPARATOR, filename, file_extension);
	u->url = switch_safe_strdup(url);
	u->size = 0;
	u->used = 1;
	u->status = CACHED_URL_RX_IN_PROGRESS;
	u->waiters = 0;
	u->download_time = switch_time_now();
	u->max_age = cache->default_max_age;

	switch_safe_free(dirname);

	return u;
}
コード例 #3
0
static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
{
	char api_cmd[MAXATOMLEN];
	char arg[ARGLEN];

	if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string_or_binary(buf->buff, &buf->index, ARGLEN - 1, arg)) {
		ei_x_encode_tuple_header(rbuf, 2);
		ei_x_encode_atom(rbuf, "error");
		ei_x_encode_atom(rbuf, "badarg");
	} else {
		struct api_command_struct *acs = NULL;
		switch_memory_pool_t *pool;
		switch_thread_t *thread;
		switch_threadattr_t *thd_attr = NULL;
		switch_uuid_t uuid;

		switch_core_new_memory_pool(&pool);
		acs = switch_core_alloc(pool, sizeof(*acs));
		switch_assert(acs);
		acs->pool = pool;
		acs->listener = listener;
		acs->api_cmd = switch_core_strdup(acs->pool, api_cmd);
		acs->arg = switch_core_strdup(acs->pool, arg);
		acs->bg = 1;
		acs->pid = msg->from;

		switch_threadattr_create(&thd_attr, acs->pool);
		switch_threadattr_detach_set(thd_attr, 1);
		switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);

		switch_uuid_get(&uuid);
		switch_uuid_format(acs->uuid_str, &uuid);
		switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool);

		ei_x_encode_tuple_header(rbuf, 2);
		ei_x_encode_atom(rbuf, "ok");
		_ei_x_encode_string(rbuf, acs->uuid_str);
	}
	return SWITCH_STATUS_SUCCESS;
}
コード例 #4
0
static switch_status_t tts_commandline_speech_open(switch_speech_handle_t *sh, const char *voice_name, int rate, switch_speech_flag_t *flags)
{
	switch_uuid_t uuid;
	char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
	char outfile[512] = "";

	tts_commandline_t *info = switch_core_alloc(sh->memory_pool, sizeof(*info));

	info->voice_name = switch_core_strdup(sh->memory_pool, voice_name);
	info->rate = rate;

	/* Construct temporary file name with a new UUID */
	switch_uuid_get(&uuid);
	switch_uuid_format(uuid_str, &uuid);
	switch_snprintf(outfile, sizeof(outfile), "%s%s%s.tmp.wav", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, uuid_str);
	info->file = switch_core_strdup(sh->memory_pool, outfile);

	info->fh = (switch_file_handle_t *) switch_core_alloc(sh->memory_pool, sizeof(switch_file_handle_t));

	sh->private_info = info;

	return SWITCH_STATUS_SUCCESS;
}
コード例 #5
0
WSClientParser::WSClientParser() {
	// TODO Auto-generated constructor stub
	mState = WSClientState_UnKnow;
	mpCallback = NULL;
	mpClient = NULL;

	mpUser = NULL;
	mpDomain = NULL;
	mpDestNumber = NULL;
	mpSite = NULL;
	mpCustom = NULL;
	mpChannel = NULL;
	memset(mWebSocketKey, '\0', sizeof(mWebSocketKey));

	// 创建内存池
	switch_core_new_memory_pool(&mpPool);
	switch_mutex_init(&clientMutex, SWITCH_MUTEX_NESTED, mpPool);

	// 生成唯一标识
	switch_uuid_t uuid;
	switch_uuid_get(&uuid);
	switch_uuid_format(this->uuid, &uuid);
}
コード例 #6
0
static switch_xml_t fetch_handler(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data) {
    switch_xml_t xml = NULL;
    switch_uuid_t uuid;
    switch_time_t now = 0;
    ei_xml_agent_t *agent = (ei_xml_agent_t *) user_data;
    ei_xml_client_t *client;
    fetch_handler_t *fetch_handler;
    xml_fetch_reply_t reply, *pending, *prev = NULL;

    now = switch_micro_time_now();

    if (!switch_test_flag(&globals, LFLAG_RUNNING)) {
        return xml;
    }

    /* read-lock the agent */
    switch_thread_rwlock_rdlock(agent->lock);

    /* serialize access to current, used to round-robin requests */
    /* TODO: check globals for round-robin boolean or loop all clients */
    switch_mutex_lock(agent->current_client_mutex);
    if (!agent->current_client) {
        client = agent->clients;
    } else {
        client = agent->current_client;
    }
    if (client) {
        agent->current_client = client->next;
    }
    switch_mutex_unlock(agent->current_client_mutex);

    /* no client, no work required */
    if (!client || !client->fetch_handlers) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "No %s XML erlang handler currently available\n"
                          ,section);
        switch_thread_rwlock_unlock(agent->lock);
        return xml;
    }

    /* prepare the reply collector */
    switch_uuid_get(&uuid);
    switch_uuid_format(reply.uuid_str, &uuid);
    reply.next = NULL;
    reply.xml_str = NULL;

    /* add our reply placeholder to the replies list */
    switch_mutex_lock(agent->replies_mutex);
    if (!agent->replies) {
        agent->replies = &reply;
    } else {
        reply.next = agent->replies;
        agent->replies = &reply;
    }
    switch_mutex_unlock(agent->replies_mutex);

    fetch_handler = client->fetch_handlers;
    while (fetch_handler != NULL) {
        ei_send_msg_t *send_msg;

        switch_malloc(send_msg, sizeof(*send_msg));
        memcpy(&send_msg->pid, &fetch_handler->pid, sizeof(erlang_pid));

        ei_x_new_with_version(&send_msg->buf);

        ei_x_encode_tuple_header(&send_msg->buf, 7);
        ei_x_encode_atom(&send_msg->buf, "fetch");
        ei_x_encode_atom(&send_msg->buf, section);
        _ei_x_encode_string(&send_msg->buf, tag_name ? tag_name : "undefined");
        _ei_x_encode_string(&send_msg->buf, key_name ? key_name : "undefined");
        _ei_x_encode_string(&send_msg->buf, key_value ? key_value : "undefined");
        _ei_x_encode_string(&send_msg->buf, reply.uuid_str);

        if (params) {
            ei_encode_switch_event_headers(&send_msg->buf, params);
        } else {
            ei_x_encode_empty_list(&send_msg->buf);
        }

        if (switch_queue_trypush(client->ei_node->send_msgs, send_msg) != SWITCH_STATUS_SUCCESS) {
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send %s XML request to %s <%d.%d.%d>\n"
                              ,section
                              ,fetch_handler->pid.node
                              ,fetch_handler->pid.creation
                              ,fetch_handler->pid.num
                              ,fetch_handler->pid.serial);
            ei_x_free(&send_msg->buf);
            switch_safe_free(send_msg);
        } else {
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending %s XML request (%s) to %s <%d.%d.%d>\n"
                              ,section
                              ,reply.uuid_str
                              ,fetch_handler->pid.node
                              ,fetch_handler->pid.creation
                              ,fetch_handler->pid.num
                              ,fetch_handler->pid.serial);
        }

        fetch_handler = fetch_handler->next;
    }

    /* wait for a reply (if there isnt already one...amazingly improbable but lets not take shortcuts */
    switch_mutex_lock(agent->replies_mutex);

    switch_thread_rwlock_unlock(agent->lock);

    if (!reply.xml_str) {
        switch_time_t timeout;

        timeout = switch_micro_time_now() + 3000000;
        while (switch_micro_time_now() < timeout) {
            /* unlock the replies list and go to sleep, calculate a three second timeout before we started the loop
             * plus 100ms to add a little hysteresis between the timeout and the while loop */
            switch_thread_cond_timedwait(agent->new_reply, agent->replies_mutex, (timeout - switch_micro_time_now() + 100000));

            /* if we woke up (and therefore have locked replies again) check if we got our reply
             * otherwise we either timed-out (the while condition will fail) or one of
             * our sibling processes got a reply and we should go back to sleep */
            if (reply.xml_str) {
                break;
            }
        }
    }

    /* find our reply placeholder in the linked list and remove it */
    pending = agent->replies;
    while (pending != NULL) {
        if (pending->uuid_str == reply.uuid_str) {
            break;
        }

        prev = pending;
        pending = pending->next;
    }

    if (pending) {
        if (!prev) {
            agent->replies = reply.next;
        } else {
            prev->next = reply.next;
        }
    }

    /* we are done with the replies link-list */
    switch_mutex_unlock(agent->replies_mutex);

    /* after all that did we get what we were after?! */
    if (reply.xml_str) {
        /* HELL YA WE DID */
        reply.xml_str = expand_vars(reply.xml_str);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received %s XML (%s) after %dms: %s\n"
                          ,section
                          ,reply.uuid_str
                          ,(unsigned int) (switch_micro_time_now() - now) / 1000
                          ,reply.xml_str);

        xml = switch_xml_parse_str_dynamic(reply.xml_str, SWITCH_FALSE);
    } else {
        /* facepalm */
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Request for %s XML (%s) timed-out after %dms\n"
                          ,section
                          ,reply.uuid_str
                          ,(unsigned int) (switch_micro_time_now() - now) / 1000);
    }

    return xml;
}
コード例 #7
0
static switch_xml_t xml_url_fetch(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params,
								  void *user_data)
{
	char filename[512] = "";
	CURL *curl_handle = NULL;
	struct config_data config_data;
	switch_xml_t xml = NULL;
	char *data = NULL;
	switch_uuid_t uuid;
	char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
	xml_binding_t *binding = (xml_binding_t *) user_data;
	char *file_url;
	struct curl_slist *slist = NULL;
	long httpRes = 0;
	struct curl_slist *headers = NULL;
	char hostname[256] = "";
	char basic_data[512];
	char *uri = NULL;
	char *dynamic_url = NULL;

    strncpy(hostname, switch_core_get_switchname(), sizeof(hostname));

	if (!binding) {
		return NULL;
	}

	if ((file_url = strstr(binding->url, "file:"))) {
		file_url += 5;

		if (!(xml = switch_xml_parse_file(file_url))) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n");
		}

		return xml;
	}

	switch_snprintf(basic_data, sizeof(basic_data), "hostname=%s&section=%s&tag_name=%s&key_name=%s&key_value=%s",
					hostname, section, switch_str_nil(tag_name), switch_str_nil(key_name), switch_str_nil(key_value));

	data = switch_event_build_param_string(params, basic_data, binding->vars_map);
	switch_assert(data);

	if (binding->use_dynamic_url) {
		if (!params) {
			switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
			switch_assert(params);
		}

		switch_event_add_header_string(params, SWITCH_STACK_TOP, "hostname", hostname);
		switch_event_add_header_string(params, SWITCH_STACK_TOP, "section", switch_str_nil(section));
		switch_event_add_header_string(params, SWITCH_STACK_TOP, "tag_name", switch_str_nil(tag_name));
		switch_event_add_header_string(params, SWITCH_STACK_TOP, "key_name", switch_str_nil(key_name));
		switch_event_add_header_string(params, SWITCH_STACK_TOP, "key_value", switch_str_nil(key_value));
		dynamic_url = switch_event_expand_headers(params, binding->url);
		switch_assert(dynamic_url);
	} else {
		dynamic_url = binding->url;
	}

	if (binding->use_get_style == 1) {
		uri = malloc(strlen(data) + strlen(dynamic_url) + 16);
		switch_assert(uri);
		sprintf(uri, "%s%c%s", dynamic_url, strchr(dynamic_url, '?') != NULL ? '&' : '?', data);
	}

	switch_uuid_get(&uuid);
	switch_uuid_format(uuid_str, &uuid);

	switch_snprintf(filename, sizeof(filename), "%s%s.tmp.xml", SWITCH_GLOBAL_dirs.temp_dir, uuid_str);
	curl_handle = curl_easy_init();
	headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");

	if (!strncasecmp(binding->url, "https", 5)) {
		curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
		curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
	}

	memset(&config_data, 0, sizeof(config_data));

	config_data.name = filename;
	config_data.max_bytes = XML_CURL_MAX_BYTES;

	if ((config_data.fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
		if (!zstr(binding->cred)) {
			curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, binding->auth_scheme);
			curl_easy_setopt(curl_handle, CURLOPT_USERPWD, binding->cred);
		}
		curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
		if (binding->method != NULL)
			curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, binding->method);
		curl_easy_setopt(curl_handle, CURLOPT_POST, !binding->use_get_style);
		curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
		curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
		if (!binding->use_get_style)
			curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);
		curl_easy_setopt(curl_handle, CURLOPT_URL, binding->use_get_style ? uri : dynamic_url);
		curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, file_callback);
		curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
		curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0");

		if (binding->timeout) {
			curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, binding->timeout);
			curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
		}

		if (binding->disable100continue) {
			slist = curl_slist_append(slist, "Expect:");
			curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, slist);
		}

		if (binding->enable_cacert_check) {
			curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, TRUE);
		}

		if (binding->ssl_cert_file) {
			curl_easy_setopt(curl_handle, CURLOPT_SSLCERT, binding->ssl_cert_file);
		}

		if (binding->ssl_key_file) {
			curl_easy_setopt(curl_handle, CURLOPT_SSLKEY, binding->ssl_key_file);
		}

		if (binding->ssl_key_password) {
			curl_easy_setopt(curl_handle, CURLOPT_SSLKEYPASSWD, binding->ssl_key_password);
		}

		if (binding->ssl_version) {
			if (!strcasecmp(binding->ssl_version, "SSLv3")) {
				curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
			} else if (!strcasecmp(binding->ssl_version, "TLSv1")) {
				curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
			}
		}

		if (binding->ssl_cacert_file) {
			curl_easy_setopt(curl_handle, CURLOPT_CAINFO, binding->ssl_cacert_file);
		}

		if (binding->enable_ssl_verifyhost) {
			curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
		}

		if (binding->cookie_file) {
			curl_easy_setopt(curl_handle, CURLOPT_COOKIEJAR, binding->cookie_file);
			curl_easy_setopt(curl_handle, CURLOPT_COOKIEFILE, binding->cookie_file);
		}

		curl_easy_perform(curl_handle);
		curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
		curl_easy_cleanup(curl_handle);
		curl_slist_free_all(headers);
		curl_slist_free_all(slist);
		close(config_data.fd);
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening temp file!\n");
	}

	if (config_data.err) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered! [%s]\ndata: [%s]\n", binding->url, data);
		xml = NULL;
	} else {
		if (httpRes == 200) {
			if (!(xml = switch_xml_parse_file(filename))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result! [%s]\ndata: [%s]\n", binding->url, data);
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received HTTP error %ld trying to fetch %s\ndata: [%s]\n", httpRes, binding->url,
							  data);
			xml = NULL;
		}
	}

	/* Debug by leaving the file behind for review */
	if (keep_files_around) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "XML response is in %s\n", filename);
	} else {
		if (unlink(filename) != 0) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "XML response file [%s] delete failed\n", filename);
		}
	}

	switch_safe_free(data);
	if (binding->use_get_style == 1)
		switch_safe_free(uri);
	if (binding->use_dynamic_url && dynamic_url != binding->url)
		switch_safe_free(dynamic_url);
	return xml;
}
コード例 #8
0
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;
}
コード例 #9
0
static void event_handler(switch_event_t *event)
{
	uint8_t send = 0;

	if (globals.running != 1) {
		return;
	}

	if (event->subclass_name && (!strcmp(event->subclass_name, MULTICAST_EVENT) ||
								 !strcmp(event->subclass_name, MULTICAST_PEERUP) || !strcmp(event->subclass_name, MULTICAST_PEERDOWN))) {
		char *event_name, *sender;
		if ((event_name = switch_event_get_header(event, "orig-event-name")) &&
			!strcasecmp(event_name, "HEARTBEAT") && (sender = switch_event_get_header(event, "orig-multicast-sender"))) {
			struct peer_status *p;
			time_t now = switch_epoch_time_now(NULL);

			if (!(p = switch_core_hash_find(globals.peer_hash, sender))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Host %s not already in hash\n", sender);
				p = switch_core_alloc(module_pool, sizeof(struct peer_status));
				p->active = SWITCH_FALSE;
				p->lastseen = 0;
				/*} else { */
				/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Host %s last seen %d seconds ago\n", sender, now - p->lastseen); */
			}

			if (!p->active) {
				switch_event_t *local_event;
				if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERUP) == SWITCH_STATUS_SUCCESS) {
					char lastseen[21];
					switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", sender);
					if (p->lastseen) {
						switch_snprintf(lastseen, sizeof(lastseen), "%d", (int) p->lastseen);
					} else {
						switch_snprintf(lastseen, sizeof(lastseen), "%s", "Never");
					}
					switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen);
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has come up; last seen: %s\n", sender, lastseen);

					switch_event_fire(&local_event);
				}
			}
			p->active = SWITCH_TRUE;
			p->lastseen = now;

			switch_core_hash_insert(globals.peer_hash, sender, p);
		}

		/* ignore our own events to avoid ping pong */
		return;
	}

	if (event->event_id == SWITCH_EVENT_RELOADXML) {
		switch_mutex_lock(globals.mutex);
		switch_core_hash_destroy(&globals.event_hash);
		globals.event_hash = NULL;
		if (globals.psk) {
			switch_safe_free(globals.psk);
			globals.psk = NULL;
		}
		switch_core_hash_init(&globals.event_hash, module_pool);
		memset(globals.event_list, 0, SWITCH_EVENT_ALL + 1);
		if (load_config() != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to reload config file\n");
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Event Multicast Reloaded\n");
		}
		switch_mutex_unlock(globals.mutex);
	}

	if (event->event_id == SWITCH_EVENT_HEARTBEAT) {
		switch_hash_index_t *cur;
		switch_ssize_t keylen;
		const void *key;
		void *value;
		time_t now = switch_epoch_time_now(NULL);
		struct peer_status *last;
		char *host;

		for (cur = switch_hash_first(NULL, globals.peer_hash); cur; cur = switch_hash_next(cur)) {
			switch_hash_this(cur, &key, &keylen, &value);
			host = (char *) key;
			last = (struct peer_status *) value;
			if (last->active && (now - (last->lastseen)) > 60) {
				switch_event_t *local_event;

				last->active = SWITCH_FALSE;
				if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERDOWN) == SWITCH_STATUS_SUCCESS) {
					char lastseen[21];
					switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", host);
					switch_snprintf(lastseen, sizeof(lastseen), "%d", (int) last->lastseen);
					switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen);
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has gone down; last seen: %s\n", host, lastseen);

					switch_event_fire(&local_event);
				}
			}
		}
	}

	switch_mutex_lock(globals.mutex);
	if (globals.event_list[(uint8_t) SWITCH_EVENT_ALL]) {
		send = 1;
	} else if ((globals.event_list[(uint8_t) event->event_id])) {
		if (event->event_id != SWITCH_EVENT_CUSTOM || (event->subclass_name && switch_core_hash_find(globals.event_hash, event->subclass_name))) {
			send = 1;
		}
	}
	switch_mutex_unlock(globals.mutex);

	if (send) {
		char *packet;

		switch (event->event_id) {
		case SWITCH_EVENT_LOG:
			return;
		default:
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Multicast-Sender", switch_core_get_switchname());
			if (switch_event_serialize(event, &packet, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
				size_t len;
				char *buf;
#ifdef HAVE_OPENSSL
				int outlen, tmplen;
				EVP_CIPHER_CTX ctx;
				char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
				switch_uuid_t uuid;

				switch_uuid_get(&uuid);
				switch_uuid_format(uuid_str, &uuid);
				len = strlen(packet) + SWITCH_UUID_FORMATTED_LENGTH + EVP_MAX_IV_LENGTH + strlen((char *) MAGIC);
#else
				len = strlen(packet) + strlen((char *) MAGIC);
#endif
				buf = malloc(len + 1);
				memset(buf, 0, len + 1);
				switch_assert(buf);

#ifdef HAVE_OPENSSL
				if (globals.psk) {
					switch_copy_string(buf, uuid_str, SWITCH_UUID_FORMATTED_LENGTH);

					EVP_CIPHER_CTX_init(&ctx);
					EVP_EncryptInit(&ctx, EVP_bf_cbc(), NULL, NULL);
					EVP_CIPHER_CTX_set_key_length(&ctx, strlen(globals.psk));
					EVP_EncryptInit(&ctx, NULL, (unsigned char *) globals.psk, (unsigned char *) uuid_str);
					EVP_EncryptUpdate(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH,
									  &outlen, (unsigned char *) packet, (int) strlen(packet));
					EVP_EncryptUpdate(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH + outlen,
									  &tmplen, (unsigned char *) MAGIC, (int) strlen((char *) MAGIC));
					outlen += tmplen;
					EVP_EncryptFinal(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH + outlen, &tmplen);
					outlen += tmplen;
					len = (size_t) outlen + SWITCH_UUID_FORMATTED_LENGTH;
					*(buf + SWITCH_UUID_FORMATTED_LENGTH + outlen) = '\0';
				} else {
#endif
					switch_copy_string(buf, packet, len);
					switch_copy_string(buf + strlen(packet), (char *) MAGIC, strlen((char *) MAGIC) + 1);
#ifdef HAVE_OPENSSL
				}
#endif

				switch_socket_sendto(globals.udp_socket, globals.addr, 0, buf, &len);
				switch_safe_free(packet);
				switch_safe_free(buf);
			}
			break;
		}
	}
	return;
}