Пример #1
0
static char *dist_engine(const char *name)
{
	struct dist_node *np = NULL;
	struct dist_list *lp;
	char *str = NULL;
	char *myname = strdup(name);
	char *except;
	int argc = 0;
	char *argv[100] = { 0 };

	
	if ((except = strchr(myname, ' '))) {
		*except++ = '\0';
		argc = switch_split(except, ' ', argv);
	}

	switch_mutex_lock(globals.mod_lock);
	for (lp = globals.list; lp; lp = lp->next) {
		if (!strcasecmp(myname, lp->name)) {
			np = find_next(lp, argc, argv);
			break;
		}
	}

	if (np) {
		str = strdup(np->name);
	}
	switch_mutex_unlock(globals.mod_lock);

	free(myname);

	return str;

}
Пример #2
0
static switch_status_t process_node(const switch_log_node_t *node, switch_log_level_t level)
{
	switch_hash_index_t *hi;
	void *val;
	const void *var;
	logfile_profile_t *profile;

	for (hi = switch_core_hash_first(profile_hash); hi; hi = switch_core_hash_next(&hi)) {
		size_t mask = 0;
		size_t ok = 0;

		switch_core_hash_this(hi, &var, NULL, &val);
		profile = val;

		ok = switch_log_check_mask(profile->all_level, level);

		if (!ok) {
			mask = (size_t) switch_core_hash_find(profile->log_hash, node->file);
			ok = switch_log_check_mask(mask, level);
		}

		if (!ok) {
			mask = (size_t) switch_core_hash_find(profile->log_hash, node->func);
			ok = switch_log_check_mask(mask, level);
		}

		if (!ok) {
			char tmp[256] = "";
			switch_snprintf(tmp, sizeof(tmp), "%s:%s", node->file, node->func);
			mask = (size_t) switch_core_hash_find(profile->log_hash, tmp);
			ok = switch_log_check_mask(mask, level);
		}

		if (ok) {
			if (profile->log_uuid && !zstr(node->userdata)) {
				char buf[2048];
				char *dup = strdup(node->data);
				char *lines[100];
				int argc, i;
				
				argc = switch_split(dup, '\n', lines);
				for (i = 0; i < argc; i++) {
					switch_snprintf(buf, sizeof(buf), "%s %s\n", node->userdata, lines[i]);
					mod_logfile_raw_write(profile, buf);	
				}
				
				free(dup);
				
			} else {
				mod_logfile_raw_write(profile, node->data);
			}
		}

	}

	return SWITCH_STATUS_SUCCESS;
}
static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t **results)
{
	char *str = ldns_rr2str(naptr);
	char *argv[11] = { 0 };
	int i, argc;
	char *pack[4] = { 0 };
	int packc;

	char *p;
	int order = 10;
	int preference = 100;
	char *service = NULL;
	char *packstr;

	char *regex, *replace;
	
	if (zstr(str)) {
		if (str != NULL) {
			/* In this case ldns_rr2str returned a malloc'd null terminated string */
			switch_safe_free(str);
		}
		return;
	}

	for (p = str; p && *p; p++) {
		if (*p == '\t') *p = ' ';
		if (*p == ' ' && *(p+1) == '.') *p = '\0';
	}


	argc = switch_split(str, ' ', argv);

	for (i = 0; i < argc; i++) {
		if (i > 0) {
			strip_quotes(argv[i]);
		}
	}

	service = argv[7];
	packstr = argv[8];

	if (zstr(service) || zstr(packstr)) {
		goto end;
	}
	
	if (!zstr(argv[4])) {
		order = atoi(argv[4]);
	}

	if (!zstr(argv[5])) {
		preference = atoi(argv[5]);
	}


	if ((packc = switch_split(packstr, '!', pack))) {
		regex = pack[1];
		replace = pack[2];
	} else {
		goto end;
	}
	
	for (p = replace; p && *p; p++) {
		if (*p == '\\') {
			*p = '$';
		}
	}

	if (service && regex && replace) {
		switch_regex_t *re = NULL, *re2 = NULL;
		int proceed = 0, ovector[30];
		char *substituted = NULL;
		char *substituted_2 = NULL;
		char *orig_uri;
		char *uri_expanded = NULL;
		enum_route_t *route;
		int supported = 0;
		uint32_t len = 0;

		if ((proceed = switch_regex_perform(number, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
			if (strchr(regex, '(')) {
				len = (uint32_t) (strlen(number) + strlen(replace) + 10) * proceed;
				if (!(substituted = malloc(len))) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
					switch_regex_safe_free(re);
					goto end;
				}
				memset(substituted, 0, len);

				switch_perform_substitution(re, proceed, replace, number, substituted, len, ovector);
				orig_uri = substituted;
			} else {
				orig_uri = replace;
			}
			
			switch_mutex_lock(MUTEX);
			for (route = globals.route_order; route; route = route->next) {
				char *uri = orig_uri;
				
				if (strcasecmp(service, route->service)) {
					continue;
				}

				if ((proceed = switch_regex_perform(uri, route->regex, &re2, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
					switch_event_t *event = NULL;

					if (strchr(route->regex, '(')) {
						len = (uint32_t) (strlen(uri) + strlen(route->replace) + 10) * proceed;
						if (!(substituted_2 = malloc(len))) {
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
							switch_safe_free(substituted);
							switch_regex_safe_free(re);
							switch_regex_safe_free(re2);
							switch_mutex_unlock(MUTEX);
							goto end;
						}
						memset(substituted_2, 0, len);

						switch_perform_substitution(re2, proceed, route->replace, uri, substituted_2, len, ovector);
						uri = substituted_2;
					} else {
						uri = route->replace;
					}
					switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS);
					uri_expanded = switch_event_expand_headers(event, uri);
					switch_event_destroy(&event);

					if (uri_expanded == uri) {
						uri_expanded = NULL;
					} else {
						uri = uri_expanded;
					}

					supported++;
					add_result(results, order, preference, service, uri, supported);
					
				}
				switch_safe_free(uri_expanded);
				switch_safe_free(substituted_2);
				switch_regex_safe_free(re2);
			}
			switch_mutex_unlock(MUTEX);			

			if (!supported) {
				add_result(results, order, preference, service, orig_uri, 0);
			}

			switch_safe_free(substituted);
			switch_regex_safe_free(re);
		}
	}

 end:

	switch_safe_free(str);
	
	return;
}
Пример #4
0
SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session)
{
	switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state;
	const switch_endpoint_interface_t *endpoint_interface;
	const switch_state_handler_table_t *driver_state_handler = NULL;
	const switch_state_handler_table_t *application_state_handler = NULL;
	int proceed = 1;
	int global_proceed = 1;
	int do_extra_handlers = 1;
	int silly = 0;
	int index = 0;
	const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE);
	const char *skip_var = switch_channel_get_variable(session->channel, SWITCH_SKIP_CDR_CAUSES_VARIABLE);
	const char *hook_var;
	int use_session = 0;
	switch_event_t *event;
	switch_call_cause_t cause = switch_channel_get_cause(session->channel);

	if (switch_channel_test_flag(session->channel, CF_REPORTING)) {
		return;
	}

	switch_channel_set_flag(session->channel, CF_REPORTING);

	switch_assert(session != NULL);

	endpoint_interface = session->endpoint_interface;
	switch_assert(endpoint_interface != NULL);

	driver_state_handler = endpoint_interface->state_handler;
	switch_assert(driver_state_handler != NULL);

	if (!zstr(var)) {
		if (!strcasecmp(var, "a_only")) {
			if (switch_channel_get_originator_caller_profile(session->channel)) {
				do_extra_handlers = 0;
			}
		} else if (!strcasecmp(var, "b_only")) {
			if (switch_channel_get_originatee_caller_profile(session->channel)) {
				do_extra_handlers = 0;
			}
		} else if (!switch_true(var)) {
			do_extra_handlers = 0;
		}
	}


	if (!zstr(skip_var)) {
		int x, ttl = 0;
		char *list[128] = { 0 };
		char *dup = switch_core_session_strdup(session, skip_var);

		ttl = switch_split(dup, '|', list);

		for(x = 0; x < ttl; x++) {
			if (switch_channel_str2cause(list[x]) == cause) {
				do_extra_handlers = 0;
				break;
			}
		}
	}

	if (switch_channel_test_flag(session->channel, CF_NO_CDR)) {
		do_extra_handlers = 0;
	}


	STATE_MACRO(reporting, "REPORTING");

	if ((hook_var = switch_channel_get_variable(session->channel, SWITCH_API_REPORTING_HOOK_VARIABLE))) {

		if (switch_true(switch_channel_get_variable(session->channel, SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE))) {
			use_session = 1;
		}

		api_hook(session, hook_var, use_session);
	}

	if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE) == SWITCH_STATUS_SUCCESS) {
		switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(cause));
		switch_channel_event_set_data(session->channel, event);
		if (switch_true(switch_channel_get_variable(session->channel, "hangup_complete_with_xml"))) {
			switch_xml_t cdr = NULL;
			char *xml_cdr_text;
			
			if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
				xml_cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE);
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Attached", "xml");
				switch_event_add_body(event, "%s", xml_cdr_text);
				switch_xml_free(cdr);
				switch_safe_free(xml_cdr_text);
			}
		}
		switch_event_fire(&event);
	}



	return;
}
Пример #5
0
/* 
   State methods they get called when the state changes to the specific state 
   returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
   so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
*/
static switch_status_t channel_on_init(switch_core_session_t *session)
{
	switch_channel_t *channel, *b_channel;
	private_t *tech_pvt = NULL, *b_tech_pvt = NULL;
	switch_core_session_t *b_session;
	char name[128];
	switch_caller_profile_t *caller_profile;
	switch_event_t *vars = NULL;
	const char *var;

	tech_pvt = switch_core_session_get_private(session);
	switch_assert(tech_pvt != NULL);

	channel = switch_core_session_get_channel(session);
	switch_assert(channel != NULL);



	if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && !switch_test_flag(tech_pvt, TFLAG_BLEG)) {

		if (!(b_session = switch_core_session_request(loopback_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL))) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n");
			goto end;
		}

		if (switch_core_session_read_lock(b_session) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure.\n");
			switch_core_session_destroy(&b_session);
			goto end;
		}

		switch_core_session_add_stream(b_session, NULL);
		b_channel = switch_core_session_get_channel(b_session);
		b_tech_pvt = (private_t *) switch_core_session_alloc(b_session, sizeof(*b_tech_pvt));

		switch_snprintf(name, sizeof(name), "loopback/%s-b", tech_pvt->caller_profile->destination_number);
		switch_channel_set_name(b_channel, name);
		if (tech_init(b_tech_pvt, b_session, switch_core_session_get_read_codec(session)) != SWITCH_STATUS_SUCCESS) {
			switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
			switch_core_session_destroy(&b_session);
			goto end;
		}

		caller_profile = switch_caller_profile_clone(b_session, tech_pvt->caller_profile);
		caller_profile->source = switch_core_strdup(caller_profile->pool, modname);
		switch_channel_set_caller_profile(b_channel, caller_profile);
		b_tech_pvt->caller_profile = caller_profile;
		switch_channel_set_state(b_channel, CS_INIT);

		tech_pvt->other_session = b_session;
		tech_pvt->other_tech_pvt = b_tech_pvt;
		tech_pvt->other_channel = b_channel;

		//b_tech_pvt->other_session = session;
		//b_tech_pvt->other_tech_pvt = tech_pvt;
		//b_tech_pvt->other_channel = channel;

		b_tech_pvt->other_uuid = switch_core_session_strdup(b_session, switch_core_session_get_uuid(session));

		switch_set_flag_locked(tech_pvt, TFLAG_LINKED);
		switch_set_flag_locked(b_tech_pvt, TFLAG_LINKED);
		switch_set_flag_locked(b_tech_pvt, TFLAG_BLEG);


		switch_channel_set_flag(channel, CF_ACCEPT_CNG);

		if ((vars = (switch_event_t *) switch_channel_get_private(channel, "__loopback_vars__"))) {
			switch_event_header_t *h;
		
			switch_channel_set_private(channel, "__loopback_vars__", NULL);

			for (h = vars->headers; h; h = h->next) {
				switch_channel_set_variable(tech_pvt->other_channel, h->name, h->value);
			}

			switch_event_destroy(&vars);
		}

		if ((var = switch_channel_get_variable(channel, "loopback_export"))) {
			int argc = 0;
			char *argv[128] = { 0 };
			char *dup = switch_core_session_strdup(session, var);

			if ((argc = switch_split(dup, ',', argv))) {
				int i;
				for (i = 0; i < argc; i++) {
					
					if (!zstr(argv[i])) {
						const char *val = switch_channel_get_variable(channel, argv[i]);

						if(!zstr(val)) {
							switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Transfer variable [%s]=[%s] %s -> %s\n",
											  argv[i], val, switch_channel_get_name(channel), switch_channel_get_name(tech_pvt->other_channel));
											  
							switch_channel_set_variable(tech_pvt->other_channel, argv[i], val);
						}
					}
				}
			}
		}

		if (switch_test_flag(tech_pvt, TFLAG_APP)) {
			switch_set_flag(b_tech_pvt, TFLAG_APP);
			switch_clear_flag(tech_pvt, TFLAG_APP);
		}

		switch_channel_set_variable(channel, "other_loopback_leg_uuid", switch_channel_get_uuid(b_channel));
		switch_channel_set_variable(b_channel, "other_loopback_leg_uuid", switch_channel_get_uuid(channel));

		if (switch_core_session_thread_launch(b_session) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Error spawning thread\n");
			switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
			goto end;
		}
	} else if ((tech_pvt->other_session = switch_core_session_locate(tech_pvt->other_uuid))) {
		tech_pvt->other_tech_pvt = switch_core_session_get_private(tech_pvt->other_session);
		tech_pvt->other_channel = switch_core_session_get_channel(tech_pvt->other_session);
	}

	if (!tech_pvt->other_session) {
		switch_clear_flag_locked(tech_pvt, TFLAG_LINKED);
		switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
		goto end;
	}

	switch_channel_set_variable(channel, "loopback_leg", switch_test_flag(tech_pvt, TFLAG_BLEG) ? "B" : "A");
	switch_channel_set_state(channel, CS_ROUTING);

  end:

	return SWITCH_STATUS_SUCCESS;
}
Пример #6
0
static void *SWITCH_THREAD_FUNC limit_remote_thread(switch_thread_t *thread, void *obj)
{
	limit_remote_t *remote = (limit_remote_t*)obj;
	while (remote->state > REMOTE_OFF) {
		if (remote->state != REMOTE_UP) {
			if  (esl_connect_timeout(&remote->handle, remote->host, remote->port, remote->username, remote->password, 5000) == ESL_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to remote FreeSWITCH (%s) at %s:%d\n",
					remote->name, remote->host, remote->port);
				
				remote->state = REMOTE_UP;
			} else {
				esl_disconnect(&remote->handle);
				memset(&remote->handle, 0, sizeof(remote->handle));
			}
		} else {
			if (esl_send_recv_timed(&remote->handle, "api hash_dump limit", 5000) != ESL_SUCCESS) {
				esl_disconnect(&remote->handle);
				memset(&remote->handle, 0, sizeof(remote->handle));
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Disconnected from remote FreeSWITCH (%s) at %s:%d\n",
					remote->name, remote->host, remote->port);
				memset(&remote->handle, 0, sizeof(remote->handle));
				remote->state = REMOTE_DOWN;
				/* Delete all remote tracking entries */
				switch_thread_rwlock_wrlock(remote->rwlock);
				switch_core_hash_delete_multi(remote->index, limit_hash_remote_cleanup_callback, NULL);
				switch_thread_rwlock_unlock(remote->rwlock);
			} else {
				if (!zstr(remote->handle.last_sr_event->body)) {
					char *data = strdup(remote->handle.last_sr_event->body);
					char *p = data, *p2;
					switch_time_t now = switch_epoch_time_now(NULL);
					while (p && *p) {
						/* We are getting the limit data as:
							L/key/usage/rate/interval/last_checked 
						*/
						if ((p2 = strchr(p, '\n'))) {
							*p2++ = '\0';
						}
						
						/* Now p points at the beginning of the current line, 
						p2 at the start of the next one */
						if (*p == 'L') { /* Limit data */
							char *argv[5]; 
							int argc = switch_split(p+2, '/', argv);
							
							if (argc < 5) {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "[%s] Protocol error: missing argument in line: %s\n", 
									remote->name, p);
							} else {
								limit_hash_item_t *item;
								switch_thread_rwlock_wrlock(remote->rwlock);
								if (!(item = switch_core_hash_find(remote->index, argv[0]))) {
									item = malloc(sizeof(*item));
									switch_core_hash_insert(remote->index, argv[0], item);
								}
								item->total_usage = atoi(argv[1]);
								item->rate_usage = atoi(argv[2]);
								item->interval = atoi(argv[3]);
								item->last_check = atoi(argv[4]);
								item->last_update = now;
								switch_thread_rwlock_unlock(remote->rwlock);
							}
						}
						
						p = p2;
					}
					free(data);
					
					/* Now free up anything that wasn't in this update since it means their usage is 0 */
					switch_thread_rwlock_wrlock(remote->rwlock);
					switch_core_hash_delete_multi(remote->index, limit_hash_remote_cleanup_callback, (void*)(intptr_t)now);
					switch_thread_rwlock_unlock(remote->rwlock);
				}
			}
		}
		
		switch_yield(remote->interval * 1000);
	}
	
	remote->thread = NULL;
	
	return NULL;
}
Пример #7
0
switch_status_t ladspa_session(switch_core_session_t *session, const char *flags, const char *plugin_name, const char *label, const char *params)
{
    switch_channel_t *channel = switch_core_session_get_channel(session);
    switch_media_bug_t *bug;
    switch_status_t status;
    switch_ladspa_t *pvt = { 0 };
    switch_codec_implementation_t read_impl = { 0 };
    int i, bflags = SMBF_READ_REPLACE | SMBF_ANSWER_REQ;
    char *pstr;
    int argc;
    char *argv[50];
    char *dparams = NULL;

    if (zstr(plugin_name)) {
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s INVALID PLUGIN\n", switch_channel_get_name(channel));
        return SWITCH_STATUS_FALSE;
    }

    if (zstr(flags)) {
        flags = "r";
    }

    if (strchr(flags, 'w')) {
        bflags = SMBF_WRITE_REPLACE;
    }

    switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "FLAGS: %s PLUGIN: %s LABEL: %s PARAMS: %s\n",
                      flags, plugin_name, label, params);

    switch_core_session_get_read_impl(session, &read_impl);

    pvt = switch_core_session_alloc(session, sizeof(*pvt));

    pvt->session = session;
    if (!zstr(label)) {
        pvt->label_name = switch_core_session_strdup(session, label);
    } else {
        char *p;
        pvt->label_name = switch_core_session_strdup(session, plugin_name);
        if ((p = strrchr(pvt->label_name, '.'))) {
            *p = '\0';
        }
    }

    if (strstr(plugin_name, ".so")) {
        pvt->plugin_name = switch_core_session_strdup(session, plugin_name);
    } else {
        pvt->plugin_name = switch_core_session_sprintf(session, "%s.so", plugin_name);
    }

    dparams = switch_core_session_strdup(session, params);

    argc = switch_split(dparams, ' ', argv);

    for (i = 0; i < argc; i++) {
        if (switch_is_number(argv[i])) {
            if (pvt->num_idx < MAX_INDEX) {
                pvt->config[pvt->num_idx] = atof(argv[i]);
                pvt->has_config[pvt->num_idx] = 1;
                pvt->num_idx++;
            }
        } else {
            if (pvt->str_idx < MAX_INDEX) {
                pvt->str_config[pvt->str_idx++] = switch_core_session_strdup(session, argv[i]);
            }
        }
    }

    if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
        return SWITCH_STATUS_FALSE;
    }

    pstr = switch_core_session_sprintf(session, "%s|%s|%s|%s", flags, plugin_name, label, params);

    if ((status = switch_core_media_bug_add(session, "ladspa", pstr,
                                            ladspa_callback, pvt, 0, bflags | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) {
        return status;
    }

    switch_channel_set_private(channel, "ladspa", bug);

    return SWITCH_STATUS_SUCCESS;
}
Пример #8
0
int main(int argc, char *argv[]) 
{
	int r = 1;
	switch_bool_t verbose = SWITCH_FALSE;
	const char *err = NULL;
	int i;
	char *extra_modules[100] = { 0 };
	int extra_modules_count = 0;
	int cmd_fail = 0;
	const char *fmtp = "";
	int ptime = 20;
	const char *input, *output, *format = NULL;
	int channels = 1;
	int rate = 8000;
	switch_file_handle_t fh_input = { 0 }, fh_output = { 0 };
	switch_codec_t codec = { 0 };
	switch_codec_t raw_codec = { 0 };
	char buf[2048];
	switch_size_t len = sizeof(buf)/2;
	switch_memory_pool_t *pool = NULL;
	int bitrate = 0;
	int blocksize;
	int in_asis = 0;
	int out_asis = 0;
	int out_flags = SWITCH_FILE_FLAG_WRITE;

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch(argv[i][1]) {
				case 'c':
					i++;
					if((SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
						return 255;
					}
					strcpy(SWITCH_GLOBAL_dirs.conf_dir, argv[i]);
					break;
				case 'k':
					i++;
					if((SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
						return 255;
					}
					strcpy(SWITCH_GLOBAL_dirs.log_dir, argv[i]);
					break;
				case 'm':
					i++;
					if((SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(strlen(argv[i]) + 1)) == NULL) {
						return 255;
					}
					strcpy(SWITCH_GLOBAL_dirs.mod_dir, argv[i]);
					break;
				case 'l':
					i++;
					/* Load extra modules */
					if (strchr(argv[i], ','))  {
						extra_modules_count = switch_split(argv[i], ',', extra_modules);	
					} else {
						extra_modules_count = 1;
						extra_modules[0] = argv[i];
					}
					break;
				case 'f':
					fmtp = argv[++i];
					break;
				case 'p':
					ptime = atoi(argv[++i]);
					break;
				case 'r':
					rate = atoi(argv[++i]);
					break;
				case 'b':
					bitrate = atoi(argv[++i]);
					break;
				case 'v':
					verbose = SWITCH_TRUE;
					break;
				default:
					printf("Command line option not recognized: %s\n", argv[i]);
					cmd_fail = 1;
			}
		} else {
			break;
		}
	}
	
	if (argc - i < 2 || cmd_fail) {
		goto usage;
	}
	
	input = argv[i++];
	output = argv[i++];
	if (zstr(input) || zstr(output) || !(format = strchr(output, '.'))) {
		goto usage;
	}
	
	format++;
	
	if (switch_core_init(SCF_MINIMAL, verbose, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot init core [%s]\n", err);
		goto end;
	}
	
	switch_loadable_module_init(SWITCH_FALSE);
	switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_TRUE, &err);
	switch_loadable_module_load_module("", "CORE_SPEEX_MODULE", SWITCH_TRUE, &err);
	switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_TRUE, &err);

	for (i = 0; i < extra_modules_count; i++) {
		if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) extra_modules[i], SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
			fprintf(stderr, "Cannot init %s [%s]\n", extra_modules[i], err);
			goto end;
		}
	}
	
	if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_spandsp", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot init mod_spandsp [%s]\n", err);
		goto end;
	}
	
	if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_sndfile", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot init mod_sndfile [%s]\n", err);
		goto end;
	}
	
	if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_native_file", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Cannot init mod_native_file [%s]\n", err);
		goto end;
	}

	switch_core_new_memory_pool(&pool);
	if (verbose) {
		fprintf(stderr, "Opening file %s\n", input);
	}
	if (switch_core_file_open(&fh_input, input, channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Couldn't open %s\n", input);
		goto end;
	}
	

	if (verbose) {
		fprintf(stderr, "Opening file %s\n", output);
	}

	if (switch_stristr(".wav", output)) {
		out_asis = 0;
		out_flags |= SWITCH_FILE_DATA_SHORT;
	} else {
		out_asis = 1;
		out_flags |= SWITCH_FILE_NATIVE;
	}


	if (out_asis) {
		if (switch_core_codec_init_with_bitrate(&codec, format, NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
			fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", format, rate, ptime);
			goto end;
		}
	} else {
		char *p;

		if ((p = strchr(input, '.'))) {
			p++;
		}
		if (!p || switch_core_codec_init_with_bitrate(&codec, p, NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
			fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", p, rate, ptime);
			goto end;
		}
		
		if (switch_core_codec_init_with_bitrate(&raw_codec, "L16", NULL, fmtp, rate, ptime, channels, bitrate, SWITCH_CODEC_FLAG_ENCODE|SWITCH_CODEC_FLAG_DECODE, NULL, pool) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Couldn't initialize codec for %s@%dh@%di\n", "L16", rate, ptime);
		goto end;
		}
	}




	if (switch_core_file_open(&fh_output, output, channels, codec.implementation->actual_samples_per_second, out_flags, NULL) != SWITCH_STATUS_SUCCESS) {
		fprintf(stderr, "Couldn't open %s\n", output);
		goto end;	
	}
	
	if (switch_test_flag(&fh_input, SWITCH_FILE_NATIVE)) {
		in_asis = 1;
	}



	if (in_asis) {
		blocksize = len = codec.implementation->encoded_bytes_per_packet;
	} else {
		blocksize = len = (rate*ptime)/1000;
	}

	switch_assert(sizeof(buf) >= len * 2);

	if (verbose) {
		fprintf(stderr, "Frame size is %d\n", blocksize);	
	}
	
	while (switch_core_file_read(&fh_input, buf, &len) == SWITCH_STATUS_SUCCESS) {
		char encode_buf[2048];
		uint32_t encoded_len = sizeof(buf);
		uint32_t encoded_rate = rate;
		unsigned int flags = 0;

		if (out_asis) {
			if (switch_core_codec_encode(&codec, NULL, buf, len*2, rate, encode_buf, &encoded_len, &encoded_rate, &flags) != SWITCH_STATUS_SUCCESS) {
				fprintf(stderr, "Codec encoder error\n");
				goto end;
			}
			
			len = encoded_len;
		} else {
			if (!in_asis) {
				encoded_len = len;
			} else if (in_asis) {
				
				switch_core_codec_decode(&codec,
										 &raw_codec,
										 buf,
										 len,
										 rate,
										 encode_buf,
										 &encoded_len,
										 &encoded_rate,
										 &flags);
				encoded_len /= 2;
				len = encoded_len;
			}
		}


		if (switch_core_file_write(&fh_output, encode_buf, &len) != SWITCH_STATUS_SUCCESS) {
			fprintf(stderr, "Write error\n");
			goto end;
		}
		
		if (len != encoded_len) {
			printf("Short write: wrote %"SWITCH_SIZE_T_FMT"/%d bytes\n", len, encoded_len);
		}
		
		len = blocksize;
	}
	
	r = 0;

end:


	switch_core_codec_destroy(&codec);
	switch_core_codec_destroy(&raw_codec);


	if (fh_input.file_interface) {
		switch_core_file_close(&fh_input);		
	}

	if (fh_output.file_interface) {
		switch_core_file_close(&fh_output);		
	}

	if (pool) {
		switch_core_destroy_memory_pool(&pool);
	}
	
	fs_encode_cleanup();

	//switch_core_destroy();

	return r;
usage:
	printf("Usage: %s [options] input output\n\n", argv[0]);
	printf("The output must end in the format, e.g., myfile.SPEEX\n");
	printf("\t\t -c path\t\t Path to the FS configurations.\n");
	printf("\t\t -k path\t\t Path to the FS log directory\n");
	printf("\t\t -l module[,module]\t Load additional modules (comma-separated)\n");
	printf("\t\t -m path\t\t Path to the modules.\n");
	printf("\t\t -f format\t\t fmtp to pass to the codec\n");
	printf("\t\t -p ptime\t\t ptime to use while encoding\n");
	printf("\t\t -r rate\t\t sampling rate\n");
	printf("\t\t -b bitrate\t\t codec bitrate (if supported)\n");
	printf("\t\t -v\t\t\t verbose\n");
	fs_encode_cleanup();
	return 1;
}